-
-
Notifications
You must be signed in to change notification settings - Fork 33
Feat/foreground service notifications #802
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
base: main
Are you sure you want to change the base?
Conversation
…re-mansion/react-native-audio-api into feat/fs_android_recording
michalsek
left a 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.
Small nitpicks, but overall great job, thanks for this! :)
packages/audiodocs/docs/system/playback-notification-manager.mdx
Outdated
Show resolved
Hide resolved
packages/audiodocs/docs/system/recording-notification-manager.mdx
Outdated
Show resolved
Hide resolved
...-native-audio-api/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt
Outdated
Show resolved
Hide resolved
...id/src/main/java/com/swmansion/audioapi/system/notification/ForegroundNotificationService.kt
Outdated
Show resolved
Hide resolved
...pi/android/src/main/java/com/swmansion/audioapi/system/notification/RecordingNotification.kt
Outdated
Show resolved
Hide resolved
...pi/android/src/main/java/com/swmansion/audioapi/system/notification/RecordingNotification.kt
Show resolved
Hide resolved
...pi/android/src/main/java/com/swmansion/audioapi/system/notification/RecordingNotification.kt
Show resolved
Hide resolved
packages/react-native-audio-api/src/web-system/notification/RecordingNotificationManager.ts
Outdated
Show resolved
Hide resolved
maciejmakowski2003
left a 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.
beside a few nitpicks, really great work!!! fingers crossed that it works as well as android code looks 🙃
| useEffect(() => { | ||
| // Create AudioContext in suspended state | ||
| // Will be resumed when showing notification | ||
| audioContextRef.current = new AudioContext({ initSuspended: true }); |
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.
we do not have that option anymore
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.
AudioContext is by default suspended. However if for the first time user starts sth, it will resume context.
| | 'skipBackward'; | ||
|
|
||
| /// Event names for playback notification actions. | ||
| interface PlaybackNotificationEvent { |
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.
where is seek event? (change playback position)
| } | ||
|
|
||
| // Disable all remote commands | ||
| MPRemoteCommandCenter *remoteCenter = [MPRemoteCommandCenter sharedCommandCenter]; |
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.
do we need all of them? we only support some subset
| registerNotification( | ||
| type: string, | ||
| key: string | ||
| ): Promise<{ success: boolean; error?: string }>; | ||
| showNotification( | ||
| key: string, | ||
| options: { [key: string]: string | boolean | number | undefined } | ||
| ): Promise<{ success: boolean; error?: string }>; | ||
| updateNotification( | ||
| key: string, | ||
| options: { [key: string]: string | boolean | number | undefined } | ||
| ): Promise<{ success: boolean; error?: string }>; | ||
| hideNotification(key: string): Promise<{ success: boolean; error?: string }>; | ||
| unregisterNotification( | ||
| key: string | ||
| ): Promise<{ success: boolean; error?: string }>; |
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.
you can extract repeating types to some named interfaces and types
| { | ||
| if (!type || !key) { | ||
| NSLog(@"[NotificationRegistry] Invalid type or key"); | ||
| return NO; |
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.
we need to agree internally on consistency in objective-c parts
bool vs BOOL
true vs YES
false vs NO
anyway it will require some changes
| if ([control isEqualToString:@"play"]) { | ||
| remoteCommandName = @"play"; | ||
| } else if ([control isEqualToString:@"pause"]) { | ||
| remoteCommandName = @"pause"; | ||
| } else if ([control isEqualToString:@"next"]) { | ||
| remoteCommandName = @"next"; | ||
| } else if ([control isEqualToString:@"previous"]) { | ||
| remoteCommandName = @"previous"; | ||
| } else if ([control isEqualToString:@"skipForward"]) { | ||
| remoteCommandName = @"skipForward"; | ||
| } else if ([control isEqualToString:@"skipBackward"]) { | ||
| remoteCommandName = @"skipBackward"; | ||
| } else if ([control isEqualToString:@"seek"]) { | ||
| remoteCommandName = @"seek"; | ||
| } |
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.
| if ([control isEqualToString:@"play"]) { | |
| remoteCommandName = @"play"; | |
| } else if ([control isEqualToString:@"pause"]) { | |
| remoteCommandName = @"pause"; | |
| } else if ([control isEqualToString:@"next"]) { | |
| remoteCommandName = @"next"; | |
| } else if ([control isEqualToString:@"previous"]) { | |
| remoteCommandName = @"previous"; | |
| } else if ([control isEqualToString:@"skipForward"]) { | |
| remoteCommandName = @"skipForward"; | |
| } else if ([control isEqualToString:@"skipBackward"]) { | |
| remoteCommandName = @"skipBackward"; | |
| } else if ([control isEqualToString:@"seek"]) { | |
| remoteCommandName = @"seek"; | |
| } | |
| NSSet *validControls = [NSSet setWithObjects: | |
| @"play", | |
| @"pause", | |
| @"next", | |
| @"previous", | |
| @"skipForward", | |
| @"skipBackward", | |
| @"seek" | |
| ]; | |
| if ([validControls containsObject:control]) { | |
| [self enableRemoteCommand:control enabled:enabled]; | |
| } |
|
|
||
| // New notification system | ||
| registerNotification( | ||
| type: string, |
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.
you can type it stronger than string
| 'recording', | ||
| this.notificationKey |
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.
idk if its just me, bur registering notification of type 'recording' for 'recording' key seems kind of "strange"
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.
if it is intended as only one notification at the time, I think it can be simplified, but if it can display more than one there is no method to change the notificationKey
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.
why only android lock screen manager is deleted, if ios one is not used either?
| #define NOW_PLAYING_INFO_KEYS \ | ||
| @{ \ | ||
| @"title" : MPMediaItemPropertyTitle, \ | ||
| @"artist" : MPMediaItemPropertyArtist, \ | ||
| @"album" : MPMediaItemPropertyAlbumTitle, \ | ||
| @"duration" : MPMediaItemPropertyPlaybackDuration, \ | ||
| @"elapsedTime" : MPNowPlayingInfoPropertyElapsedPlaybackTime, \ | ||
| @"speed" : MPNowPlayingInfoPropertyPlaybackRate \ | ||
| } |
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.
what about artwork?
| } else if ([state isEqualToString:@"paused"]) { | ||
| playbackState = MPNowPlayingPlaybackStatePaused; | ||
| } else if ([state isEqualToString:@"stopped"]) { | ||
| playbackState = MPNowPlayingPlaybackStateStopped; |
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.
you cannot pass 'stopped' from typescript
| self.playingInfoCenter.playbackState = playbackState; | ||
|
|
||
| // Handle artwork | ||
| NSString *artworkUrl = [self getArtworkUrl:_currentInfo[@"artwork"]]; |
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.
artworkUrl will always be null, because there is no entry in map defined above and you put in current info only keys that exist in pre-defined map
| registerNotification : (NSString *)type key : (NSString *)key resolve : (RCTPromiseResolveBlock) | ||
| resolve reject : (RCTPromiseRejectBlock)reject) |
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.
if the method is based on promises and cannot be resolved instantly, invoke methods on seperate queue, similar to getDevicesInfo function
💀
Closes #820
Closes RNAA-310
TODO
Maybe TODO
NotificationReceiver for notification dissmised event can be centralized right now there are two receivers(not wanted)AudioManageryou should usePlaybackNotificationManagerIntroduced changes
RecordingNotificationManagerfor management of notification dedicated for recordingPlaybackNotificationManagerfor management of notification dedicated for playbackAudioManagerChecklist