diff --git a/app/src/main/java/com/github/libretube/constants/IntentData.kt b/app/src/main/java/com/github/libretube/constants/IntentData.kt index 24626b00e4..80c2f8d061 100644 --- a/app/src/main/java/com/github/libretube/constants/IntentData.kt +++ b/app/src/main/java/com/github/libretube/constants/IntentData.kt @@ -50,4 +50,5 @@ object IntentData { const val videoInfo = "videoInfo" const val offlinePlayer = "offlinePlayer" const val downloadTab = "downloadTab" + const val shuffle = "shuffle" } diff --git a/app/src/main/java/com/github/libretube/helpers/BackgroundHelper.kt b/app/src/main/java/com/github/libretube/helpers/BackgroundHelper.kt index bdba88cfcb..39983fbb98 100644 --- a/app/src/main/java/com/github/libretube/helpers/BackgroundHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/BackgroundHelper.kt @@ -77,11 +77,12 @@ object BackgroundHelper { * @param context the current context * @param videoId the videoId of the video or null if all available downloads should be shuffled */ - fun playOnBackgroundOffline(context: Context, videoId: String?, downloadTab: DownloadTab) { + fun playOnBackgroundOffline(context: Context, videoId: String?, downloadTab: DownloadTab, shuffle: Boolean = false) { stopBackgroundPlay(context) val playerIntent = Intent(context, OfflinePlayerService::class.java) .putExtra(IntentData.videoId, videoId) + .putExtra(IntentData.shuffle, shuffle) .putExtra(IntentData.downloadTab, downloadTab) ContextCompat.startForegroundService(context, playerIntent) diff --git a/app/src/main/java/com/github/libretube/services/OfflinePlayerService.kt b/app/src/main/java/com/github/libretube/services/OfflinePlayerService.kt index 91003c5e50..ca209e30de 100644 --- a/app/src/main/java/com/github/libretube/services/OfflinePlayerService.kt +++ b/app/src/main/java/com/github/libretube/services/OfflinePlayerService.kt @@ -21,6 +21,7 @@ import com.github.libretube.ui.fragments.DownloadTab import com.github.libretube.util.PlayingQueue import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import kotlin.io.path.exists @@ -31,10 +32,20 @@ import kotlin.io.path.exists class OfflinePlayerService : AbstractPlayerService() { private var downloadWithItems: DownloadWithItems? = null private lateinit var downloadTab: DownloadTab + private var shuffle: Boolean = false override suspend fun onServiceCreated(intent: Intent) { - videoId = intent.getStringExtra(IntentData.videoId) ?: return downloadTab = intent.serializableExtra(IntentData.downloadTab)!! + shuffle = intent.getBooleanExtra(IntentData.shuffle, false) + + videoId = if (shuffle) { + runBlocking(Dispatchers.IO) { + Database.downloadDao().getAll().filterByTab(downloadTab) + .randomOrNull()?.download?.videoId + } + } else { + intent.getStringExtra(IntentData.videoId) + } ?: return PlayingQueue.clear() @@ -92,7 +103,11 @@ class OfflinePlayerService : AbstractPlayerService() { private suspend fun fillQueue() { val downloads = withContext(Dispatchers.IO) { Database.downloadDao().getAll() - }.filterByTab(downloadTab) + } + .filterByTab(downloadTab) + .toMutableList() + + if (shuffle) downloads.shuffle() PlayingQueue.insertRelatedStreams(downloads.map { it.download.toStreamItem() }) } 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 e42e0d69b8..1f24312b73 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 @@ -31,7 +31,9 @@ import com.github.libretube.db.obj.filterByTab import com.github.libretube.extensions.ceilHalf import com.github.libretube.extensions.formatAsFileSize import com.github.libretube.extensions.serializable +import com.github.libretube.helpers.BackgroundHelper import com.github.libretube.helpers.DownloadHelper +import com.github.libretube.helpers.NavigationHelper import com.github.libretube.helpers.PreferenceHelper import com.github.libretube.obj.DownloadStatus import com.github.libretube.receivers.DownloadReceiver @@ -253,6 +255,17 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment() { binding.deleteAll.setOnClickListener { showDeleteAllDialog(binding.root.context, adapter) } + + binding.shuffleAll.setOnClickListener { + BackgroundHelper.playOnBackgroundOffline( + requireContext(), + null, + downloadTab, + shuffle = true + ) + + NavigationHelper.startAudioPlayer(requireContext(), offlinePlayer = true) + } } private fun toggleVisibilities() { @@ -262,6 +275,7 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment() { binding.downloadsEmpty.isVisible = isEmpty binding.downloadsContainer.isGone = isEmpty binding.deleteAll.isGone = isEmpty + binding.shuffleAll.isGone = isEmpty || downloadTab != DownloadTab.AUDIO } private fun sortDownloadList(sortType: Int, previousSortType: Int? = null) { diff --git a/app/src/main/res/layout/fragment_download_content.xml b/app/src/main/res/layout/fragment_download_content.xml index d8993f8da9..183707b203 100644 --- a/app/src/main/res/layout/fragment_download_content.xml +++ b/app/src/main/res/layout/fragment_download_content.xml @@ -60,20 +60,40 @@ android:textStyle="bold" /> - + android:layout_marginEnd="18dp" + android:layout_marginBottom="18dp" + android:orientation="vertical"> + + + + + + \ No newline at end of file