@@ -85,6 +85,18 @@ import com.metrolist.music.constants.CrossfadeDurationKey
8585import com.metrolist.music.constants.CrossfadeEnabledKey
8686import com.metrolist.music.constants.CrossfadeGaplessKey
8787import com.metrolist.music.constants.DisableLoadMoreWhenRepeatAllKey
88+ import android.os.Handler
89+ import android.os.Looper
90+ import android.widget.Toast
91+ import com.metrolist.music.constants.DiscordActivityNameKey
92+ import com.metrolist.music.constants.DiscordActivityTypeKey
93+ import com.metrolist.music.constants.DiscordAdvancedModeKey
94+ import com.metrolist.music.constants.DiscordAvatarKey
95+ import com.metrolist.music.constants.DiscordButton1TextKey
96+ import com.metrolist.music.constants.DiscordButton1VisibleKey
97+ import com.metrolist.music.constants.DiscordButton2TextKey
98+ import com.metrolist.music.constants.DiscordButton2VisibleKey
99+ import com.metrolist.music.constants.DiscordStatusKey
88100import com.metrolist.music.constants.DiscordTokenKey
89101import com.metrolist.music.constants.DiscordUseDetailsKey
90102import com.metrolist.music.constants.EnableDiscordRPCKey
@@ -119,6 +131,7 @@ import com.metrolist.music.db.entities.Event
119131import com.metrolist.music.db.entities.FormatEntity
120132import com.metrolist.music.db.entities.LyricsEntity
121133import com.metrolist.music.db.entities.RelatedSongMap
134+ import com.metrolist.music.db.entities.Song
122135import com.metrolist.music.di.DownloadCache
123136import com.metrolist.music.di.PlayerCache
124137import com.metrolist.music.eq.EqualizerService
@@ -372,7 +385,7 @@ class MusicService :
372385 if (player.isPlaying) {
373386 scope.launch {
374387 currentSong.value?.let { song ->
375- discordRpc?.updateSong (song, player.currentPosition, player.playbackParameters.speed, dataStore.get( DiscordUseDetailsKey , false ) )
388+ updateDiscordRPC (song)
376389 }
377390 }
378391 }
@@ -518,7 +531,7 @@ class MusicService :
518531 val mediaId = player.currentMetadata?.id
519532 if (mediaId != null ) {
520533 database.song(mediaId).first()?.let { song ->
521- discordRpc?.updateSong (song, player.currentPosition, player.playbackParameters.speed, dataStore.get( DiscordUseDetailsKey , false ) )
534+ updateDiscordRPC (song)
522535 }
523536 }
524537 }
@@ -620,25 +633,33 @@ class MusicService :
620633 discordRpc = DiscordRPC (this , key)
621634 if (player.playbackState == Player .STATE_READY && player.playWhenReady) {
622635 currentSong.value?.let {
623- discordRpc?.updateSong (it, player.currentPosition, player.playbackParameters.speed, dataStore.get( DiscordUseDetailsKey , false ) )
636+ updateDiscordRPC (it, true )
624637 }
625638 }
626639 }
627640 }
628641
629- // details key stuff
642+ // Watch all Discord customization preferences
630643 dataStore.data
631- .map { it[DiscordUseDetailsKey ] ? : false }
632- .debounce(1000 )
644+ .map {
645+ listOf (
646+ it[DiscordUseDetailsKey ],
647+ it[DiscordAdvancedModeKey ],
648+ it[DiscordStatusKey ],
649+ it[DiscordButton1TextKey ],
650+ it[DiscordButton1VisibleKey ],
651+ it[DiscordButton2TextKey ],
652+ it[DiscordButton2VisibleKey ],
653+ it[DiscordActivityTypeKey ],
654+ it[DiscordActivityNameKey ]
655+ )
656+ }
657+ .debounce(300 )
633658 .distinctUntilChanged()
634- .collect(scope) { useDetails ->
635- if (player.playbackState == Player .STATE_READY && player.playWhenReady ) {
659+ .collect(scope) {
660+ if (player.playbackState == Player .STATE_READY ) {
636661 currentSong.value?.let { song ->
637- discordUpdateJob?.cancel()
638- discordUpdateJob = scope.launch {
639- delay(1000 )
640- discordRpc?.updateSong(song, player.currentPosition, player.playbackParameters.speed, useDetails)
641- }
662+ updateDiscordRPC(song, true )
642663 }
643664 }
644665 }
@@ -1874,7 +1895,7 @@ class MusicService :
18741895 scope.launch {
18751896 // Fetch song from database to get full info
18761897 database.song(mediaId).first()?.let { song ->
1877- discordRpc?.updateSong (song, player.currentPosition, player.playbackParameters.speed, dataStore.get( DiscordUseDetailsKey , false ) )
1898+ updateDiscordRPC (song)
18781899 }
18791900 }
18801901 }
@@ -1985,7 +2006,7 @@ class MusicService :
19852006 delay(1000 )
19862007 if (player.playWhenReady && player.playbackState == Player .STATE_READY ) {
19872008 currentSong.value?.let { song ->
1988- discordRpc?.updateSong (song, player.currentPosition, playbackParameters.speed, dataStore.get( DiscordUseDetailsKey , false ) )
2009+ updateDiscordRPC (song)
19892010 }
19902011 }
19912012 }
@@ -2502,6 +2523,43 @@ class MusicService :
25022523 }
25032524 }
25042525
2526+ private fun updateDiscordRPC (song : Song , showFeedback : Boolean = false) {
2527+ val useDetails = dataStore.get(DiscordUseDetailsKey , false )
2528+ val advancedMode = dataStore.get(DiscordAdvancedModeKey , false )
2529+
2530+ val status = if (advancedMode) dataStore.get(DiscordStatusKey , " online" ) else " online"
2531+ val b1Text = if (advancedMode) dataStore.get(DiscordButton1TextKey , " " ) else " "
2532+ val b1Visible = if (advancedMode) dataStore.get(DiscordButton1VisibleKey , true ) else true
2533+ val b2Text = if (advancedMode) dataStore.get(DiscordButton2TextKey , " " ) else " "
2534+ val b2Visible = if (advancedMode) dataStore.get(DiscordButton2VisibleKey , true ) else true
2535+ val activityType = if (advancedMode) dataStore.get(DiscordActivityTypeKey , " listening" ) else " listening"
2536+ val activityName = if (advancedMode) dataStore.get(DiscordActivityNameKey , " " ) else " "
2537+
2538+ discordUpdateJob?.cancel()
2539+ discordUpdateJob = scope.launch {
2540+ discordRpc?.updateSong(
2541+ song,
2542+ player.currentPosition,
2543+ player.playbackParameters.speed,
2544+ useDetails,
2545+ status,
2546+ b1Text,
2547+ b1Visible,
2548+ b2Text,
2549+ b2Visible,
2550+ activityType,
2551+ activityName
2552+ )?.onFailure {
2553+ // Rate limited or error
2554+ if (showFeedback) {
2555+ Handler (Looper .getMainLooper()).post {
2556+ Toast .makeText(this @MusicService, " Discord RPC update failed: ${it.message} " , Toast .LENGTH_SHORT ).show()
2557+ }
2558+ }
2559+ }
2560+ }
2561+ }
2562+
25052563 private fun createDataSourceFactory (): DataSource .Factory {
25062564 return ResolvingDataSource .Factory (createCacheDataSource()) { dataSpec ->
25072565 val mediaId = dataSpec.key ? : error(" No media id" )
0 commit comments