diff --git a/app/src/main/java/com/github/libretube/dialogs/DownloadDialog.kt b/app/src/main/java/com/github/libretube/dialogs/DownloadDialog.kt index e7042b789..a056fe88c 100644 --- a/app/src/main/java/com/github/libretube/dialogs/DownloadDialog.kt +++ b/app/src/main/java/com/github/libretube/dialogs/DownloadDialog.kt @@ -9,15 +9,20 @@ import android.os.Bundle import android.os.Environment import android.util.Log import android.widget.ArrayAdapter +import android.widget.Toast import androidx.core.app.ActivityCompat import androidx.fragment.app.DialogFragment +import androidx.lifecycle.lifecycleScope import com.github.libretube.R import com.github.libretube.activities.MainActivity import com.github.libretube.databinding.DialogDownloadBinding import com.github.libretube.obj.Streams import com.github.libretube.services.DownloadService +import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.ThemeHelper import com.google.android.material.dialog.MaterialAlertDialogBuilder +import retrofit2.HttpException +import java.io.IOException class DownloadDialog : DialogFragment() { private val TAG = "DownloadDialog" @@ -29,13 +34,14 @@ class DownloadDialog : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { - streams = arguments?.getParcelable("streams")!! videoId = arguments?.getString("video_id")!! val mainActivity = activity as MainActivity val builder = MaterialAlertDialogBuilder(it) binding = DialogDownloadBinding.inflate(layoutInflater) + fetchStreams() + // request storage permissions if not granted yet if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { Log.d("myz", "" + Build.VERSION.SDK_INT) @@ -70,69 +76,89 @@ class DownloadDialog : DialogFragment() { } } - var vidName = arrayListOf() - var vidUrl = arrayListOf() - - // add empty selection - vidName.add(getString(R.string.no_video)) - vidUrl.add("") - - // add all available video streams - for (vid in streams.videoStreams!!) { - val name = vid.quality + " " + vid.format - vidName.add(name) - vidUrl.add(vid.url!!) - } - - var audioName = arrayListOf() - var audioUrl = arrayListOf() - - // add empty selection - audioName.add(getString(R.string.no_audio)) - audioUrl.add("") - - // add all available audio streams - for (audio in streams.audioStreams!!) { - val name = audio.quality + " " + audio.format - audioName.add(name) - audioUrl.add(audio.url!!) - } - - val videoArrayAdapter = ArrayAdapter( - requireContext(), - android.R.layout.simple_spinner_item, - vidName - ) - videoArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - binding.videoSpinner.adapter = videoArrayAdapter - binding.videoSpinner.setSelection(1) - - val audioArrayAdapter = ArrayAdapter( - requireContext(), - android.R.layout.simple_spinner_item, - audioName - ) - audioArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - binding.audioSpinner.adapter = audioArrayAdapter - binding.audioSpinner.setSelection(1) - - binding.download.setOnClickListener { - val selectedAudioUrl = audioUrl[binding.audioSpinner.selectedItemPosition] - val selectedVideoUrl = vidUrl[binding.videoSpinner.selectedItemPosition] - - val intent = Intent(context, DownloadService::class.java) - intent.putExtra("videoId", videoId) - intent.putExtra("videoUrl", selectedVideoUrl) - intent.putExtra("audioUrl", selectedAudioUrl) - intent.putExtra("duration", duration) - context?.startService(intent) - dismiss() - } - binding.title.text = ThemeHelper.getStyledAppName(requireContext()) builder.setView(binding.root) builder.create() } ?: throw IllegalStateException("Activity cannot be null") } + + private fun fetchStreams() { + lifecycleScope.launchWhenCreated { + val response = try { + RetrofitInstance.api.getStreams(videoId!!) + } catch (e: IOException) { + println(e) + Log.e(TAG, "IOException, you might not have internet connection") + Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT).show() + return@launchWhenCreated + } catch (e: HttpException) { + Log.e(TAG, "HttpException, unexpected response") + Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show() + return@launchWhenCreated + } + initDownloadOptions(response) + } + } + + private fun initDownloadOptions(streams: Streams) { + var vidName = arrayListOf() + var vidUrl = arrayListOf() + + // add empty selection + vidName.add(getString(R.string.no_video)) + vidUrl.add("") + + // add all available video streams + for (vid in streams.videoStreams!!) { + val name = vid.quality + " " + vid.format + vidName.add(name) + vidUrl.add(vid.url!!) + } + + var audioName = arrayListOf() + var audioUrl = arrayListOf() + + // add empty selection + audioName.add(getString(R.string.no_audio)) + audioUrl.add("") + + // add all available audio streams + for (audio in streams.audioStreams!!) { + val name = audio.quality + " " + audio.format + audioName.add(name) + audioUrl.add(audio.url!!) + } + + val videoArrayAdapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_spinner_item, + vidName + ) + videoArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + binding.videoSpinner.adapter = videoArrayAdapter + binding.videoSpinner.setSelection(1) + + val audioArrayAdapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_spinner_item, + audioName + ) + audioArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + binding.audioSpinner.adapter = audioArrayAdapter + binding.audioSpinner.setSelection(1) + + binding.download.setOnClickListener { + val selectedAudioUrl = audioUrl[binding.audioSpinner.selectedItemPosition] + val selectedVideoUrl = vidUrl[binding.videoSpinner.selectedItemPosition] + + val intent = Intent(context, DownloadService::class.java) + intent.putExtra("videoId", videoId) + intent.putExtra("videoUrl", selectedVideoUrl) + intent.putExtra("audioUrl", selectedAudioUrl) + intent.putExtra("duration", duration) + context?.startService(intent) + dismiss() + } + } } diff --git a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt index 4d1f19f87..dccc5a21c 100644 --- a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt @@ -774,9 +774,8 @@ class PlayerFragment : Fragment() { val newFragment = DownloadDialog() val bundle = Bundle() bundle.putString("video_id", videoId) - bundle.putParcelable("streams", response) newFragment.arguments = bundle - newFragment.show(childFragmentManager, "Download") + newFragment.show(childFragmentManager, "DownloadDialog") } else { Toast.makeText(context, R.string.dlisinprogress, Toast.LENGTH_SHORT) .show() diff --git a/app/src/main/java/com/github/libretube/obj/Streams.kt b/app/src/main/java/com/github/libretube/obj/Streams.kt index 144a7e758..c55e34fd6 100644 --- a/app/src/main/java/com/github/libretube/obj/Streams.kt +++ b/app/src/main/java/com/github/libretube/obj/Streams.kt @@ -1,7 +1,5 @@ package com.github.libretube.obj -import android.os.Parcel -import android.os.Parcelable import com.fasterxml.jackson.annotation.JsonIgnoreProperties @JsonIgnoreProperties(ignoreUnknown = true) @@ -28,68 +26,4 @@ data class Streams( val livestream: Boolean?, val proxyUrl: String?, val chapters: List? -) : Parcelable { - constructor(parcel: Parcel) : this( - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readValue(Boolean::class.java.classLoader) as? Boolean, - parcel.readValue(Int::class.java.classLoader) as? Int, - parcel.readValue(Long::class.java.classLoader) as? Long, - parcel.readValue(Long::class.java.classLoader) as? Long, - parcel.readValue(Int::class.java.classLoader) as? Long, - TODO("audioStreams"), - TODO("videoStreams"), - TODO("relatedStreams"), - TODO("subtitles"), - parcel.readValue(Boolean::class.java.classLoader) as? Boolean, - parcel.readString(), - TODO("chapters") - ) - - constructor() : this( - "", "", "", "", "", "", "", "", "", "", null, -1, -1, -1, -1, emptyList(), emptyList(), - emptyList(), emptyList(), null, "", emptyList() - ) - - override fun writeToParcel(parcel: Parcel, flags: Int) { - parcel.writeString(title) - parcel.writeString(description) - parcel.writeString(uploadDate) - parcel.writeString(uploader) - parcel.writeString(uploaderUrl) - parcel.writeString(uploaderAvatar) - parcel.writeString(thumbnailUrl) - parcel.writeString(hls) - parcel.writeString(dash) - parcel.writeString(lbryId) - parcel.writeValue(uploaderVerified) - parcel.writeValue(duration) - parcel.writeValue(views) - parcel.writeValue(likes) - parcel.writeValue(dislikes) - parcel.writeValue(livestream) - parcel.writeString(proxyUrl) - } - - override fun describeContents(): Int { - return 0 - } - - companion object CREATOR : Parcelable.Creator { - override fun createFromParcel(parcel: Parcel): Streams { - return Streams(parcel) - } - - override fun newArray(size: Int): Array { - return arrayOfNulls(size) - } - } -} +)