From a6e7576f34e6cb4cfff7ecbbb67695315f1ad53f Mon Sep 17 00:00:00 2001 From: Bnyro Date: Fri, 23 Aug 2024 13:33:29 +0200 Subject: [PATCH] refactor: reduce amount of api calls for adding video to playlist --- .../github/libretube/api/StreamsExtractor.kt | 8 ++-- .../github/libretube/constants/IntentData.kt | 1 + .../github/libretube/helpers/ProxyHelper.kt | 21 ++++++++-- .../ui/activities/AddToPlaylistActivity.kt | 31 ++++++++++++-- .../ui/dialogs/AddToPlaylistDialog.kt | 19 +++------ .../libretube/ui/fragments/PlayerFragment.kt | 42 +++++++++++++------ .../ui/sheets/VideoOptionsBottomSheet.kt | 12 ++++-- 7 files changed, 93 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/com/github/libretube/api/StreamsExtractor.kt b/app/src/main/java/com/github/libretube/api/StreamsExtractor.kt index 97c7897e0..047ede4ac 100644 --- a/app/src/main/java/com/github/libretube/api/StreamsExtractor.kt +++ b/app/src/main/java/com/github/libretube/api/StreamsExtractor.kt @@ -33,7 +33,7 @@ object StreamsExtractor { description = resp.description.toString(), uploader = resp.uploaderName, uploaderAvatar = resp.uploaderAvatars.maxBy { it.height }.url, - uploaderUrl = resp.uploaderUrl, + uploaderUrl = resp.uploaderUrl.replace("https://www.youtube.com", ""), uploaderVerified = resp.isUploaderVerified, uploaderSubscriberCount = resp.uploaderSubscriberCount, category = resp.category, @@ -58,12 +58,12 @@ object StreamsExtractor { thumbnailUrl = resp.thumbnails.maxBy { it.height }.url, relatedStreams = resp.relatedItems.map { it as StreamInfoItem }.map { StreamItem( - it.url, - it.infoType.name, + it.url.replace("https://www.youtube.com", ""), + StreamItem.TYPE_STREAM, it.name, it.thumbnails.maxBy { image -> image.height }.url, it.uploaderName, - it.uploaderUrl, + it.uploaderUrl.replace("https://www.youtube.com", ""), it.uploaderAvatars.maxBy { image -> image.height }.url, it.textualUploadDate, it.duration, 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 a156375ce..3ca4ee38c 100644 --- a/app/src/main/java/com/github/libretube/constants/IntentData.kt +++ b/app/src/main/java/com/github/libretube/constants/IntentData.kt @@ -47,4 +47,5 @@ object IntentData { const val tabData = "tabData" const val videoList = "videoList" const val nextPage = "nextPage" + const val videoInfo = "videoInfo" } diff --git a/app/src/main/java/com/github/libretube/helpers/ProxyHelper.kt b/app/src/main/java/com/github/libretube/helpers/ProxyHelper.kt index 293eb185d..0c7cb7f9b 100644 --- a/app/src/main/java/com/github/libretube/helpers/ProxyHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/ProxyHelper.kt @@ -19,13 +19,26 @@ object ProxyHelper { } fun rewriteUrl(url: String?): String? { + if (url == null) return null + val proxyUrl = PreferenceHelper.getString(PreferenceKeys.IMAGE_PROXY_URL, "") .toHttpUrlOrNull() ?: return url - return url?.toHttpUrlOrNull()?.newBuilder() - ?.host(proxyUrl.host) - ?.port(proxyUrl.port) - ?.toString() + val parsedUrl = url.toHttpUrlOrNull() ?: return url + if (parsedUrl.queryParameter("host").isNullOrEmpty()) { + return parsedUrl.newBuilder() + .host(proxyUrl.host) + .port(proxyUrl.port) + .setQueryParameter("host", parsedUrl.host) + .build() + .toString() + } + + return parsedUrl.newBuilder() + .host(proxyUrl.host) + .port(proxyUrl.port) + .build() + .toString() } /** diff --git a/app/src/main/java/com/github/libretube/ui/activities/AddToPlaylistActivity.kt b/app/src/main/java/com/github/libretube/ui/activities/AddToPlaylistActivity.kt index 58dd3ae15..b27ec8c8f 100644 --- a/app/src/main/java/com/github/libretube/ui/activities/AddToPlaylistActivity.kt +++ b/app/src/main/java/com/github/libretube/ui/activities/AddToPlaylistActivity.kt @@ -4,12 +4,21 @@ import android.content.Intent import android.os.Bundle import androidx.core.net.toUri import androidx.core.os.bundleOf +import androidx.lifecycle.lifecycleScope +import com.github.libretube.R +import com.github.libretube.api.StreamsExtractor +import com.github.libretube.api.obj.StreamItem import com.github.libretube.constants.IntentData +import com.github.libretube.extensions.toastFromMainDispatcher import com.github.libretube.helpers.IntentHelper +import com.github.libretube.helpers.PreferenceHelper import com.github.libretube.ui.base.BaseActivity import com.github.libretube.ui.dialogs.AddToPlaylistDialog +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext -class AddToPlaylistActivity: BaseActivity() { +class AddToPlaylistActivity : BaseActivity() { override val isDialogActivity: Boolean = true override fun onCreate(savedInstanceState: Bundle?) { @@ -29,8 +38,22 @@ class AddToPlaylistActivity: BaseActivity() { this ) { _, _ -> finish() } - AddToPlaylistDialog().apply { - arguments = bundleOf(IntentData.videoId to videoId) - }.show(supportFragmentManager, null) + lifecycleScope.launch(Dispatchers.IO) { + val videoInfo = if (PreferenceHelper.getToken().isEmpty()) { + try { + StreamsExtractor.extractStreams(videoId).toStreamItem(videoId) + } catch (e: Exception) { + toastFromMainDispatcher(R.string.unknown_error) + } + } else { + StreamItem(videoId) + } + + withContext(Dispatchers.Main) { + AddToPlaylistDialog().apply { + arguments = bundleOf(IntentData.videoInfo to videoInfo) + }.show(supportFragmentManager, null) + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/github/libretube/ui/dialogs/AddToPlaylistDialog.kt b/app/src/main/java/com/github/libretube/ui/dialogs/AddToPlaylistDialog.kt index d9f5840c3..290f45b47 100644 --- a/app/src/main/java/com/github/libretube/ui/dialogs/AddToPlaylistDialog.kt +++ b/app/src/main/java/com/github/libretube/ui/dialogs/AddToPlaylistDialog.kt @@ -15,12 +15,12 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.github.libretube.R import com.github.libretube.api.PlaylistsHelper -import com.github.libretube.api.RetrofitInstance -import com.github.libretube.api.StreamsExtractor import com.github.libretube.api.obj.Playlists +import com.github.libretube.api.obj.StreamItem import com.github.libretube.constants.IntentData import com.github.libretube.databinding.DialogAddToPlaylistBinding import com.github.libretube.extensions.TAG +import com.github.libretube.extensions.parcelable import com.github.libretube.extensions.toastFromMainDispatcher import com.github.libretube.ui.models.PlaylistViewModel import com.github.libretube.util.PlayingQueue @@ -32,14 +32,15 @@ import kotlinx.coroutines.launch * videoId: The id of the video to add. If non is provided, insert the whole playing queue */ class AddToPlaylistDialog : DialogFragment() { - private var videoId: String? = null + private var videoInfo: StreamItem? = null private val viewModel: PlaylistViewModel by activityViewModels() var playlists = emptyList() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - videoId = arguments?.getString(IntentData.videoId) + videoInfo = arguments?.parcelable(IntentData.videoInfo) + Log.e("video info", videoInfo.toString()) } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { @@ -110,15 +111,7 @@ class AddToPlaylistDialog : DialogFragment() { @SuppressLint("StringFormatInvalid") private suspend fun addToPlaylist(playlistId: String, playlistName: String) { val appContext = context?.applicationContext ?: return - val streams = when { - videoId != null -> listOfNotNull( - runCatching { - StreamsExtractor.extractStreams(videoId!!).toStreamItem(videoId!!) - }.getOrNull() - ) - - else -> PlayingQueue.getStreams() - } + val streams = videoInfo?.let { listOf(it) } ?: PlayingQueue.getStreams() val success = try { if (streams.isEmpty()) throw IllegalArgumentException() diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index dfa0fd26b..ff9c9145e 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -104,8 +104,8 @@ import com.github.libretube.ui.interfaces.OnlinePlayerOptions import com.github.libretube.ui.listeners.SeekbarPreviewListener import com.github.libretube.ui.models.ChaptersViewModel import com.github.libretube.ui.models.CommentsViewModel -import com.github.libretube.ui.models.PlayerViewModel import com.github.libretube.ui.models.CommonPlayerViewModel +import com.github.libretube.ui.models.PlayerViewModel import com.github.libretube.ui.sheets.BaseBottomSheet import com.github.libretube.ui.sheets.CommentsSheet import com.github.libretube.ui.sheets.StatsSheet @@ -282,7 +282,11 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { } if (events.contains(Player.EVENT_TRACKS_CHANGED)) { - PlayerHelper.setPreferredAudioQuality(requireContext(), viewModel.player, viewModel.trackSelector) + PlayerHelper.setPreferredAudioQuality( + requireContext(), + viewModel.player, + viewModel.trackSelector + ) } } @@ -628,9 +632,11 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { ) binding.relPlayerSave.setOnClickListener { - val newAddToPlaylistDialog = AddToPlaylistDialog() - newAddToPlaylistDialog.arguments = bundleOf(IntentData.videoId to videoId) - newAddToPlaylistDialog.show(childFragmentManager, AddToPlaylistDialog::class.java.name) + if (!::streams.isInitialized) return@setOnClickListener + + AddToPlaylistDialog().apply { + arguments = bundleOf(IntentData.videoInfo to streams.toStreamItem(videoId)) + }.show(childFragmentManager, AddToPlaylistDialog::class.java.name) } playerBinding.skipPrev.setOnClickListener { @@ -1074,7 +1080,13 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { playerGestureControlsViewBinding, chaptersViewModel ) - binding.player.initPlayerOptions(viewModel, commonPlayerViewModel, viewLifecycleOwner, viewModel.trackSelector, this) + binding.player.initPlayerOptions( + viewModel, + commonPlayerViewModel, + viewLifecycleOwner, + viewModel.trackSelector, + this + ) binding.descriptionLayout.setStreams(streams) @@ -1534,11 +1546,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { } } - private fun updateCurrentSubtitle(subtitle: Subtitle?) = viewModel.trackSelector.updateParameters { - val roleFlags = if (subtitle?.code != null) getSubtitleRoleFlags(subtitle) else 0 - setPreferredTextRoleFlags(roleFlags) - setPreferredTextLanguage(subtitle?.code) - } + private fun updateCurrentSubtitle(subtitle: Subtitle?) = + viewModel.trackSelector.updateParameters { + val roleFlags = if (subtitle?.code != null) getSubtitleRoleFlags(subtitle) else 0 + setPreferredTextRoleFlags(roleFlags) + setPreferredTextLanguage(subtitle?.code) + } fun onUserLeaveHint() { if (shouldStartPiP()) { @@ -1550,7 +1563,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { private val pipParams get() = PictureInPictureParamsCompat.Builder() - .setActions(PlayerHelper.getPiPModeActions(requireActivity(), viewModel.player.isPlaying)) + .setActions( + PlayerHelper.getPiPModeActions( + requireActivity(), + viewModel.player.isPlaying + ) + ) .setAutoEnterEnabled(PlayerHelper.pipEnabled && viewModel.player.isPlaying) .apply { if (viewModel.player.isPlaying) { diff --git a/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt b/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt index ffbf7eec5..896d0bbfb 100644 --- a/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt +++ b/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt @@ -62,16 +62,20 @@ class VideoOptionsBottomSheet : BaseBottomSheet() { } // Add Video to Playlist Dialog R.string.addToPlaylist -> { - val newAddToPlaylistDialog = AddToPlaylistDialog() - newAddToPlaylistDialog.arguments = bundleOf(IntentData.videoId to videoId) - newAddToPlaylistDialog.show( + AddToPlaylistDialog().apply { + arguments = bundleOf(IntentData.videoInfo to streamItem) + }.show( parentFragmentManager, AddToPlaylistDialog::class.java.name ) } R.string.download -> { - DownloadHelper.startDownloadDialog(requireContext(), parentFragmentManager, videoId) + DownloadHelper.startDownloadDialog( + requireContext(), + parentFragmentManager, + videoId + ) } R.string.share -> {