[Download dialog] Cleanup and sort by quality

This commit is contained in:
Bnyro 2023-02-12 16:35:55 +01:00
parent 59a1378531
commit 22af1f9362
2 changed files with 74 additions and 64 deletions

View File

@ -0,0 +1,10 @@
package com.github.libretube.extensions
/**
* Read a string as long as the char is a digit and return the number value as int
*/
fun String?.getWhileDigit(): Int? {
return orEmpty().takeWhile { char ->
char.isDigit()
}.toIntOrNull()
}

View File

@ -12,10 +12,14 @@ import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.obj.PipedStream
import com.github.libretube.api.obj.Streams import com.github.libretube.api.obj.Streams
import com.github.libretube.api.obj.Subtitle
import com.github.libretube.databinding.DialogDownloadBinding import com.github.libretube.databinding.DialogDownloadBinding
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.getWhileDigit
import com.github.libretube.helpers.DownloadHelper import com.github.libretube.helpers.DownloadHelper
import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.util.TextUtils import com.github.libretube.util.TextUtils
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.IOException import java.io.IOException
@ -76,77 +80,55 @@ class DownloadDialog(
private fun initDownloadOptions(streams: Streams) { private fun initDownloadOptions(streams: Streams) {
binding.fileName.setText(streams.title) binding.fileName.setText(streams.title)
val vidName = arrayListOf<String>() val videoStreams = streams.videoStreams.filter {
!it.url.isNullOrEmpty()
// add empty selection }.sortedByDescending {
vidName.add(getString(R.string.no_video)) it.quality.getWhileDigit()
// add all available video streams
for (vid in streams.videoStreams) {
if (vid.url != null) {
val name = vid.quality + " " + vid.format
vidName.add(name)
}
} }
val audioName = arrayListOf<String>() val audioStreams = streams.audioStreams.filter {
!it.url.isNullOrEmpty()
// add empty selection }.sortedByDescending {
audioName.add(getString(R.string.no_audio)) it.quality.getWhileDigit()
// add all available audio streams
for (audio in streams.audioStreams) {
if (audio.url != null) {
val name = audio.quality + " " + audio.format
audioName.add(name)
}
} }
val subtitleName = arrayListOf<String>() val subtitles = streams.subtitles.filter { !it.url.isNullOrEmpty() }.sortedBy { it.name }
// add empty selection if (subtitles.isEmpty()) binding.subtitleSpinner.visibility = View.GONE
subtitleName.add(getString(R.string.no_subtitle))
// add all available subtitles
for (subtitle in streams.subtitles) {
if (subtitle.url != null) {
subtitleName.add(subtitle.name.toString())
}
}
if (subtitleName.size == 1) binding.subtitleSpinner.visibility = View.GONE
// initialize the video sources // initialize the video sources
val videoArrayAdapter = ArrayAdapter( val videoArrayAdapter = ArrayAdapter(
requireContext(), requireContext(),
android.R.layout.simple_spinner_item, android.R.layout.simple_spinner_item,
vidName videoStreams.map { "${it.quality} ${it.format}" }.toMutableList().also {
it.add(0, getString(R.string.no_video))
}
) )
videoArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
binding.videoSpinner.adapter = videoArrayAdapter
if (binding.videoSpinner.size >= 1) binding.videoSpinner.setSelection(1)
if (binding.audioSpinner.size >= 1) binding.audioSpinner.setSelection(1)
if (binding.subtitleSpinner.size >= 1) binding.subtitleSpinner.setSelection(1)
// initialize the audio sources
val audioArrayAdapter = ArrayAdapter( val audioArrayAdapter = ArrayAdapter(
requireContext(), requireContext(),
android.R.layout.simple_spinner_item, android.R.layout.simple_spinner_item,
audioName audioStreams.map { "${it.quality} ${it.format}" }.toMutableList().also {
it.add(0, getString(R.string.no_audio))
}
) )
audioArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
binding.audioSpinner.adapter = audioArrayAdapter
if (binding.audioSpinner.size >= 1) binding.audioSpinner.setSelection(1)
// initialize the subtitle sources
val subtitleArrayAdapter = ArrayAdapter( val subtitleArrayAdapter = ArrayAdapter(
requireContext(), requireContext(),
android.R.layout.simple_spinner_item, android.R.layout.simple_spinner_item,
subtitleName subtitles.map { it.name }.toMutableList().also {
it.add(0, getString(R.string.no_subtitle))
}
) )
subtitleArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
listOf(videoArrayAdapter, audioArrayAdapter, subtitleArrayAdapter).forEach {
it.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
}
binding.videoSpinner.adapter = videoArrayAdapter
binding.audioSpinner.adapter = audioArrayAdapter
binding.subtitleSpinner.adapter = subtitleArrayAdapter binding.subtitleSpinner.adapter = subtitleArrayAdapter
if (binding.subtitleSpinner.size >= 1) binding.subtitleSpinner.setSelection(1)
restorePreviousSelections(videoStreams, audioStreams, subtitles)
binding.download.setOnClickListener { binding.download.setOnClickListener {
if (binding.fileName.text.toString().isEmpty()) { if (binding.fileName.text.toString().isEmpty()) {
@ -158,23 +140,16 @@ class DownloadDialog(
val audioPosition = binding.audioSpinner.selectedItemPosition - 1 val audioPosition = binding.audioSpinner.selectedItemPosition - 1
val subtitlePosition = binding.subtitleSpinner.selectedItemPosition - 1 val subtitlePosition = binding.subtitleSpinner.selectedItemPosition - 1
if (videoPosition == -1 && audioPosition == -1 && subtitlePosition == -1) { if (listOf(videoPosition, audioPosition, subtitlePosition).all { it == -1 }) {
Toast.makeText(context, R.string.nothing_selected, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.nothing_selected, Toast.LENGTH_SHORT).show()
return@setOnClickListener return@setOnClickListener
} }
val videoStream = when (videoPosition) { val videoStream = videoStreams.getOrNull(videoPosition)
-1 -> null val audioStream = audioStreams.getOrNull(audioPosition)
else -> streams.videoStreams[videoPosition] val subtitle = subtitles.getOrNull(subtitlePosition)
}
val audioStream = when (audioPosition) { saveSelections(videoStream, audioStream, subtitle)
-1 -> null
else -> streams.audioStreams[audioPosition]
}
val subtitle = when (subtitlePosition) {
-1 -> null
else -> streams.subtitles[subtitlePosition]
}
DownloadHelper.startDownloadService( DownloadHelper.startDownloadService(
context = requireContext(), context = requireContext(),
@ -191,8 +166,33 @@ class DownloadDialog(
} }
} }
private fun saveSelections(
videoStream: PipedStream?,
audioStream: PipedStream?,
subtitle: Subtitle?
) {
PreferenceHelper.putString(SUBTITLE_LANGUAGE, subtitle?.code.orEmpty())
}
private fun restorePreviousSelections(
videoStreams: List<PipedStream>,
audioStream: List<PipedStream>,
subtitles: List<Subtitle>
) {
if (binding.videoSpinner.size >= 1) binding.videoSpinner.setSelection(1)
if (binding.audioSpinner.size >= 1) binding.audioSpinner.setSelection(1)
val lastSubtitleSelection = PreferenceHelper.getString(SUBTITLE_LANGUAGE, "")
subtitles.indexOfFirst { it.code == lastSubtitleSelection }.takeIf { it > 0 }?.let {
binding.subtitleSpinner.setSelection(it)
}
}
companion object { companion object {
const val AUDIO_DOWNLOAD_PREF_KEY = "audio_download_selection" private const val VIDEO_DOWNLOAD_QUALITY = "video_download_quality"
const val VIDEO_DOWNLOAD_PREF_KEY = "video_download_selection" private const val VIDEO_DOWNLOAD_FORMAT = "video_download_format"
private const val AUDIO_DOWNLOAD_QUALITY = "audio_download_quality"
private const val AUDIO_DOWNLOAD_FORMAT = "audio_download_format"
private const val SUBTITLE_LANGUAGE = "subtitle_download_language"
} }
} }