Fixed remote playlist ToPlaylist.

This commit is contained in:
Koen 2024-06-14 14:54:37 +02:00
commit 2a6ba6d541
3 changed files with 44 additions and 35 deletions

View file

@ -8,5 +8,5 @@ interface IPlatformPlaylistDetails: IPlatformPlaylist {
//TODO: Determine if this should be IPlatformContent (probably not?) //TODO: Determine if this should be IPlatformContent (probably not?)
val contents: IPager<IPlatformVideo>; val contents: IPager<IPlatformVideo>;
fun toPlaylist(): Playlist; fun toPlaylist(onProgress: ((progress: Int) -> Unit)? = null): Playlist;
} }

View file

@ -7,7 +7,7 @@ import com.futo.platformplayer.api.media.models.video.SerializedPlatformVideo
import com.futo.platformplayer.api.media.platforms.js.JSClient import com.futo.platformplayer.api.media.platforms.js.JSClient
import com.futo.platformplayer.api.media.platforms.js.SourcePluginConfig import com.futo.platformplayer.api.media.platforms.js.SourcePluginConfig
import com.futo.platformplayer.api.media.structures.IPager import com.futo.platformplayer.api.media.structures.IPager
import com.futo.platformplayer.engine.V8Plugin import com.futo.platformplayer.api.media.structures.ReusablePager
import com.futo.platformplayer.getOrThrow import com.futo.platformplayer.getOrThrow
import com.futo.platformplayer.models.Playlist import com.futo.platformplayer.models.Playlist
@ -15,22 +15,26 @@ class JSPlaylistDetails: JSPlaylist, IPlatformPlaylistDetails {
override val contents: IPager<IPlatformVideo>; override val contents: IPager<IPlatformVideo>;
constructor(plugin: JSClient, config: SourcePluginConfig, obj: V8ValueObject): super(config, obj) { constructor(plugin: JSClient, config: SourcePluginConfig, obj: V8ValueObject): super(config, obj) {
contents = JSVideoPager(config, plugin, obj.getOrThrow(config, "contents", "PlaylistDetails")); contents = ReusablePager(JSVideoPager(config, plugin, obj.getOrThrow(config, "contents", "PlaylistDetails")));
} }
override fun toPlaylist(): Playlist { override fun toPlaylist(onProgress: ((progress: Int) -> Unit)?): Playlist {
val videos = contents.getResults().toMutableList(); val playlist = if (contents is ReusablePager) contents.getWindow() else contents;
val videos = playlist.getResults().toMutableList();
onProgress?.invoke(videos.size);
//Download all pages //Download all pages
var allowedEmptyCount = 2; var allowedEmptyCount = 2;
while(contents.hasMorePages()) { while(playlist.hasMorePages()) {
contents.nextPage(); playlist.nextPage();
if(!videos.addAll(contents.getResults())) { if(!videos.addAll(playlist.getResults())) {
allowedEmptyCount--; allowedEmptyCount--;
if(allowedEmptyCount <= 0) if(allowedEmptyCount <= 0)
break; break;
} }
else allowedEmptyCount = 2; else allowedEmptyCount = 2;
onProgress?.invoke(videos.size);
} }
return Playlist(id.toString(), name, videos.map { SerializedPlatformVideo.fromVideo(it)}); return Playlist(id.toString(), name, videos.map { SerializedPlatformVideo.fromVideo(it)});

View file

@ -24,11 +24,11 @@ import com.futo.platformplayer.api.media.platforms.js.models.JSPager
import com.futo.platformplayer.api.media.structures.IAsyncPager import com.futo.platformplayer.api.media.structures.IAsyncPager
import com.futo.platformplayer.api.media.structures.IPager import com.futo.platformplayer.api.media.structures.IPager
import com.futo.platformplayer.api.media.structures.MultiPager import com.futo.platformplayer.api.media.structures.MultiPager
import com.futo.platformplayer.api.media.structures.ReusablePager
import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.constructs.TaskHandler
import com.futo.platformplayer.fragment.mainactivity.topbar.NavigationTopBarFragment import com.futo.platformplayer.fragment.mainactivity.topbar.NavigationTopBarFragment
import com.futo.platformplayer.images.GlideHelper.Companion.crossfade import com.futo.platformplayer.images.GlideHelper.Companion.crossfade
import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.logging.Logger
import com.futo.platformplayer.models.Playlist
import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StateApp
import com.futo.platformplayer.states.StatePlatform import com.futo.platformplayer.states.StatePlatform
import com.futo.platformplayer.states.StatePlaylists import com.futo.platformplayer.states.StatePlaylists
@ -66,6 +66,7 @@ class RemotePlaylistFragment : MainFragment() {
private val _fragment: RemotePlaylistFragment; private val _fragment: RemotePlaylistFragment;
private var _remotePlaylist: IPlatformPlaylistDetails? = null; private var _remotePlaylist: IPlatformPlaylistDetails? = null;
private var _remotePlaylistPagerWindow: IPager<IPlatformVideo>? = null;
private var _url: String? = null; private var _url: String? = null;
private val _videos: ArrayList<IPlatformVideo> = arrayListOf(); private val _videos: ArrayList<IPlatformVideo> = arrayListOf();
@ -103,9 +104,7 @@ class RemotePlaylistFragment : MainFragment() {
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.list_playlist, viewGroup, false); val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.list_playlist, viewGroup, false);
val holder = VideoListEditorViewHolder(view, null); val holder = VideoListEditorViewHolder(view, null);
holder.onClick.subscribe { holder.onClick.subscribe {
showConvertConfirmationModal() { showConvertConfirmationModal();
_fragment.navigate<PlaylistFragment>(it);
}
}; };
return@InsertedViewAdapterWithLoader holder; return@InsertedViewAdapterWithLoader holder;
} }
@ -129,14 +128,10 @@ class RemotePlaylistFragment : MainFragment() {
}; };
buttonPlayAll.setOnClickListener { buttonPlayAll.setOnClickListener {
showConvertConfirmationModal() { showConvertConfirmationModal();
_fragment.navigate<PlaylistFragment>(it);
}
}; };
buttonShuffle.setOnClickListener { buttonShuffle.setOnClickListener {
showConvertConfirmationModal() { showConvertConfirmationModal();
_fragment.navigate<PlaylistFragment>(it);
}
}; };
_taskLoadPlaylist = TaskHandler<String, IPlatformPlaylistDetails>( _taskLoadPlaylist = TaskHandler<String, IPlatformPlaylistDetails>(
@ -146,8 +141,10 @@ class RemotePlaylistFragment : MainFragment() {
}) })
.success { .success {
_remotePlaylist = it; _remotePlaylist = it;
val c = it.contents;
_remotePlaylistPagerWindow = if (c is ReusablePager) c.getWindow() else c;
setName(it.name); setName(it.name);
setVideos(it.contents.getResults()); setVideos(_remotePlaylistPagerWindow!!.getResults());
setVideoCount(it.videoCount); setVideoCount(it.videoCount);
setLoading(false); setLoading(false);
} }
@ -193,7 +190,7 @@ class RemotePlaylistFragment : MainFragment() {
} }
private fun loadNextPage() { private fun loadNextPage() {
val pager: IPager<IPlatformVideo> = _remotePlaylist?.contents ?: return; val pager: IPager<IPlatformVideo> = _remotePlaylistPagerWindow ?: return;
val hasMorePages = pager.hasMorePages(); val hasMorePages = pager.hasMorePages();
Logger.i(TAG, "loadNextPage() hasMorePages=$hasMorePages, page size=${pager.getResults().size}"); Logger.i(TAG, "loadNextPage() hasMorePages=$hasMorePages, page size=${pager.getResults().size}");
@ -256,7 +253,7 @@ class RemotePlaylistFragment : MainFragment() {
} }
} }
private fun showConvertConfirmationModal(onSuccess: ((playlist: Playlist) -> Unit)? = null) { private fun showConvertConfirmationModal() {
val remotePlaylist = _remotePlaylist; val remotePlaylist = _remotePlaylist;
if (remotePlaylist == null) { if (remotePlaylist == null) {
UIDialogs.toast(context.getString(R.string.please_wait_for_playlist_to_finish_loading)); UIDialogs.toast(context.getString(R.string.please_wait_for_playlist_to_finish_loading));
@ -266,22 +263,30 @@ class RemotePlaylistFragment : MainFragment() {
val c = context ?: return; val c = context ?: return;
UIDialogs.showConfirmationDialog(c, "Conversion to local playlist is required for this action", { UIDialogs.showConfirmationDialog(c, "Conversion to local playlist is required for this action", {
setLoading(true); setLoading(true);
StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) {
try {
val playlist = remotePlaylist.toPlaylist();
StatePlaylists.instance.playlistStore.save(playlist);
withContext(Dispatchers.Main) { UIDialogs.showDialogProgress(context) {
setLoading(false); it.setText("Converting playlist..");
UIDialogs.toast(context.getString(R.string.playlist_copied_as_local_playlist)); it.setProgress(0f);
onSuccess?.invoke(playlist);
}
} catch (e: Throwable) {
withContext(Dispatchers.Main) {
setLoading(false);
}
throw e; _fragment.lifecycleScope.launch(Dispatchers.IO) {
try {
val playlist = remotePlaylist.toPlaylist() { progress ->
_fragment.lifecycleScope.launch(Dispatchers.Main) {
it.setProgress(progress.toDouble() / remotePlaylist.videoCount);
}
};
StatePlaylists.instance.playlistStore.save(playlist);
withContext(Dispatchers.Main) {
UIDialogs.toast("Playlist converted");
it.dismiss();
_fragment.navigate<PlaylistFragment>(playlist);
}
}
catch(ex: Throwable) {
UIDialogs.appToast("Failed to convert playlist.\n" + ex.message);
}
} }
} }
}); });