From aad50e7b503b50ca174aab81803bdbb268ae64d9 Mon Sep 17 00:00:00 2001 From: Kelvin K Date: Thu, 13 Jun 2024 13:45:31 +0200 Subject: [PATCH] Improved playlist import support --- .../main/ImportPlaylistsFragment.kt | 41 +++++++++++++++---- .../mainactivity/main/PlaylistFragment.kt | 6 +-- .../viewholders/ImportPlaylistsViewHolder.kt | 7 ++-- app/src/main/res/layout/dialog_progress.xml | 1 + app/src/unstable/assets/sources/youtube | 2 +- 5 files changed, 42 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ImportPlaylistsFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ImportPlaylistsFragment.kt index e90a535d..fbfe75c8 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ImportPlaylistsFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ImportPlaylistsFragment.kt @@ -12,16 +12,21 @@ import android.widget.TextView import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import com.futo.platformplayer.* +import com.futo.platformplayer.api.media.models.playlists.IPlatformPlaylistDetails import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.fragment.mainactivity.topbar.ImportTopBarFragment import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.models.Playlist import com.futo.platformplayer.states.StatePlatform import com.futo.platformplayer.states.StatePlaylists +import com.futo.platformplayer.states.StateSubscriptions import com.futo.platformplayer.views.AnyAdapterView import com.futo.platformplayer.views.AnyAdapterView.Companion.asAny import com.futo.platformplayer.views.adapters.viewholders.ImportPlaylistsViewHolder import com.futo.platformplayer.views.adapters.viewholders.SelectablePlaylist +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class ImportPlaylistsFragment : MainFragment() { override val isMainView : Boolean = true; @@ -67,7 +72,7 @@ class ImportPlaylistsFragment : MainFragment() { private val _items: ArrayList = arrayListOf(); private var _currentLoadIndex = 0; - private var _taskLoadPlaylist: TaskHandler; + private var _taskLoadPlaylist: TaskHandler; constructor(fragment: ImportPlaylistsFragment, inflater: LayoutInflater) : super(inflater.context) { _fragment = fragment; @@ -102,7 +107,7 @@ class ImportPlaylistsFragment : MainFragment() { setLoading(false); - _taskLoadPlaylist = TaskHandler({fragment.lifecycleScope}, { link -> StatePlatform.instance.getPlaylist(link).toPlaylist(); }) + _taskLoadPlaylist = TaskHandler({fragment.lifecycleScope}, { link -> StatePlatform.instance.getPlaylist(link); }) .success { if (it != null) { _items.add(SelectablePlaylist(it)); @@ -113,7 +118,7 @@ class ImportPlaylistsFragment : MainFragment() { }.exceptionWithParameter { ex, para -> //setLoading(false); Logger.w(ChannelFragment.TAG, "Failed to load results.", ex); - UIDialogs.toast(context, context.getString(R.string.failed_to_fetch) + "\n${para}", false) + UIDialogs.appToast(context.getString(R.string.failed_to_fetch) + "\n${para}\n" + ex.message, false) //UIDialogs.showDataRetryDialog(layoutInflater, { load(); }); loadNext(); }; @@ -147,12 +152,32 @@ class ImportPlaylistsFragment : MainFragment() { it.title = context.getString(R.string.import_playlists); it.onImport.subscribe(this) { val playlistsToImport = _items.filter { i -> i.selected }.toList(); - for (playlistToImport in playlistsToImport) { - StatePlaylists.instance.createOrUpdatePlaylist(playlistToImport.playlist); - } - UIDialogs.toast("${playlistsToImport.size} " + context.getString(R.string.playlists_imported)); - _fragment.closeSegment(); + UIDialogs.showDialogProgress(context) { + it.setText("Importing playlists.."); + it.setProgress(0f); + _fragment.lifecycleScope.launch(Dispatchers.IO) { + for ((i, playlistToImport) in playlistsToImport.withIndex()) { + withContext(Dispatchers.Main) { + it.setText("Importing playlists..\n[${playlistToImport.playlist.name}]"); + } + try { + StatePlaylists.instance.createOrUpdatePlaylist(playlistToImport.playlist.toPlaylist()); + } + catch(ex: Throwable) { + UIDialogs.appToast("Failed to import [${playlistToImport.playlist.name}]\n" + ex.message); + } + withContext(Dispatchers.Main) { + it.setProgress(i.toDouble() / playlistsToImport.size); + } + } + withContext(Dispatchers.Main) { + UIDialogs.toast("${playlistsToImport.size} " + context.getString(R.string.playlists_imported)); + _fragment.closeSegment(); + it.dismiss(); + } + } + } }; } } diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/PlaylistFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/PlaylistFragment.kt index d938e970..713668fe 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/PlaylistFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/PlaylistFragment.kt @@ -136,12 +136,12 @@ class PlaylistFragment : MainFragment() { return@TaskHandler StatePlatform.instance.getPlaylist(it); }) .success { - setLoading(false); _remotePlaylist = it; setName(it.name); - setVideos(it.contents.getResults(), false); - setVideoCount(it.videoCount); //TODO: Implement support for pagination + setVideos(it.toPlaylist().videos, false); + setVideoCount(it.videoCount); + setLoading(false); } .exception { Logger.w(TAG, "Failed to load playlist.", it); diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/ImportPlaylistsViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/ImportPlaylistsViewHolder.kt index 9cbf400c..e17e84aa 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/ImportPlaylistsViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/ImportPlaylistsViewHolder.kt @@ -7,6 +7,7 @@ import android.widget.LinearLayout import android.widget.TextView import com.bumptech.glide.Glide import com.futo.platformplayer.R +import com.futo.platformplayer.api.media.models.playlists.IPlatformPlaylistDetails import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.models.Playlist import com.futo.platformplayer.views.adapters.AnyAdapter @@ -45,10 +46,10 @@ class ImportPlaylistsViewHolder(private val _viewGroup: ViewGroup) : AnyAdapter. override fun bind(value: SelectablePlaylist) { _textName.text = value.playlist.name; - _textMetadata.text = "${value.playlist.videos.size} " + _view.context.getString(R.string.videos); + _textMetadata.text = "${value.playlist.videoCount} " + _view.context.getString(R.string.videos); _checkbox.value = value.selected; - val thumbnail = value.playlist.videos.firstOrNull()?.thumbnails?.getHQThumbnail(); + val thumbnail = value.playlist.thumbnail; if (thumbnail != null) Glide.with(_imageThumbnail) .load(thumbnail) @@ -62,6 +63,6 @@ class ImportPlaylistsViewHolder(private val _viewGroup: ViewGroup) : AnyAdapter. } class SelectablePlaylist( - val playlist: Playlist, + val playlist: IPlatformPlaylistDetails, var selected: Boolean = false ) { } \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_progress.xml b/app/src/main/res/layout/dialog_progress.xml index 75b37e42..7bcc6228 100644 --- a/app/src/main/res/layout/dialog_progress.xml +++ b/app/src/main/res/layout/dialog_progress.xml @@ -45,6 +45,7 @@ android:textColor="@color/white" android:textSize="14dp" android:fontFamily="@font/inter_regular" + android:textAlignment="center" android:layout_marginTop="30dp" android:layout_marginStart="30dp" android:layout_marginEnd="30dp" /> diff --git a/app/src/unstable/assets/sources/youtube b/app/src/unstable/assets/sources/youtube index c23302da..2a38e0ce 160000 --- a/app/src/unstable/assets/sources/youtube +++ b/app/src/unstable/assets/sources/youtube @@ -1 +1 @@ -Subproject commit c23302da76fc706faf02f7d9331ed28baed04607 +Subproject commit 2a38e0cecc635df2122b142f2d0c9e13ac894772