mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-08-02 22:30:40 +00:00
Improved playlist import support
This commit is contained in:
parent
ff28a07871
commit
aad50e7b50
5 changed files with 42 additions and 15 deletions
|
@ -12,16 +12,21 @@ import android.widget.TextView
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.futo.platformplayer.*
|
import com.futo.platformplayer.*
|
||||||
|
import com.futo.platformplayer.api.media.models.playlists.IPlatformPlaylistDetails
|
||||||
import com.futo.platformplayer.constructs.TaskHandler
|
import com.futo.platformplayer.constructs.TaskHandler
|
||||||
import com.futo.platformplayer.fragment.mainactivity.topbar.ImportTopBarFragment
|
import com.futo.platformplayer.fragment.mainactivity.topbar.ImportTopBarFragment
|
||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
import com.futo.platformplayer.models.Playlist
|
import com.futo.platformplayer.models.Playlist
|
||||||
import com.futo.platformplayer.states.StatePlatform
|
import com.futo.platformplayer.states.StatePlatform
|
||||||
import com.futo.platformplayer.states.StatePlaylists
|
import com.futo.platformplayer.states.StatePlaylists
|
||||||
|
import com.futo.platformplayer.states.StateSubscriptions
|
||||||
import com.futo.platformplayer.views.AnyAdapterView
|
import com.futo.platformplayer.views.AnyAdapterView
|
||||||
import com.futo.platformplayer.views.AnyAdapterView.Companion.asAny
|
import com.futo.platformplayer.views.AnyAdapterView.Companion.asAny
|
||||||
import com.futo.platformplayer.views.adapters.viewholders.ImportPlaylistsViewHolder
|
import com.futo.platformplayer.views.adapters.viewholders.ImportPlaylistsViewHolder
|
||||||
import com.futo.platformplayer.views.adapters.viewholders.SelectablePlaylist
|
import com.futo.platformplayer.views.adapters.viewholders.SelectablePlaylist
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class ImportPlaylistsFragment : MainFragment() {
|
class ImportPlaylistsFragment : MainFragment() {
|
||||||
override val isMainView : Boolean = true;
|
override val isMainView : Boolean = true;
|
||||||
|
@ -67,7 +72,7 @@ class ImportPlaylistsFragment : MainFragment() {
|
||||||
private val _items: ArrayList<SelectablePlaylist> = arrayListOf();
|
private val _items: ArrayList<SelectablePlaylist> = arrayListOf();
|
||||||
private var _currentLoadIndex = 0;
|
private var _currentLoadIndex = 0;
|
||||||
|
|
||||||
private var _taskLoadPlaylist: TaskHandler<String, Playlist?>;
|
private var _taskLoadPlaylist: TaskHandler<String, IPlatformPlaylistDetails?>;
|
||||||
|
|
||||||
constructor(fragment: ImportPlaylistsFragment, inflater: LayoutInflater) : super(inflater.context) {
|
constructor(fragment: ImportPlaylistsFragment, inflater: LayoutInflater) : super(inflater.context) {
|
||||||
_fragment = fragment;
|
_fragment = fragment;
|
||||||
|
@ -102,7 +107,7 @@ class ImportPlaylistsFragment : MainFragment() {
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
||||||
_taskLoadPlaylist = TaskHandler<String, Playlist?>({fragment.lifecycleScope}, { link -> StatePlatform.instance.getPlaylist(link).toPlaylist(); })
|
_taskLoadPlaylist = TaskHandler<String, IPlatformPlaylistDetails?>({fragment.lifecycleScope}, { link -> StatePlatform.instance.getPlaylist(link); })
|
||||||
.success {
|
.success {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
_items.add(SelectablePlaylist(it));
|
_items.add(SelectablePlaylist(it));
|
||||||
|
@ -113,7 +118,7 @@ class ImportPlaylistsFragment : MainFragment() {
|
||||||
}.exceptionWithParameter<Throwable> { ex, para ->
|
}.exceptionWithParameter<Throwable> { ex, para ->
|
||||||
//setLoading(false);
|
//setLoading(false);
|
||||||
Logger.w(ChannelFragment.TAG, "Failed to load results.", ex);
|
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(); });
|
//UIDialogs.showDataRetryDialog(layoutInflater, { load(); });
|
||||||
loadNext();
|
loadNext();
|
||||||
};
|
};
|
||||||
|
@ -147,12 +152,32 @@ class ImportPlaylistsFragment : MainFragment() {
|
||||||
it.title = context.getString(R.string.import_playlists);
|
it.title = context.getString(R.string.import_playlists);
|
||||||
it.onImport.subscribe(this) {
|
it.onImport.subscribe(this) {
|
||||||
val playlistsToImport = _items.filter { i -> i.selected }.toList();
|
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));
|
UIDialogs.showDialogProgress(context) {
|
||||||
_fragment.closeSegment();
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,12 +136,12 @@ class PlaylistFragment : MainFragment() {
|
||||||
return@TaskHandler StatePlatform.instance.getPlaylist(it);
|
return@TaskHandler StatePlatform.instance.getPlaylist(it);
|
||||||
})
|
})
|
||||||
.success {
|
.success {
|
||||||
setLoading(false);
|
|
||||||
_remotePlaylist = it;
|
_remotePlaylist = it;
|
||||||
setName(it.name);
|
setName(it.name);
|
||||||
setVideos(it.contents.getResults(), false);
|
|
||||||
setVideoCount(it.videoCount);
|
|
||||||
//TODO: Implement support for pagination
|
//TODO: Implement support for pagination
|
||||||
|
setVideos(it.toPlaylist().videos, false);
|
||||||
|
setVideoCount(it.videoCount);
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
.exception<Throwable> {
|
.exception<Throwable> {
|
||||||
Logger.w(TAG, "Failed to load playlist.", it);
|
Logger.w(TAG, "Failed to load playlist.", it);
|
||||||
|
|
|
@ -7,6 +7,7 @@ import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.futo.platformplayer.R
|
import com.futo.platformplayer.R
|
||||||
|
import com.futo.platformplayer.api.media.models.playlists.IPlatformPlaylistDetails
|
||||||
import com.futo.platformplayer.constructs.Event1
|
import com.futo.platformplayer.constructs.Event1
|
||||||
import com.futo.platformplayer.models.Playlist
|
import com.futo.platformplayer.models.Playlist
|
||||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||||
|
@ -45,10 +46,10 @@ class ImportPlaylistsViewHolder(private val _viewGroup: ViewGroup) : AnyAdapter.
|
||||||
|
|
||||||
override fun bind(value: SelectablePlaylist) {
|
override fun bind(value: SelectablePlaylist) {
|
||||||
_textName.text = value.playlist.name;
|
_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;
|
_checkbox.value = value.selected;
|
||||||
|
|
||||||
val thumbnail = value.playlist.videos.firstOrNull()?.thumbnails?.getHQThumbnail();
|
val thumbnail = value.playlist.thumbnail;
|
||||||
if (thumbnail != null)
|
if (thumbnail != null)
|
||||||
Glide.with(_imageThumbnail)
|
Glide.with(_imageThumbnail)
|
||||||
.load(thumbnail)
|
.load(thumbnail)
|
||||||
|
@ -62,6 +63,6 @@ class ImportPlaylistsViewHolder(private val _viewGroup: ViewGroup) : AnyAdapter.
|
||||||
}
|
}
|
||||||
|
|
||||||
class SelectablePlaylist(
|
class SelectablePlaylist(
|
||||||
val playlist: Playlist,
|
val playlist: IPlatformPlaylistDetails,
|
||||||
var selected: Boolean = false
|
var selected: Boolean = false
|
||||||
) { }
|
) { }
|
|
@ -45,6 +45,7 @@
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="14dp"
|
android:textSize="14dp"
|
||||||
android:fontFamily="@font/inter_regular"
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:textAlignment="center"
|
||||||
android:layout_marginTop="30dp"
|
android:layout_marginTop="30dp"
|
||||||
android:layout_marginStart="30dp"
|
android:layout_marginStart="30dp"
|
||||||
android:layout_marginEnd="30dp" />
|
android:layout_marginEnd="30dp" />
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit c23302da76fc706faf02f7d9331ed28baed04607
|
Subproject commit 2a38e0cecc635df2122b142f2d0c9e13ac894772
|
Loading…
Add table
Add a link
Reference in a new issue