From 12be4c716cd88fd00f413defd96a7d63292000ed Mon Sep 17 00:00:00 2001 From: Bnyro Date: Sun, 24 Nov 2024 14:28:30 +0100 Subject: [PATCH] feat: reuse existing player when selecting other video while playing --- .../libretube/helpers/NavigationHelper.kt | 60 ++++++++++++++----- .../libretube/ui/activities/MainActivity.kt | 11 +++- .../ui/activities/NoInternetActivity.kt | 2 +- .../libretube/ui/adapters/DownloadsAdapter.kt | 2 +- .../ui/fragments/AudioPlayerFragment.kt | 4 ++ .../ui/fragments/DownloadsFragment.kt | 2 +- .../libretube/ui/fragments/PlayerFragment.kt | 4 +- .../ui/sheets/VideoOptionsBottomSheet.kt | 4 +- 8 files changed, 65 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/github/libretube/helpers/NavigationHelper.kt b/app/src/main/java/com/github/libretube/helpers/NavigationHelper.kt index 92aa015ff..34d70d4d8 100644 --- a/app/src/main/java/com/github/libretube/helpers/NavigationHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/NavigationHelper.kt @@ -6,11 +6,13 @@ import android.content.Intent import android.os.Handler import android.os.Looper import android.os.Process +import androidx.annotation.OptIn import androidx.core.content.getSystemService import androidx.core.os.bundleOf import androidx.core.os.postDelayed import androidx.fragment.app.commitNow import androidx.fragment.app.replace +import androidx.media3.common.util.UnstableApi import com.github.libretube.NavDirections import com.github.libretube.R import com.github.libretube.constants.IntentData @@ -61,30 +63,56 @@ object NavigationHelper { if (videoUrlOrId == null) return if (PreferenceHelper.getBoolean(PreferenceKeys.AUDIO_ONLY_MODE, false) && !forceVideo) { - BackgroundHelper.playOnBackground( - context, - videoUrlOrId.toID(), - timestamp, - playlistId, - channelId, - keepQueue - ) - handler.postDelayed(500) { - startAudioPlayer(context) - } + navigateAudio(context, videoUrlOrId.toID(), playlistId, channelId, keepQueue, timestamp) return } + val activity = ContextHelper.unwrapActivity(context) + val attachedToRunningPlayer = activity.runOnPlayerFragment { + this.playNextVideo(videoUrlOrId.toID()) + true + } + if (attachedToRunningPlayer) return + val playerData = PlayerData(videoUrlOrId.toID(), playlistId, channelId, keepQueue, timestamp) val bundle = bundleOf(IntentData.playerData to playerData) - - val activity = ContextHelper.unwrapActivity(context) activity.supportFragmentManager.commitNow { replace(R.id.container, args = bundle) } } + @OptIn(UnstableApi::class) + fun navigateAudio( + context: Context, + videoId: String, + playlistId: String? = null, + channelId: String? = null, + keepQueue: Boolean = false, + timestamp: Long = 0, + minimizeByDefault: Boolean = false + ) { + val activity = ContextHelper.unwrapActivity(context) + val attachedToRunningPlayer = activity.runOnAudioPlayerFragment { + this.playNextVideo(videoId) + true + } + if (attachedToRunningPlayer) return + + BackgroundHelper.playOnBackground( + context, + videoId, + timestamp, + playlistId, + channelId, + keepQueue + ) + + handler.postDelayed(500) { + openAudioPlayerFragment(context, minimizeByDefault = minimizeByDefault) + } + } + fun navigatePlaylist(context: Context, playlistUrlOrId: String?, playlistType: PlaylistType) { if (playlistUrlOrId == null) return @@ -97,7 +125,11 @@ object NavigationHelper { /** * Start the audio player fragment */ - fun startAudioPlayer(context: Context, offlinePlayer: Boolean = false, minimizeByDefault: Boolean = false) { + fun openAudioPlayerFragment( + context: Context, + offlinePlayer: Boolean = false, + minimizeByDefault: Boolean = false + ) { val activity = ContextHelper.unwrapActivity(context) activity.supportFragmentManager.commitNow { val args = bundleOf( diff --git a/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt b/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt index 00374462e..66aed5545 100644 --- a/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt +++ b/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt @@ -468,7 +468,7 @@ class MainActivity : BaseActivity() { if (intent?.getBooleanExtra(IntentData.openAudioPlayer, false) == true) { val offlinePlayer = intent!!.getBooleanExtra(IntentData.offlinePlayer, false) - NavigationHelper.startAudioPlayer(this, offlinePlayer = offlinePlayer) + NavigationHelper.openAudioPlayerFragment(this, offlinePlayer = offlinePlayer) return } @@ -639,10 +639,17 @@ class MainActivity : BaseActivity() { * Attempt to run code on the player fragment if running * Returns true if a running player fragment was found and the action got consumed, else false */ - private fun runOnPlayerFragment(action: PlayerFragment.() -> Boolean): Boolean { + fun runOnPlayerFragment(action: PlayerFragment.() -> Boolean): Boolean { return supportFragmentManager.fragments.filterIsInstance() .firstOrNull() ?.let(action) ?: false } + + fun runOnAudioPlayerFragment(action: AudioPlayerFragment.() -> Boolean): Boolean { + return supportFragmentManager.fragments.filterIsInstance() + .firstOrNull() + ?.let(action) + ?: false + } } diff --git a/app/src/main/java/com/github/libretube/ui/activities/NoInternetActivity.kt b/app/src/main/java/com/github/libretube/ui/activities/NoInternetActivity.kt index af24147b6..e14b58fb8 100644 --- a/app/src/main/java/com/github/libretube/ui/activities/NoInternetActivity.kt +++ b/app/src/main/java/com/github/libretube/ui/activities/NoInternetActivity.kt @@ -69,7 +69,7 @@ class NoInternetActivity : BaseActivity() { super.onNewIntent(intent) if (intent.getBooleanExtra(IntentData.openAudioPlayer, false)) { - NavigationHelper.startAudioPlayer(this, offlinePlayer = true) + NavigationHelper.openAudioPlayerFragment(this, offlinePlayer = true) } } } diff --git a/app/src/main/java/com/github/libretube/ui/adapters/DownloadsAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/DownloadsAdapter.kt index 56528b635..1556017cd 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/DownloadsAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/DownloadsAdapter.kt @@ -114,7 +114,7 @@ class DownloadsAdapter( root.context.startActivity(intent) } else { BackgroundHelper.playOnBackgroundOffline(root.context, download.videoId, downloadTab) - NavigationHelper.startAudioPlayer(root.context, offlinePlayer = true) + NavigationHelper.openAudioPlayerFragment(root.context, offlinePlayer = true) } } diff --git a/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt index ec37ea673..dece92f3c 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt @@ -252,6 +252,10 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions { } } + fun playNextVideo(videoId: String) { + playerController?.navigateVideo(videoId) + } + @SuppressLint("ClickableViewAccessibility") private fun initializeTransitionLayout() { if (mainActivity == null) return diff --git a/app/src/main/java/com/github/libretube/ui/fragments/DownloadsFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/DownloadsFragment.kt index bce0eeb17..cf26dd588 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/DownloadsFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/DownloadsFragment.kt @@ -247,7 +247,7 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment() { shuffle = true ) - NavigationHelper.startAudioPlayer(requireContext(), offlinePlayer = true) + NavigationHelper.openAudioPlayerFragment(requireContext(), offlinePlayer = true) } } diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 803571886..6bab9d975 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -749,7 +749,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { keepVideoPlayerAlive = true ) killPlayerFragment() - NavigationHelper.startAudioPlayer(requireContext()) + NavigationHelper.openAudioPlayerFragment(requireContext()) } private fun updateFullscreenOrientation() { @@ -1020,7 +1020,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { /** * Manually skip to another video. */ - private fun playNextVideo(nextId: String) { + fun playNextVideo(nextId: String) { playerController.sendCustomCommand( AbstractPlayerService.runPlayerActionCommand, bundleOf(PlayerCommand.PLAY_VIDEO_BY_ID.name to nextId) diff --git a/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt b/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt index bec7b3544..f8840c5ff 100644 --- a/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt +++ b/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt @@ -14,7 +14,6 @@ import com.github.libretube.db.obj.WatchPosition import com.github.libretube.enums.ShareObjectType import com.github.libretube.extensions.parcelable import com.github.libretube.extensions.toID -import com.github.libretube.helpers.BackgroundHelper import com.github.libretube.helpers.DownloadHelper import com.github.libretube.helpers.NavigationHelper import com.github.libretube.helpers.PlayerHelper @@ -58,8 +57,7 @@ class VideoOptionsBottomSheet : BaseBottomSheet() { when (optionsList[which]) { // Start the background mode R.string.playOnBackground -> { - BackgroundHelper.playOnBackground(requireContext(), videoId) - NavigationHelper.startAudioPlayer(requireContext(), minimizeByDefault = true) + NavigationHelper.navigateAudio(requireContext(), videoId, minimizeByDefault = true) } // Add Video to Playlist Dialog R.string.addToPlaylist -> {