-
Notifications
You must be signed in to change notification settings - Fork 4
Develop #176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughFirebase and push-notification integrations added; a NotificationSoundService singleton implemented; AppInitializationService now initializes push notifications; push notification parsing and store updated to play sounds; CI workflow enhanced for iOS Google services, dynamic release-notes extraction, and Changerawr submission; build configs and deps updated. Changes
Sequence Diagram(s)sequenceDiagram
participant App as App Startup
participant AIS as AppInitializationService
participant PNS as PushNotificationService
participant SNS as NotificationSoundService
participant FIR as Firebase/Notifee
App->>AIS: initialize()
activate AIS
AIS->>PNS: _initializePushNotifications()
activate PNS
PNS->>FIR: setupAndroidChannels()
PNS->>FIR: addNotificationListeners()
PNS->>FIR: setupForegroundMessageHandler()
PNS-->>AIS: success (errors logged, not thrown)
deactivate PNS
AIS->>SNS: initialize()
activate SNS
SNS->>SNS: initializeAudio() / preload assets
SNS-->>AIS: success
deactivate SNS
AIS-->>App: initialization complete
deactivate AIS
sequenceDiagram
participant FCM as FCM Message (foreground)
participant PNS as PushNotificationService
participant Store as PushNotificationStore
participant SNS as NotificationSoundService
participant UI as Modal UI
FCM->>PNS: onMessage(remoteMessage)
activate PNS
PNS->>Store: create notificationData (extract eventCode)
PNS->>Store: showNotificationModal(notificationData)
deactivate PNS
activate Store
Store->>Store: parse eventCode (C1234 → call)
Store->>SNS: playNotificationSound('call')
activate SNS
SNS-->>Store: playback result (errors logged)
deactivate SNS
Store->>UI: display modal
deactivate Store
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Areas to review closely:
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (4)
.gitignore (1)
22-23: Remove the duplicate/appsentry.Line 22 and line 23 both contain
/apps, creating a redundant rule.-/apps -/apps +/appssrc/services/notification-sound.service.ts (3)
27-29: Clarify initialization strategy.This public method provides explicit initialization, but the constructor also calls
initializeAudio()(line 17). TheisInitializedguard prevents double work, but the design is confusing. If you adopt Option 1 from the previous comment (removing constructor initialization), this method becomes the primary initialization point—document that callers must invoke it.
121-127: Consider reusing chat sound for group chat.Currently, group chat creates a separate
Audio.Soundinstance from the same asset as chat. If they should sound identical, consider referencing the same sound object to save memory:- // Group chat uses the same sound as regular chat - const { sound: groupChatSound } = await Audio.Sound.createAsync({ uri: chatSoundAsset.localUri || chatSoundAsset.uri } as AVPlaybackSource, { - shouldPlay: false, - isLooping: false, - volume: 1.0, - }); - this.groupChatSound = groupChatSound; + // Group chat uses the same sound as regular chat + this.groupChatSound = this.chatSound;Note: Only do this if concurrent playback of chat and group-chat sounds will never occur. If they might play simultaneously, keep separate instances.
209-248: LGTM: Thorough cleanup.All sound resources are properly unloaded, nullified, and the initialization state is reset. This allows for proper re-initialization if needed.
Optionally, you could reduce duplication by iterating over sounds:
const sounds = [ { ref: this.callSound, name: 'callSound' }, { ref: this.messageSound, name: 'messageSound' }, // ... ]; for (const { ref } of sounds) { if (ref) await ref.unloadAsync(); }However, the current explicit approach is clear and maintainable.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
.DS_Storeis excluded by!**/.DS_Storeyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (19)
.github/workflows/react-native-cicd.yml(4 hunks).gitignore(1 hunks)__mocks__/react-native-ble-plx.ts(0 hunks)app.config.ts(3 hunks)eas.json(1 hunks)package.json(2 hunks)src/components/calls/dispatch-selection-modal.tsx(5 hunks)src/components/push-notification/push-notification-modal.tsx(3 hunks)src/services/__tests__/app-initialization.service.test.ts(7 hunks)src/services/__tests__/notification-sound.service.test.ts(1 hunks)src/services/__tests__/push-notification.test.ts(1 hunks)src/services/app-initialization.service.ts(3 hunks)src/services/notification-sound.service.ts(1 hunks)src/services/push-notification.ts(2 hunks)src/stores/push-notification/__tests__/store.test.ts(12 hunks)src/stores/push-notification/store.ts(3 hunks)src/translations/ar.json(1 hunks)src/translations/en.json(1 hunks)src/translations/es.json(1 hunks)
💤 Files with no reviewable changes (1)
- mocks/react-native-ble-plx.ts
🧰 Additional context used
📓 Path-based instructions (9)
**/*
📄 CodeRabbit inference engine (.cursorrules)
Directory and file names should be lowercase and hyphenated (e.g., user-profile, chat-screen)
Files:
src/translations/es.jsonsrc/translations/ar.jsonsrc/stores/push-notification/__tests__/store.test.tssrc/stores/push-notification/store.tssrc/services/__tests__/push-notification.test.tssrc/services/push-notification.tsapp.config.tspackage.jsonsrc/translations/en.jsonsrc/services/__tests__/app-initialization.service.test.tssrc/services/__tests__/notification-sound.service.test.tssrc/services/app-initialization.service.tssrc/components/calls/dispatch-selection-modal.tsxsrc/components/push-notification/push-notification-modal.tsxsrc/services/notification-sound.service.tseas.json
src/translations/**
📄 CodeRabbit inference engine (.cursorrules)
Store translation dictionaries in src/translations
Files:
src/translations/es.jsonsrc/translations/ar.jsonsrc/translations/en.json
src/translations/**/*.{json,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Store translation dictionaries in src/translations
Files:
src/translations/es.jsonsrc/translations/ar.jsonsrc/translations/en.json
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx}: Write concise, type-safe TypeScript code
Use camelCase for variable and function names (e.g., isFetchingData, handleUserInput)
Use TypeScript for all components, favoring interfaces for props and state
Avoid using any; strive for precise types
Use Expo SecureStore for sensitive data
Use zustand for state management
Use react-query for data fetching and caching
Use react-i18next for internationalization
Use react-native-mmkv for local storage
Use axios for API requests
**/*.{ts,tsx}: Write concise, type-safe TypeScript code
Use camelCase for variable and function names
Use TypeScript for all components, favoring interfaces for props and state
Avoid using any; strive for precise types
Use React Navigation for handling navigation and deep linking
Handle errors gracefully and provide user feedback
Use Expo's SecureStore for sensitive data
Use zustand for state management
Use react-query for data fetching
Use react-i18next for internationalization
Use react-native-mmkv for local storage
Use axios for API requests
Files:
src/stores/push-notification/__tests__/store.test.tssrc/stores/push-notification/store.tssrc/services/__tests__/push-notification.test.tssrc/services/push-notification.tsapp.config.tssrc/services/__tests__/app-initialization.service.test.tssrc/services/__tests__/notification-sound.service.test.tssrc/services/app-initialization.service.tssrc/components/calls/dispatch-selection-modal.tsxsrc/components/push-notification/push-notification-modal.tsxsrc/services/notification-sound.service.ts
**/*.{test.ts,test.tsx,spec.ts,spec.tsx}
📄 CodeRabbit inference engine (.cursorrules)
Create and use Jest tests to validate all generated components
Files:
src/stores/push-notification/__tests__/store.test.tssrc/services/__tests__/push-notification.test.tssrc/services/__tests__/app-initialization.service.test.tssrc/services/__tests__/notification-sound.service.test.ts
**/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
Generate tests for all components, services, and logic; ensure tests run without errors
Files:
src/stores/push-notification/__tests__/store.test.tssrc/services/__tests__/push-notification.test.tssrc/services/__tests__/app-initialization.service.test.tssrc/services/__tests__/notification-sound.service.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Create and use Jest tests for all generated components
Files:
src/stores/push-notification/__tests__/store.test.tssrc/services/__tests__/push-notification.test.tssrc/services/__tests__/app-initialization.service.test.tssrc/services/__tests__/notification-sound.service.test.ts
**/*.tsx
📄 CodeRabbit inference engine (.cursorrules)
**/*.tsx: Use functional components and hooks over class components
Use PascalCase for React component names (e.g., UserProfile, ChatScreen)
Utilize React.FC for defining functional components with props
Minimize useEffect, useState, and heavy computations inside render
Use React.memo() for components with static props to prevent unnecessary re-renders
Optimize FlatList with removeClippedSubviews, maxToRenderPerBatch, windowSize
Use getItemLayout for FlatList when items have consistent size
Avoid anonymous functions in renderItem or event handlers to prevent re-renders
Use gluestack-ui for styling; if no component exists in src/components/ui, style via StyleSheet.create or styled-components
Optimize images using react-native-fast-image
Use React Navigation for navigation and deep linking with best practices
Wrap all user-facing text in t() from react-i18next
Use react-hook-form for form handling
Use @rnmapbox/maps for maps or vehicle navigation
Use lucide-react-native for icons directly in markup; do not use the gluestack-ui icon component
Use the conditional operator (?:) for conditional rendering instead of &&
**/*.tsx: Use functional components and hooks over class components
Use PascalCase for component names
Utilize React.FC for defining functional components with props
Minimize useEffect/useState and heavy computations inside render
Use React.memo for components with static props to prevent unnecessary re-renders
Optimize FlatList with removeClippedSubviews, maxToRenderPerBatch, and windowSize
Use getItemLayout for FlatList when items have consistent size
Avoid anonymous functions in renderItem or event handlers
Optimize image handling using react-native-fast-image
Wrap all user-facing text in t() from react-i18next
Ensure support for dark mode and light mode
Ensure the app is accessible following WCAG for mobile
Use react-hook-form for form handling
Use @rnmapbox/maps for maps and navigation
Use lucide-react-native for icons directly in markup; do not us...
Files:
src/components/calls/dispatch-selection-modal.tsxsrc/components/push-notification/push-notification-modal.tsx
{components/ui/**/*.{ts,tsx},**/*.tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use gluestack-ui consistently; if no component exists in components/ui, style via StyleSheet.create or styled-components
Files:
src/components/calls/dispatch-selection-modal.tsxsrc/components/push-notification/push-notification-modal.tsx
🧠 Learnings (7)
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to **/*.tsx : Use rnmapbox/maps for maps and navigation
Applied to files:
package.json
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/*.{test.ts,test.tsx,spec.ts,spec.tsx} : Create and use Jest tests to validate all generated components
Applied to files:
src/services/__tests__/notification-sound.service.test.ts
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to **/*.{test,spec}.{ts,tsx} : Create and use Jest tests for all generated components
Applied to files:
src/services/__tests__/notification-sound.service.test.ts
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/__tests__/**/*.{ts,tsx} : Generate tests for all components, services, and logic; ensure tests run without errors
Applied to files:
src/services/__tests__/notification-sound.service.test.ts
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/*.tsx : Use React.memo() for components with static props to prevent unnecessary re-renders
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/*.tsx : Use lucide-react-native for icons directly in markup; do not use the gluestack-ui icon component
Applied to files:
src/components/push-notification/push-notification-modal.tsx
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to **/*.tsx : Use lucide-react-native for icons directly in markup; do not use gluestack-ui icon component
Applied to files:
src/components/push-notification/push-notification-modal.tsx
🧬 Code graph analysis (7)
src/stores/push-notification/__tests__/store.test.ts (2)
src/stores/push-notification/store.ts (1)
usePushNotificationModalStore(32-104)src/services/notification-sound.service.ts (1)
notificationSoundService(251-251)
src/stores/push-notification/store.ts (2)
src/services/notification-sound.service.ts (1)
notificationSoundService(251-251)src/lib/logging/index.tsx (2)
error(74-76)logger(80-80)
src/services/push-notification.ts (2)
src/lib/logging/index.tsx (1)
logger(80-80)src/stores/push-notification/store.ts (1)
usePushNotificationModalStore(32-104)
src/services/__tests__/app-initialization.service.test.ts (4)
src/lib/logging/index.tsx (1)
logger(80-80)src/services/callkeep.service.ios.ts (1)
callKeepService(341-341)src/services/push-notification.ts (1)
pushNotificationService(301-301)src/services/app-initialization.service.ts (1)
appInitializationService(180-180)
src/services/__tests__/notification-sound.service.test.ts (2)
__mocks__/expo-av.ts (1)
Audio(2-28)src/services/notification-sound.service.ts (1)
notificationSoundService(251-251)
src/services/app-initialization.service.ts (2)
src/services/push-notification.ts (1)
pushNotificationService(301-301)src/lib/logging/index.tsx (2)
logger(80-80)error(74-76)
src/services/notification-sound.service.ts (3)
__mocks__/expo-av.ts (3)
Audio(2-28)InterruptionModeIOS(30-34)AVPlaybackSource(36-36)src/lib/logging/index.tsx (2)
logger(80-80)error(74-76)src/stores/push-notification/store.ts (1)
NotificationType(13-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
🔇 Additional comments (17)
eas.json (1)
83-98: Clarify the purpose of the newdev-simprofile.A new
dev-simbuild profile has been added with iOS and Android simulator support anddevelopmentClientexplicitly set tofalse. This profile appears to overlap with the existingsimulatorprofile (lines 99–112), which also enables iOS simulator support.The distinction seems to be that
dev-simexplicitly disables the development client while thesimulatorprofile leaves it unset. If this profile is intended to test production-like behavior on simulators, consider adding a comment explaining its purpose. If it's truly necessary alongsidesimulator, verify that both profiles serve distinct use cases in your CI/CD and development workflow.Could you confirm:
- What specific use case or workflow does
dev-simaddress thatsimulatordoes not?- Is this profile tied to the Firebase integration or CI/CD enhancements mentioned in the PR?
.gitignore (1)
27-27: Clarify the pattern scope for GoogleService-Info.plist.The current pattern
GoogleService-Info.plistwill match the file in any directory recursively. Per the AI summary, the intent is to ignore the root-level file generated during iOS CI builds. If root-only matching is desired, prepend a forward slash:/GoogleService-Info.plist. If the intent is to ignore this file at any nesting level (e.g., within Xcode project directories), the current pattern is correct.app.config.ts (3)
47-47: LGTM! Firebase iOS configuration correctly added.The
googleServicesFileconfiguration for iOS is properly set and aligns with the CI/CD workflow changes that create this file from theUNIT_IOS_GOOGLE_SERVICESsecret.
218-218: LGTM! Required iOS framework configuration for Firebase.The
useFrameworks: 'static'setting is correctly configured and necessary for Firebase SDK compatibility on iOS.
267-267: LGTM! Firebase plugin correctly registered.The
@react-native-firebase/appplugin is properly added to the plugins array, matching the dependency addition in package.json..github/workflows/react-native-cicd.yml (2)
50-50: LGTM! Environment secrets properly configured.The new environment variables for iOS Google Services and Changerawr API are correctly added.
Also applies to: 75-76
159-162: LGTM! iOS Google Services file creation properly implemented.The step correctly creates the GoogleService-Info.plist file from the base64-encoded secret, matching the pattern used for Android's google-services.json.
src/services/__tests__/push-notification.test.ts (1)
125-129: LGTM! Mock notification structure improved.The addition of a realistic
triggerobject withtype: 'push'makes the test data more accurate. The double type assertion (as unknown as Notifications.Notification) is an acceptable TypeScript workaround for test data construction.src/services/app-initialization.service.ts (3)
5-5: LGTM! Push notification service import added.The import is correctly added for the push notification initialization flow.
77-78: LGTM! Push notification initialization integrated into app startup.The initialization is correctly added to the startup flow, following the same pattern as CallKeep initialization.
118-136: LGTM! Push notification initialization method properly implemented.The implementation follows the established pattern:
- Private async method for initialization
- Proper error handling with logging
- Non-throwing behavior to prevent app startup failure
- Clear log messages for success and error cases
package.json (2)
94-96: I need to verify a couple more details before finalizing the assessment. Let me check the React Native version specified in the codebase and investigate the validity of version 0.79.6:Ensure awareness of React Native 0.79 Metro compatibility requirements with Firebase packages.
The three Firebase packages at ^23.5.0 are compatible with React Native 0.79.6:
- All three packages are aligned at 23.5.0 (latest available)
- Peer dependencies are satisfied (v23.5.0 is the latest version)
- React Native 0.79 has known incompatibilities with Firebase packages due to Metro 0.82's package.json "exports" field resolution
If using React Native 0.79.6, ensure your project either uses Metro 0.81.5 hotfix or disables package exports resolution to avoid potential Firebase initialization issues.
128-128: Document the reason for the expo-notifications downgrade.The web search found no documented incompatibility between @react-native-firebase/messaging v23.5.0 and expo-notifications 0.31.4. However, 0.31.4 (2025-07-05) contains no user-facing changes (internal fixes), while 0.28.3 (2024-05-16) added iOS support for interruptionLevel. Downgrading from 0.31.4 to 0.28.3 moves backward ~13 months without a clear technical justification. Please clarify why this downgrade is necessary—whether it addresses a specific issue or dependency conflict.
src/services/notification-sound.service.ts (4)
31-64: LGTM: Well-structured initialization.The initialization logic is clean with proper guards, platform-specific audio configuration, and comprehensive error handling.
66-84: LGTM: Efficient parallel asset preloading.Using
Promise.allfor parallel loading is efficient. Error handling allows the process to continue toloadAudioFileseven if preloading fails partially.
151-179: LGTM: Robust playback implementation.The method includes proper guards (null check, lazy initialization) and resets playback position before playing. The on-demand initialization (lines 161-163) provides good defensive behavior.
181-207: LGTM: Complete notification type coverage.All
NotificationTypecases are handled, with appropriate fallback to default sound for unknown types. Error context includes the notification type for debugging.
| - name: 📋 Prepare Release Notes file | ||
| if: ${{ matrix.platform == 'android' }} | ||
| env: | ||
| RELEASE_NOTES_INPUT: ${{ github.event.inputs.release_notes }} | ||
| PR_BODY: ${{ github.event.pull_request.body }} | ||
| run: | | ||
| set -eo pipefail | ||
| # Determine source of release notes: workflow input, PR body, or recent commits | ||
| if [ -n "$RELEASE_NOTES_INPUT" ]; then | ||
| NOTES="$RELEASE_NOTES_INPUT" | ||
| elif [ -n "$PR_BODY" ]; then | ||
| NOTES="$(printf '%s\n' "$PR_BODY" \ | ||
| # Function to extract release notes from PR body | ||
| extract_release_notes() { | ||
| local body="$1" | ||
| # Try to extract content under "## Release Notes" heading | ||
| local notes="$(printf '%s\n' "$body" \ | ||
| | awk 'f && /^## /{exit} /^## Release Notes/{f=1; next} f')" | ||
| else | ||
| # If no specific section found, use the entire body (up to first 500 chars for safety) | ||
| if [ -z "$notes" ]; then | ||
| notes="$(printf '%s\n' "$body" | head -c 500)" | ||
| fi | ||
| printf '%s\n' "$notes" | ||
| } | ||
| # Determine source of release notes | ||
| NOTES="" | ||
| # Check if this was triggered by a push event (likely a merge) | ||
| if [ "${{ github.event_name }}" = "push" ]; then | ||
| echo "Fetching PR body for merged commit..." | ||
| # Get the PR number associated with this merge commit | ||
| PR_NUMBER=$(gh pr list \ | ||
| --state merged \ | ||
| --search "${{ github.sha }}" \ | ||
| --json number \ | ||
| --jq '.[0].number' 2>/dev/null || echo "") | ||
| if [ -n "$PR_NUMBER" ]; then | ||
| echo "Found merged PR #$PR_NUMBER" | ||
| # Fetch the PR body | ||
| PR_BODY=$(gh pr view "$PR_NUMBER" --json body --jq '.body' 2>/dev/null || echo "") | ||
| if [ -n "$PR_BODY" ]; then | ||
| NOTES="$(extract_release_notes "$PR_BODY")" | ||
| fi | ||
| else | ||
| echo "No associated PR found, checking commit message..." | ||
| # Try to find PR number from commit message | ||
| PR_FROM_COMMIT=$(git log -1 --pretty=%B | grep -oE '#[0-9]+' | head -1 | tr -d '#' || echo "") | ||
| if [ -n "$PR_FROM_COMMIT" ]; then | ||
| echo "Found PR #$PR_FROM_COMMIT from commit message" | ||
| PR_BODY=$(gh pr view "$PR_FROM_COMMIT" --json body --jq '.body' 2>/dev/null || echo "") | ||
| if [ -n "$PR_BODY" ]; then | ||
| NOTES="$(extract_release_notes "$PR_BODY")" | ||
| fi | ||
| fi | ||
| fi | ||
| fi | ||
| # Fallback to recent commits if no PR body found | ||
| if [ -z "$NOTES" ]; then | ||
| echo "No PR body found, using recent commits..." | ||
| NOTES="$(git log -n 5 --pretty=format:'- %s')" | ||
| fi | ||
| # Fail if no notes extracted | ||
| if [ -z "$NOTES" ]; then | ||
| echo "Error: No release notes extracted" >&2 | ||
| exit 1 | ||
| fi | ||
| # Write header and notes to file | ||
| { | ||
| echo "## Version 7.${{ github.run_number }} - $(date +%Y-%m-%d)" | ||
| echo | ||
| printf '%s\n' "$NOTES" | ||
| } > RELEASE_NOTES.md | ||
| echo "Release notes prepared:" | ||
| cat RELEASE_NOTES.md | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix shell script quote mismatch and improve PR detection logic.
Several issues in the release notes extraction script:
- Quote mismatch at line 306: The awk pattern has mismatched quotes (
'at start,"at end) - PR detection may fail: Line 326 uses
gh pr list --search "${{ github.sha }}"which searches PR content, not commits. This won't reliably find the PR that introduced the commit. - No handling for multiple results: The script assumes exactly one PR is returned.
Apply these fixes:
extract_release_notes() {
local body="$1"
# Try to extract content under "## Release Notes" heading
- local notes="$(printf '%s\n' "$body" \
- | awk 'f && /^## /{exit} /^## Release Notes/{f=1; next} f')"
+ local notes="$(printf '%s\n' "$body" \
+ | awk 'flag && /^## /{exit} /^## Release Notes/{flag=1; next} flag')"For better PR detection, use the GitHub API to find PRs by commit SHA:
# Get the PR number associated with this merge commit
- PR_NUMBER=$(gh pr list \
- --state merged \
- --search "${{ github.sha }}" \
- --json number \
- --jq '.[0].number' 2>/dev/null || echo "")
+ # Use the GitHub API to find the PR that contains this commit
+ PR_NUMBER=$(gh api "repos/${{ github.repository }}/commits/${{ github.sha }}/pulls" \
+ --jq '.[0].number' 2>/dev/null || echo "")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: 📋 Prepare Release Notes file | |
| if: ${{ matrix.platform == 'android' }} | |
| env: | |
| RELEASE_NOTES_INPUT: ${{ github.event.inputs.release_notes }} | |
| PR_BODY: ${{ github.event.pull_request.body }} | |
| run: | | |
| set -eo pipefail | |
| # Determine source of release notes: workflow input, PR body, or recent commits | |
| if [ -n "$RELEASE_NOTES_INPUT" ]; then | |
| NOTES="$RELEASE_NOTES_INPUT" | |
| elif [ -n "$PR_BODY" ]; then | |
| NOTES="$(printf '%s\n' "$PR_BODY" \ | |
| # Function to extract release notes from PR body | |
| extract_release_notes() { | |
| local body="$1" | |
| # Try to extract content under "## Release Notes" heading | |
| local notes="$(printf '%s\n' "$body" \ | |
| | awk 'f && /^## /{exit} /^## Release Notes/{f=1; next} f')" | |
| else | |
| # If no specific section found, use the entire body (up to first 500 chars for safety) | |
| if [ -z "$notes" ]; then | |
| notes="$(printf '%s\n' "$body" | head -c 500)" | |
| fi | |
| printf '%s\n' "$notes" | |
| } | |
| # Determine source of release notes | |
| NOTES="" | |
| # Check if this was triggered by a push event (likely a merge) | |
| if [ "${{ github.event_name }}" = "push" ]; then | |
| echo "Fetching PR body for merged commit..." | |
| # Get the PR number associated with this merge commit | |
| PR_NUMBER=$(gh pr list \ | |
| --state merged \ | |
| --search "${{ github.sha }}" \ | |
| --json number \ | |
| --jq '.[0].number' 2>/dev/null || echo "") | |
| if [ -n "$PR_NUMBER" ]; then | |
| echo "Found merged PR #$PR_NUMBER" | |
| # Fetch the PR body | |
| PR_BODY=$(gh pr view "$PR_NUMBER" --json body --jq '.body' 2>/dev/null || echo "") | |
| if [ -n "$PR_BODY" ]; then | |
| NOTES="$(extract_release_notes "$PR_BODY")" | |
| fi | |
| else | |
| echo "No associated PR found, checking commit message..." | |
| # Try to find PR number from commit message | |
| PR_FROM_COMMIT=$(git log -1 --pretty=%B | grep -oE '#[0-9]+' | head -1 | tr -d '#' || echo "") | |
| if [ -n "$PR_FROM_COMMIT" ]; then | |
| echo "Found PR #$PR_FROM_COMMIT from commit message" | |
| PR_BODY=$(gh pr view "$PR_FROM_COMMIT" --json body --jq '.body' 2>/dev/null || echo "") | |
| if [ -n "$PR_BODY" ]; then | |
| NOTES="$(extract_release_notes "$PR_BODY")" | |
| fi | |
| fi | |
| fi | |
| fi | |
| # Fallback to recent commits if no PR body found | |
| if [ -z "$NOTES" ]; then | |
| echo "No PR body found, using recent commits..." | |
| NOTES="$(git log -n 5 --pretty=format:'- %s')" | |
| fi | |
| # Fail if no notes extracted | |
| if [ -z "$NOTES" ]; then | |
| echo "Error: No release notes extracted" >&2 | |
| exit 1 | |
| fi | |
| # Write header and notes to file | |
| { | |
| echo "## Version 7.${{ github.run_number }} - $(date +%Y-%m-%d)" | |
| echo | |
| printf '%s\n' "$NOTES" | |
| } > RELEASE_NOTES.md | |
| echo "Release notes prepared:" | |
| cat RELEASE_NOTES.md | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| - name: 📋 Prepare Release Notes file | |
| if: ${{ matrix.platform == 'android' }} | |
| run: | | |
| set -eo pipefail | |
| # Function to extract release notes from PR body | |
| extract_release_notes() { | |
| local body="$1" | |
| # Try to extract content under "## Release Notes" heading | |
| local notes="$(printf '%s\n' "$body" \ | |
| | awk 'flag && /^## /{exit} /^## Release Notes/{flag=1; next} flag')" | |
| # If no specific section found, use the entire body (up to first 500 chars for safety) | |
| if [ -z "$notes" ]; then | |
| notes="$(printf '%s\n' "$body" | head -c 500)" | |
| fi | |
| printf '%s\n' "$notes" | |
| } | |
| # Determine source of release notes | |
| NOTES="" | |
| # Check if this was triggered by a push event (likely a merge) | |
| if [ "${{ github.event_name }}" = "push" ]; then | |
| echo "Fetching PR body for merged commit..." | |
| # Use the GitHub API to find the PR that contains this commit | |
| PR_NUMBER=$(gh api "repos/${{ github.repository }}/commits/${{ github.sha }}/pulls" \ | |
| --jq '.[0].number' 2>/dev/null || echo "") | |
| if [ -n "$PR_NUMBER" ]; then | |
| echo "Found merged PR #$PR_NUMBER" | |
| # Fetch the PR body | |
| PR_BODY=$(gh pr view "$PR_NUMBER" --json body --jq '.body' 2>/dev/null || echo "") | |
| if [ -n "$PR_BODY" ]; then | |
| NOTES="$(extract_release_notes "$PR_BODY")" | |
| fi | |
| else | |
| echo "No associated PR found, checking commit message..." | |
| # Try to find PR number from commit message | |
| PR_FROM_COMMIT=$(git log -1 --pretty=%B | grep -oE '#[0-9]+' | head -1 | tr -d '#' || echo "") | |
| if [ -n "$PR_FROM_COMMIT" ]; then | |
| echo "Found PR #$PR_FROM_COMMIT from commit message" | |
| PR_BODY=$(gh pr view "$PR_FROM_COMMIT" --json body --jq '.body' 2>/dev/null || echo "") | |
| if [ -n "$PR_BODY" ]; then | |
| NOTES="$(extract_release_notes "$PR_BODY")" | |
| fi | |
| fi | |
| fi | |
| fi | |
| # Fallback to recent commits if no PR body found | |
| if [ -z "$NOTES" ]; then | |
| echo "No PR body found, using recent commits..." | |
| NOTES="$(git log -n 5 --pretty=format:'- %s')" | |
| fi | |
| # Fail if no notes extracted | |
| if [ -z "$NOTES" ]; then | |
| echo "Error: No release notes extracted" >&2 | |
| exit 1 | |
| fi | |
| # Write header and notes to file | |
| { | |
| echo "## Version 7.${{ github.run_number }} - $(date +%Y-%m-%d)" | |
| echo | |
| printf '%s\n' "$NOTES" | |
| } > RELEASE_NOTES.md | |
| echo "Release notes prepared:" | |
| cat RELEASE_NOTES.md | |
| env: | |
| GH_TOKEN: ${{ github.token }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (3)
.github/workflows/react-native-cicd.yml (1)
324-338: Release notes extraction and PR detection logic looks solid.The multi-source approach for finding PR information is well-designed, with graceful fallback from commit message → GitHub API → git log. This addresses the earlier review concern about PR detection reliability.
Note: The commit message extraction (line 324) is a nice addition that wasn't in the prior review suggestion.
Minor: Consider renaming the awk variable
ftoflagon line 306 for clarity, though this is purely cosmetic:- local notes="$(printf '%s\n' "$body" \ - | awk 'f && /^## /{exit} /^## Release Notes/{f=1; next} f')" + local notes="$(printf '%s\n' "$body" \ + | awk 'flag && /^## /{exit} /^## Release Notes/{flag=1; next} flag')"src/services/push-notification.ts (2)
1-1: Remove unused import.The
notifeeimport is not used anywhere in this file.-import notifee from '@notifee/react-native'; import messaging from '@react-native-firebase/messaging';
204-204: Simplify redundant ternary.Both branches of the ternary return the same value.
- const token = Platform.OS === 'ios' ? devicePushToken.data : devicePushToken.data; + const token = devicePushToken.data;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.github/workflows/react-native-cicd.yml(4 hunks)src/components/calls/dispatch-selection-modal.tsx(6 hunks)src/services/__tests__/notification-sound.service.test.ts(1 hunks)src/services/__tests__/push-notification.test.ts(4 hunks)src/services/notification-sound.service.ts(1 hunks)src/services/push-notification.ts(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/services/tests/notification-sound.service.test.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx}: Write concise, type-safe TypeScript code
Use camelCase for variable and function names (e.g., isFetchingData, handleUserInput)
Use TypeScript for all components, favoring interfaces for props and state
Avoid using any; strive for precise types
Use Expo SecureStore for sensitive data
Use zustand for state management
Use react-query for data fetching and caching
Use react-i18next for internationalization
Use react-native-mmkv for local storage
Use axios for API requests
**/*.{ts,tsx}: Write concise, type-safe TypeScript code
Use camelCase for variable and function names
Use TypeScript for all components, favoring interfaces for props and state
Avoid using any; strive for precise types
Use React Navigation for handling navigation and deep linking
Handle errors gracefully and provide user feedback
Use Expo's SecureStore for sensitive data
Use zustand for state management
Use react-query for data fetching
Use react-i18next for internationalization
Use react-native-mmkv for local storage
Use axios for API requests
Files:
src/services/notification-sound.service.tssrc/services/__tests__/push-notification.test.tssrc/services/push-notification.tssrc/components/calls/dispatch-selection-modal.tsx
**/*
📄 CodeRabbit inference engine (.cursorrules)
Directory and file names should be lowercase and hyphenated (e.g., user-profile, chat-screen)
Files:
src/services/notification-sound.service.tssrc/services/__tests__/push-notification.test.tssrc/services/push-notification.tssrc/components/calls/dispatch-selection-modal.tsx
**/*.{test.ts,test.tsx,spec.ts,spec.tsx}
📄 CodeRabbit inference engine (.cursorrules)
Create and use Jest tests to validate all generated components
Files:
src/services/__tests__/push-notification.test.ts
**/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
Generate tests for all components, services, and logic; ensure tests run without errors
Files:
src/services/__tests__/push-notification.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Create and use Jest tests for all generated components
Files:
src/services/__tests__/push-notification.test.ts
**/*.tsx
📄 CodeRabbit inference engine (.cursorrules)
**/*.tsx: Use functional components and hooks over class components
Use PascalCase for React component names (e.g., UserProfile, ChatScreen)
Utilize React.FC for defining functional components with props
Minimize useEffect, useState, and heavy computations inside render
Use React.memo() for components with static props to prevent unnecessary re-renders
Optimize FlatList with removeClippedSubviews, maxToRenderPerBatch, windowSize
Use getItemLayout for FlatList when items have consistent size
Avoid anonymous functions in renderItem or event handlers to prevent re-renders
Use gluestack-ui for styling; if no component exists in src/components/ui, style via StyleSheet.create or styled-components
Optimize images using react-native-fast-image
Use React Navigation for navigation and deep linking with best practices
Wrap all user-facing text in t() from react-i18next
Use react-hook-form for form handling
Use @rnmapbox/maps for maps or vehicle navigation
Use lucide-react-native for icons directly in markup; do not use the gluestack-ui icon component
Use the conditional operator (?:) for conditional rendering instead of &&
**/*.tsx: Use functional components and hooks over class components
Use PascalCase for component names
Utilize React.FC for defining functional components with props
Minimize useEffect/useState and heavy computations inside render
Use React.memo for components with static props to prevent unnecessary re-renders
Optimize FlatList with removeClippedSubviews, maxToRenderPerBatch, and windowSize
Use getItemLayout for FlatList when items have consistent size
Avoid anonymous functions in renderItem or event handlers
Optimize image handling using react-native-fast-image
Wrap all user-facing text in t() from react-i18next
Ensure support for dark mode and light mode
Ensure the app is accessible following WCAG for mobile
Use react-hook-form for form handling
Use @rnmapbox/maps for maps and navigation
Use lucide-react-native for icons directly in markup; do not us...
Files:
src/components/calls/dispatch-selection-modal.tsx
{components/ui/**/*.{ts,tsx},**/*.tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use gluestack-ui consistently; if no component exists in components/ui, style via StyleSheet.create or styled-components
Files:
src/components/calls/dispatch-selection-modal.tsx
🧠 Learnings (10)
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/*.tsx : Use React.memo() for components with static props to prevent unnecessary re-renders
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to **/*.tsx : Use React.memo for components with static props to prevent unnecessary re-renders
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to **/*.tsx : Minimize useEffect/useState and heavy computations inside render
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/*.tsx : Minimize useEffect, useState, and heavy computations inside render
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/*.tsx : Use functional components and hooks over class components
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to **/*.tsx : Use lucide-react-native for icons directly in markup; do not use gluestack-ui icon component
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/*.tsx : Use lucide-react-native for icons directly in markup; do not use the gluestack-ui icon component
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/*.tsx : Use React Navigation for navigation and deep linking with best practices
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to {components/ui/**/*.{ts,tsx},**/*.tsx} : Use gluestack-ui consistently; if no component exists in components/ui, style via StyleSheet.create or styled-components
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to **/*.tsx : Optimize image handling using react-native-fast-image
Applied to files:
src/components/calls/dispatch-selection-modal.tsx
🧬 Code graph analysis (2)
src/services/notification-sound.service.ts (3)
__mocks__/expo-av.ts (3)
Audio(2-28)InterruptionModeIOS(30-34)AVPlaybackSource(36-36)src/lib/logging/index.tsx (2)
logger(80-80)error(74-76)src/stores/push-notification/store.ts (1)
NotificationType(13-13)
src/services/push-notification.ts (2)
src/lib/logging/index.tsx (1)
logger(80-80)src/stores/push-notification/store.ts (1)
usePushNotificationModalStore(32-104)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
🔇 Additional comments (6)
.github/workflows/react-native-cicd.yml (2)
50-50: Also applies to: 75-76
381-434: Changerawr API integration well-implemented with robust error handling.The inline credential check (lines 387-390) provides clear messaging and allows builds to proceed when optional service credentials aren't configured. JSON payload construction properly escapes variables using
jq --arg, and response parsing correctly extracts HTTP status codes using the reliablecurl -w "\n%{http_code}" -spattern paired withtail -n1andsed '$d'. The build appropriately warns on failures without failing.src/components/calls/dispatch-selection-modal.tsx (1)
3-3: Good fix—direct call resolves the stale-memo issue.Removing
useMemoand callinggetFilteredData()directly ensuresfilteredDataupdates on every render, which properly addresses the previous issue where the memo dependencies were incomplete and caused stale data.Also applies to: 30-30
src/services/__tests__/push-notification.test.ts (1)
29-31: Comprehensive listener lifecycle tests.The new test section properly validates that listeners are registered during initialization and cleaned up correctly, including edge cases like cleanup without initialization and multiple cleanup calls. The mock setup enables precise verification of listener removal.
Also applies to: 87-95, 376-435
src/services/push-notification.ts (2)
25-27: Listener cleanup properly implemented.All listener handles are now correctly stored to instance properties and cleaned up in the
cleanup()method. This resolves the previous critical issue where listeners would accumulate after each initialization cycle.Also applies to: 96-97, 100-121, 290-303
85-93: ****The properties
shouldShowBannerandshouldShowListare valid and officially supported in expo-notifications v0.28.3. These are documented properties in the official Expo notification handler API, and they replacedshouldShowAlertin the NotificationBehavior interface as part of updates to better align with iOS's UNNotificationPresentationOptions. The code at lines 85-93 correctly implements the current notification handler API.
| logger.error({ | ||
| message: 'Failed to initialize notification sound service', | ||
| context: { error }, | ||
| }); | ||
| // Reset initialization promise on failure so it can be retried | ||
| this.initializationPromise = null; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Propagate initialization failures to callers.
performInitialization() logs the error and clears initializationPromise, but it then returns normally. Any caller awaiting initialize()/initializeAudio() will think setup worked even though nothing loaded, leaving the service in a broken-but-silent state. After logging and resetting the flag, rethrow the error (wrapping non-Error values if needed) so upstream code can decide whether to retry, surface an alert, etc.
🤖 Prompt for AI Agents
In src/services/notification-sound.service.ts around lines 72 to 78,
performInitialization() currently logs the initialization error and clears
this.initializationPromise but then returns normally, leaving callers unaware of
the failure; change the method so after logging and resetting
this.initializationPromise it rethrows the error (if the caught value is not an
instance of Error, wrap it in a new Error with the caught value stringified) so
callers awaiting initialize()/initializeAudio() receive the failure and can
handle or retry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/services/notification-sound.service.ts (1)
71-78: Still not propagating initialization failures.This issue was flagged in a previous review but remains unresolved. When
performInitialization()catches an error, it logs and resets the promise but returns normally. Callers awaitinginitialize()will assume success even though the service is in a broken state.After line 77, rethrow the error:
} catch (error) { logger.error({ message: 'Failed to initialize notification sound service', context: { error }, }); // Reset initialization promise on failure so it can be retried this.initializationPromise = null; + throw error instanceof Error ? error : new Error(String(error)); }
🧹 Nitpick comments (2)
src/services/notification-sound.service.ts (2)
137-148: Inconsistent use of the loadSound helper.Lines 137-138 manually download the chat asset before calling
loadSound(), which already handles downloading internally (lines 109-110). Then lines 143-148 manually create the group-chat sound instead of using the helper, bypassing its error handling.Simplify by using the helper consistently:
- // Load chat sound - const chatSoundAsset = Asset.fromModule(require('@assets/audio/newchat.wav')); - await chatSoundAsset.downloadAsync(); - this.chatSound = await this.loadSound(require('@assets/audio/newchat.wav'), 'chat'); - // Group chat uses the same sound as regular chat - const { sound: groupChatSound } = await Audio.Sound.createAsync({ uri: chatSoundAsset.localUri || chatSoundAsset.uri } as AVPlaybackSource, { - shouldPlay: false, - isLooping: false, - volume: 1.0, - }); - this.groupChatSound = groupChatSound; + // Group chat uses the same audio file as regular chat + this.groupChatSound = await this.loadSound(require('@assets/audio/newchat.wav'), 'group-chat');
200-205: Optional: Remove unnecessary local variable capture.Since
initializeAudio()completes at line 197, the instance properties are stable and can be used directly in the switch statement. The local variables add verbosity without improving safety or clarity.Simplify by accessing properties directly:
// Ensure audio is initialized before accessing sound properties await this.initializeAudio(); - // Capture sound properties into local variables after initialization - const callSound = this.callSound; - const messageSound = this.messageSound; - const chatSound = this.chatSound; - const groupChatSound = this.groupChatSound; - const defaultSound = this.defaultSound; - switch (type) { case 'call': - await this.playSound(callSound, 'call'); + await this.playSound(this.callSound, 'call'); break; case 'message': - await this.playSound(messageSound, 'message'); + await this.playSound(this.messageSound, 'message'); break; case 'chat': - await this.playSound(chatSound, 'chat'); + await this.playSound(this.chatSound, 'chat'); break; case 'group-chat': - await this.playSound(groupChatSound, 'group-chat'); + await this.playSound(this.groupChatSound, 'group-chat'); break; case 'unknown': default: - await this.playSound(defaultSound, 'default'); + await this.playSound(this.defaultSound, 'default'); break; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/services/notification-sound.service.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx}: Write concise, type-safe TypeScript code
Use camelCase for variable and function names (e.g., isFetchingData, handleUserInput)
Use TypeScript for all components, favoring interfaces for props and state
Avoid using any; strive for precise types
Use Expo SecureStore for sensitive data
Use zustand for state management
Use react-query for data fetching and caching
Use react-i18next for internationalization
Use react-native-mmkv for local storage
Use axios for API requests
**/*.{ts,tsx}: Write concise, type-safe TypeScript code
Use camelCase for variable and function names
Use TypeScript for all components, favoring interfaces for props and state
Avoid using any; strive for precise types
Use React Navigation for handling navigation and deep linking
Handle errors gracefully and provide user feedback
Use Expo's SecureStore for sensitive data
Use zustand for state management
Use react-query for data fetching
Use react-i18next for internationalization
Use react-native-mmkv for local storage
Use axios for API requests
Files:
src/services/notification-sound.service.ts
**/*
📄 CodeRabbit inference engine (.cursorrules)
Directory and file names should be lowercase and hyphenated (e.g., user-profile, chat-screen)
Files:
src/services/notification-sound.service.ts
🧬 Code graph analysis (1)
src/services/notification-sound.service.ts (3)
__mocks__/expo-av.ts (3)
Audio(2-28)InterruptionModeIOS(30-34)AVPlaybackSource(36-36)src/lib/logging/index.tsx (2)
logger(80-80)error(74-76)src/stores/push-notification/store.ts (1)
NotificationType(13-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
|
Approve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is approved.
Summary by CodeRabbit
New Features
Chores
Tests