From 362201eddf350168cce250e72cb408465e521fda Mon Sep 17 00:00:00 2001 From: nomadics9 Date: Wed, 17 Jul 2024 05:58:26 +0300 Subject: [PATCH] feat: Transcoding Download / code: Cleanup --- .../fragments/EpisodeBottomSheetFragment.kt | 149 +++++---- .../ananas/fragments/MovieFragment.kt | 149 +++++---- .../ananas/fragments/SeasonFragment.kt | 41 +++ .../res/layout/dialog_quality_selection.xml | 39 --- .../nomadics9/ananas/di/DownloaderModule.kt | 1 + .../nomadics9/ananas/utils/DownloaderImpl.kt | 309 ++++++++++++++---- core/src/main/res/values/string_arrays.xml | 12 + .../res/xml/fragment_settings_downloads.xml | 13 + .../ananas/repository/JellyfinRepository.kt | 17 +- .../repository/JellyfinRepositoryImpl.kt | 120 ++++++- .../JellyfinRepositoryOfflineImpl.kt | 41 ++- .../viewmodels/PlayerActivityViewModel.kt | 93 +----- .../com/nomadics9/ananas/AppPreferences.kt | 12 + .../java/com/nomadics9/ananas/Constants.kt | 2 + 14 files changed, 694 insertions(+), 304 deletions(-) delete mode 100644 app/phone/src/main/res/layout/dialog_quality_selection.xml diff --git a/app/phone/src/main/java/com/nomadics9/ananas/fragments/EpisodeBottomSheetFragment.kt b/app/phone/src/main/java/com/nomadics9/ananas/fragments/EpisodeBottomSheetFragment.kt index f6ae4229..7fdd9acf 100644 --- a/app/phone/src/main/java/com/nomadics9/ananas/fragments/EpisodeBottomSheetFragment.kt +++ b/app/phone/src/main/java/com/nomadics9/ananas/fragments/EpisodeBottomSheetFragment.kt @@ -157,70 +157,76 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() { } binding.itemActions.downloadButton.setOnClickListener { - if (viewModel.item.isDownloaded()) { - viewModel.deleteEpisode() - binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) - } else if (viewModel.item.isDownloading()) { - createCancelDialog() - } else { - binding.itemActions.downloadButton.setIconResource(AndroidR.color.transparent) - binding.itemActions.progressDownload.isIndeterminate = true - binding.itemActions.progressDownload.isVisible = true - if (requireContext().getExternalFilesDirs(null).filterNotNull().size > 1) { - val storageDialog = getStorageSelectionDialog( - requireContext(), - onItemSelected = { storageIndex -> - if (viewModel.item.sources.size > 1) { - val dialog = getVideoVersionDialog( - requireContext(), - viewModel.item, - onItemSelected = { sourceIndex -> - createDownloadPreparingDialog() - viewModel.download(sourceIndex, storageIndex) - }, - onCancel = { - binding.itemActions.progressDownload.isVisible = false - binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) - }, - ) - dialog.show() - return@getStorageSelectionDialog - } - createDownloadPreparingDialog() - viewModel.download(storageIndex = storageIndex) - }, - onCancel = { - binding.itemActions.progressDownload.isVisible = false - binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) - }, - ) - storageDialog.show() - return@setOnClickListener - } - if (viewModel.item.sources.size > 1) { - val dialog = getVideoVersionDialog( - requireContext(), - viewModel.item, - onItemSelected = { sourceIndex -> - createDownloadPreparingDialog() - viewModel.download(sourceIndex) - }, - onCancel = { - binding.itemActions.progressDownload.isVisible = false - binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) - }, - ) - dialog.show() - return@setOnClickListener - } - createDownloadPreparingDialog() - viewModel.download() - } + handleDownload() } return binding.root } + private fun handleDownload() { + if (viewModel.item.isDownloaded()) { + viewModel.deleteEpisode() + binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) + } else if (viewModel.item.isDownloading()) { + createCancelDialog() + }else if (!appPreferences.downloadQualityDefault) { + createPickQualityDialog() + } else { + binding.itemActions.downloadButton.setIconResource(AndroidR.color.transparent) + binding.itemActions.progressDownload.isIndeterminate = true + binding.itemActions.progressDownload.isVisible = true + if (requireContext().getExternalFilesDirs(null).filterNotNull().size > 1) { + val storageDialog = getStorageSelectionDialog( + requireContext(), + onItemSelected = { storageIndex -> + if (viewModel.item.sources.size > 1) { + val dialog = getVideoVersionDialog( + requireContext(), + viewModel.item, + onItemSelected = { sourceIndex -> + createDownloadPreparingDialog() + viewModel.download(sourceIndex, storageIndex) + }, + onCancel = { + binding.itemActions.progressDownload.isVisible = false + binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) + }, + ) + dialog.show() + return@getStorageSelectionDialog + } + createDownloadPreparingDialog() + viewModel.download(storageIndex = storageIndex) + }, + onCancel = { + binding.itemActions.progressDownload.isVisible = false + binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) + }, + ) + storageDialog.show() + return + } + if (viewModel.item.sources.size > 1) { + val dialog = getVideoVersionDialog( + requireContext(), + viewModel.item, + onItemSelected = { sourceIndex -> + createDownloadPreparingDialog() + viewModel.download(sourceIndex) + }, + onCancel = { + binding.itemActions.progressDownload.isVisible = false + binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) + }, + ) + dialog.show() + return + } + createDownloadPreparingDialog() + viewModel.download() + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { dialog?.let { val sheet = it as BottomSheetDialog @@ -402,6 +408,31 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() { dialog.show() } + private fun createPickQualityDialog() { + val qualityEntries = resources.getStringArray(com.nomadics9.ananas.core.R.array.quality_entries) + val qualityValues = resources.getStringArray(com.nomadics9.ananas.core.R.array.quality_values) + val quality = appPreferences.downloadQuality + val currentQualityIndex = qualityValues.indexOf(quality) + var selectedQuality = quality + + + val builder = MaterialAlertDialogBuilder(requireContext()) + builder.setTitle("Download Quality") + builder.setSingleChoiceItems(qualityEntries, currentQualityIndex) { _, which -> + selectedQuality = qualityValues[which] + } + builder.setPositiveButton("Download") { dialog, _ -> + appPreferences.downloadQuality = selectedQuality + dialog.dismiss() + handleDownload() + } + builder.setNegativeButton("Cancel") { dialog, _ -> + dialog.dismiss() + } + val dialog = builder.create() + dialog.show() + } + private fun navigateToPlayerActivity( playerItems: Array, ) { diff --git a/app/phone/src/main/java/com/nomadics9/ananas/fragments/MovieFragment.kt b/app/phone/src/main/java/com/nomadics9/ananas/fragments/MovieFragment.kt index 4eeca9ea..d0bf32fe 100644 --- a/app/phone/src/main/java/com/nomadics9/ananas/fragments/MovieFragment.kt +++ b/app/phone/src/main/java/com/nomadics9/ananas/fragments/MovieFragment.kt @@ -192,65 +192,7 @@ class MovieFragment : Fragment() { } binding.itemActions.downloadButton.setOnClickListener { - if (viewModel.item.isDownloaded()) { - viewModel.deleteItem() - binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) - } else if (viewModel.item.isDownloading()) { - createCancelDialog() - } else { - binding.itemActions.downloadButton.setIconResource(android.R.color.transparent) - binding.itemActions.progressDownload.isIndeterminate = true - binding.itemActions.progressDownload.isVisible = true - if (requireContext().getExternalFilesDirs(null).filterNotNull().size > 1) { - val storageDialog = getStorageSelectionDialog( - requireContext(), - onItemSelected = { storageIndex -> - if (viewModel.item.sources.size > 1) { - val dialog = getVideoVersionDialog( - requireContext(), - viewModel.item, - onItemSelected = { sourceIndex -> - createDownloadPreparingDialog() - viewModel.download(sourceIndex, storageIndex) - }, - onCancel = { - binding.itemActions.progressDownload.isVisible = false - binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) - }, - ) - dialog.show() - return@getStorageSelectionDialog - } - createDownloadPreparingDialog() - viewModel.download(storageIndex = storageIndex) - }, - onCancel = { - binding.itemActions.progressDownload.isVisible = false - binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) - }, - ) - storageDialog.show() - return@setOnClickListener - } - if (viewModel.item.sources.size > 1) { - val dialog = getVideoVersionDialog( - requireContext(), - viewModel.item, - onItemSelected = { sourceIndex -> - createDownloadPreparingDialog() - viewModel.download(sourceIndex) - }, - onCancel = { - binding.itemActions.progressDownload.isVisible = false - binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) - }, - ) - dialog.show() - return@setOnClickListener - } - createDownloadPreparingDialog() - viewModel.download() - } + handleDownload() } binding.peopleRecyclerView.adapter = PersonListAdapter { person -> @@ -258,6 +200,70 @@ class MovieFragment : Fragment() { } } + private fun handleDownload() { + if (viewModel.item.isDownloaded()) { + viewModel.deleteItem() + binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) + } else if (viewModel.item.isDownloading()) { + createCancelDialog() + } else if (!appPreferences.downloadQualityDefault) { + createPickQualityDialog() + } else { + binding.itemActions.downloadButton.setIconResource(android.R.color.transparent) + binding.itemActions.progressDownload.isIndeterminate = true + binding.itemActions.progressDownload.isVisible = true + if (requireContext().getExternalFilesDirs(null).filterNotNull().size > 1) { + val storageDialog = getStorageSelectionDialog( + requireContext(), + onItemSelected = { storageIndex -> + if (viewModel.item.sources.size > 1) { + val dialog = getVideoVersionDialog( + requireContext(), + viewModel.item, + onItemSelected = { sourceIndex -> + createDownloadPreparingDialog() + viewModel.download(sourceIndex, storageIndex) + }, + onCancel = { + binding.itemActions.progressDownload.isVisible = false + binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) + }, + ) + dialog.show() + return@getStorageSelectionDialog + } + createDownloadPreparingDialog() + viewModel.download(storageIndex = storageIndex) + }, + onCancel = { + binding.itemActions.progressDownload.isVisible = false + binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) + }, + ) + storageDialog.show() + return + } + if (viewModel.item.sources.size > 1) { + val dialog = getVideoVersionDialog( + requireContext(), + viewModel.item, + onItemSelected = { sourceIndex -> + createDownloadPreparingDialog() + viewModel.download(sourceIndex) + }, + onCancel = { + binding.itemActions.progressDownload.isVisible = false + binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download) + }, + ) + dialog.show() + return + } + createDownloadPreparingDialog() + viewModel.download() + } + } + override fun onResume() { super.onResume() @@ -495,6 +501,31 @@ class MovieFragment : Fragment() { dialog.show() } + private fun createPickQualityDialog() { + val qualityEntries = resources.getStringArray(com.nomadics9.ananas.core.R.array.quality_entries) + val qualityValues = resources.getStringArray(com.nomadics9.ananas.core.R.array.quality_values) + val quality = appPreferences.downloadQuality + val currentQualityIndex = qualityValues.indexOf(quality) + var selectedQuality = quality + + + val builder = MaterialAlertDialogBuilder(requireContext()) + builder.setTitle("Download Quality") + builder.setSingleChoiceItems(qualityEntries, currentQualityIndex) { _, which -> + selectedQuality = qualityValues[which] + } + builder.setPositiveButton("Download") { dialog, _ -> + appPreferences.downloadQuality = selectedQuality + dialog.dismiss() + handleDownload() + } + builder.setNegativeButton("Cancel") { dialog, _ -> + dialog.dismiss() + } + val dialog = builder.create() + dialog.show() + } + private fun navigateToPlayerActivity( playerItems: Array, ) { diff --git a/app/phone/src/main/java/com/nomadics9/ananas/fragments/SeasonFragment.kt b/app/phone/src/main/java/com/nomadics9/ananas/fragments/SeasonFragment.kt index b53e6127..d8caf6a4 100644 --- a/app/phone/src/main/java/com/nomadics9/ananas/fragments/SeasonFragment.kt +++ b/app/phone/src/main/java/com/nomadics9/ananas/fragments/SeasonFragment.kt @@ -31,7 +31,9 @@ import timber.log.Timber import androidx.appcompat.app.AlertDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.nomadics9.ananas.AppPreferences import com.nomadics9.ananas.models.UiText +import javax.inject.Inject @AndroidEntryPoint @@ -44,6 +46,9 @@ class SeasonFragment : Fragment() { private lateinit var errorDialog: ErrorDialogFragment private lateinit var downloadPreparingDialog: AlertDialog + @Inject + lateinit var appPreferences: AppPreferences + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -195,6 +200,15 @@ class SeasonFragment : Fragment() { } private fun createEpisodesToDownloadDialog(storageIndex: Int = 0) { + if (!appPreferences.downloadQualityDefault) + createPickQualityDialog { + showDownloadDialog(storageIndex) + } else { + showDownloadDialog(storageIndex) + } + } + + private fun showDownloadDialog(storageIndex: Int = 0) { val builder = MaterialAlertDialogBuilder(requireContext()) val dialog = builder .setTitle(com.nomadics9.ananas.core.R.string.download_season_dialog_title) @@ -211,6 +225,33 @@ class SeasonFragment : Fragment() { dialog.show() } + private fun createPickQualityDialog(onQualitySelected: () -> Unit) { + val qualityEntries = resources.getStringArray(com.nomadics9.ananas.core.R.array.quality_entries) + val qualityValues = resources.getStringArray(com.nomadics9.ananas.core.R.array.quality_values) + val quality = appPreferences.downloadQuality + val currentQualityIndex = qualityValues.indexOf(quality) + + var selectedQuality = quality + + val builder = MaterialAlertDialogBuilder(requireContext()) + builder.setTitle("Download Quality") + builder.setSingleChoiceItems(qualityEntries, currentQualityIndex) { _, which -> + selectedQuality = qualityValues[which] + } + builder.setPositiveButton("Download") { dialog, _ -> + appPreferences.downloadQuality = selectedQuality + dialog.dismiss() + onQualitySelected() + } + builder.setNegativeButton("Cancel") { dialog, _ -> + dialog.dismiss() + } + + val dialog = builder.create() + dialog.show() + } + + diff --git a/app/phone/src/main/res/layout/dialog_quality_selection.xml b/app/phone/src/main/res/layout/dialog_quality_selection.xml deleted file mode 100644 index 15b971ff..00000000 --- a/app/phone/src/main/res/layout/dialog_quality_selection.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - -