feat: support download of private playlists via external downloader

This commit is contained in:
Bnyro 2024-08-26 14:54:36 +02:00
parent 59c3d91e34
commit 204a48294b

View File

@ -7,15 +7,23 @@ import androidx.core.content.ContextCompat
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import com.github.libretube.R
import com.github.libretube.api.PlaylistsHelper
import com.github.libretube.constants.IntentData import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.db.obj.DownloadItem import com.github.libretube.db.obj.DownloadItem
import com.github.libretube.enums.PlaylistType import com.github.libretube.enums.PlaylistType
import com.github.libretube.extensions.toID
import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.parcelable.DownloadData import com.github.libretube.parcelable.DownloadData
import com.github.libretube.services.DownloadService import com.github.libretube.services.DownloadService
import com.github.libretube.ui.dialogs.DownloadDialog import com.github.libretube.ui.dialogs.DownloadDialog
import com.github.libretube.ui.dialogs.DownloadPlaylistDialog import com.github.libretube.ui.dialogs.DownloadPlaylistDialog
import com.github.libretube.ui.dialogs.ShareDialog import com.github.libretube.ui.dialogs.ShareDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.nio.file.Path import java.nio.file.Path
import kotlin.io.path.createDirectories import kotlin.io.path.createDirectories
import kotlin.io.path.div import kotlin.io.path.div
@ -28,7 +36,7 @@ object DownloadHelper {
const val DOWNLOAD_CHUNK_SIZE = 8L * 1024 const val DOWNLOAD_CHUNK_SIZE = 8L * 1024
const val DEFAULT_TIMEOUT = 15 * 1000 const val DEFAULT_TIMEOUT = 15 * 1000
const val DEFAULT_RETRY = 3 const val DEFAULT_RETRY = 3
private const val videoMimeType = "video/*" private const val VIDEO_MIMETYPE = "video/*"
fun getDownloadDir(context: Context, path: String): Path { fun getDownloadDir(context: Context, path: String): Path {
val storageDir = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { val storageDir = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
@ -72,7 +80,10 @@ object DownloadHelper {
} else { } else {
val intent = Intent(Intent.ACTION_VIEW) val intent = Intent(Intent.ACTION_VIEW)
.setPackage(externalProviderPackageName) .setPackage(externalProviderPackageName)
.setDataAndType("${ShareDialog.YOUTUBE_FRONTEND_URL}/watch?v=$videoId".toUri(), videoMimeType) .setDataAndType(
"${ShareDialog.YOUTUBE_FRONTEND_URL}/watch?v=$videoId".toUri(),
VIDEO_MIMETYPE
)
runCatching { context.startActivity(intent) } runCatching { context.startActivity(intent) }
} }
@ -97,12 +108,35 @@ object DownloadHelper {
) )
} }
downloadPlaylistDialog.show(fragmentManager, null) downloadPlaylistDialog.show(fragmentManager, null)
} else { } else if (playlistType == PlaylistType.PUBLIC) {
val intent = Intent(Intent.ACTION_VIEW) val intent = Intent(Intent.ACTION_VIEW)
.setPackage(externalProviderPackageName) .setPackage(externalProviderPackageName)
.setDataAndType("${ShareDialog.YOUTUBE_FRONTEND_URL}/playlist?list=$playlistId".toUri(), videoMimeType) .setDataAndType(
"${ShareDialog.YOUTUBE_FRONTEND_URL}/playlist?list=$playlistId".toUri(),
VIDEO_MIMETYPE
)
runCatching { context.startActivity(intent) }
} else {
CoroutineScope(Dispatchers.IO).launch {
val playlistVideoIds = try {
PlaylistsHelper.getPlaylist(playlistId)
} catch (e: Exception) {
context.toastFromMainDispatcher(R.string.unknown_error)
return@launch
}.relatedStreams.mapNotNull { it.url?.toID() }.joinToString(",")
val intent = Intent(Intent.ACTION_VIEW)
.setPackage(externalProviderPackageName)
.setDataAndType(
"${ShareDialog.YOUTUBE_FRONTEND_URL}/watch_videos?video_ids=${playlistVideoIds}".toUri(),
VIDEO_MIMETYPE
)
withContext(Dispatchers.Main) {
runCatching { context.startActivity(intent) } runCatching { context.startActivity(intent) }
} }
} }
}
}
} }