Skip to content
Snippets Groups Projects
Commit 83843f19 authored by Kelvin's avatar Kelvin
Browse files

Show total downloaded content duration, Indicator how many subscriptions, save queue as playlist

parent 8839d9f1
No related branches found
No related tags found
No related merge requests found
......@@ -79,6 +79,36 @@ class UISlideOverlays {
return menu;
}
fun showQueueOptionsOverlay(context: Context, container: ViewGroup) {
UISlideOverlays.showOverlay(container, "Queue options", null, {
}, SlideUpMenuItem(context, R.drawable.ic_playlist, "Save as playlist", "", "Creates a new playlist with queue as videos", null, {
val nameInput = SlideUpMenuTextInput(container.context, container.context.getString(R.string.name));
val addPlaylistOverlay = SlideUpMenuOverlay(container.context, container, container.context.getString(R.string.create_new_playlist), container.context.getString(R.string.ok), false, nameInput);
addPlaylistOverlay.onOK.subscribe {
val text = nameInput.text.trim()
if (text.isBlank()) {
return@subscribe;
}
addPlaylistOverlay.hide();
nameInput.deactivate();
nameInput.clear();
StatePlayer.instance.saveQueueAsPlaylist(text);
UIDialogs.appToast("Playlist [${text}] created");
};
addPlaylistOverlay.onCancel.subscribe {
nameInput.deactivate();
nameInput.clear();
};
addPlaylistOverlay.show();
nameInput.activate();
}, false));
}
fun showSubscriptionOptionsOverlay(subscription: Subscription, container: ViewGroup): SlideUpMenuOverlay {
val items = arrayListOf<View>();
......
......@@ -10,6 +10,7 @@ import android.widget.EditText
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.Spinner
import android.widget.TextView
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
......@@ -26,6 +27,7 @@ class CreatorsFragment : MainFragment() {
private var _overlayContainer: FrameLayout? = null;
private var _containerSearch: FrameLayout? = null;
private var _editSearch: EditText? = null;
private var _textMeta: TextView? = null;
private var _buttonClearSearch: ImageButton? = null
override fun onCreateMainView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
......@@ -34,6 +36,7 @@ class CreatorsFragment : MainFragment() {
val editSearch: EditText = view.findViewById(R.id.edit_search);
val buttonClearSearch: ImageButton = view.findViewById(R.id.button_clear_search)
_editSearch = editSearch
_textMeta = view.findViewById(R.id.text_meta);
_buttonClearSearch = buttonClearSearch
buttonClearSearch.setOnClickListener {
editSearch.text.clear()
......@@ -41,7 +44,11 @@ class CreatorsFragment : MainFragment() {
_buttonClearSearch?.visibility = View.INVISIBLE;
}
val adapter = SubscriptionAdapter(inflater, getString(R.string.confirm_delete_subscription));
val adapter = SubscriptionAdapter(inflater, getString(R.string.confirm_delete_subscription)) { subs ->
_textMeta?.let {
it.text = "${subs.size} creator${if(subs.size > 1) "s" else ""}";
}
};
adapter.onClick.subscribe { platformUser -> navigate<ChannelFragment>(platformUser) };
adapter.onSettings.subscribe { sub -> _overlayContainer?.let { UISlideOverlays.showSubscriptionOptionsOverlay(sub, it) } }
......
......@@ -22,6 +22,7 @@ import com.futo.platformplayer.states.StateDownloads
import com.futo.platformplayer.states.StatePlayer
import com.futo.platformplayer.states.StatePlaylists
import com.futo.platformplayer.toHumanBytesSize
import com.futo.platformplayer.toHumanDuration
import com.futo.platformplayer.views.AnyInsertedAdapterView
import com.futo.platformplayer.views.AnyInsertedAdapterView.Companion.asAnyWithTop
import com.futo.platformplayer.views.adapters.viewholders.VideoDownloadViewHolder
......@@ -215,7 +216,7 @@ class DownloadsFragment : MainFragment() {
_listDownloadedHeader.visibility = GONE;
} else {
_listDownloadedHeader.visibility = VISIBLE;
_listDownloadedMeta.text = "(${downloaded.size} ${context.getString(R.string.videos).lowercase()})";
_listDownloadedMeta.text = "(${downloaded.size} ${context.getString(R.string.videos).lowercase()}${if(downloaded.size > 0) ", ${downloaded.sumOf { it.duration }.toHumanDuration(false)}" else ""})";
}
lastDownloads = downloaded;
......
......@@ -13,6 +13,7 @@ import com.futo.platformplayer.UIDialogs
import com.futo.platformplayer.api.media.models.playlists.IPlatformPlaylistDetails
import com.futo.platformplayer.api.media.models.video.IPlatformVideo
import com.futo.platformplayer.api.media.models.video.IPlatformVideoDetails
import com.futo.platformplayer.api.media.models.video.SerializedPlatformVideo
import com.futo.platformplayer.constructs.Event0
import com.futo.platformplayer.constructs.Event1
import com.futo.platformplayer.logging.Logger
......@@ -130,6 +131,12 @@ class StatePlayer {
closeMediaSession();
}
fun saveQueueAsPlaylist(name: String){
val videos = _queue.toList();
val playlist = Playlist(name, videos.map { SerializedPlatformVideo.fromVideo(it) });
StatePlaylists.instance.createOrUpdatePlaylist(playlist);
}
//Notifications
fun hasMediaSession() : Boolean {
return MediaPlaybackService.getService() != null;
......
......@@ -16,6 +16,7 @@ class SubscriptionAdapter : RecyclerView.Adapter<SubscriptionViewHolder> {
private lateinit var _sortedDataset: List<Subscription>;
private val _inflater: LayoutInflater;
private val _confirmationMessage: String;
private val _onDatasetChanged: ((List<Subscription>)->Unit)?;
var onClick = Event1<Subscription>();
var onSettings = Event1<Subscription>();
......@@ -30,9 +31,10 @@ class SubscriptionAdapter : RecyclerView.Adapter<SubscriptionViewHolder> {
updateDataset();
}
constructor(inflater: LayoutInflater, confirmationMessage: String) : super() {
constructor(inflater: LayoutInflater, confirmationMessage: String, onDatasetChanged: ((List<Subscription>)->Unit)? = null) : super() {
_inflater = inflater;
_confirmationMessage = confirmationMessage;
_onDatasetChanged = onDatasetChanged;
StateSubscriptions.instance.onSubscriptionsChanged.subscribe { _, _ -> if(Looper.myLooper() != Looper.getMainLooper())
StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { updateDataset() }
......@@ -78,6 +80,8 @@ class SubscriptionAdapter : RecyclerView.Adapter<SubscriptionViewHolder> {
.filter { (queryLower.isNullOrBlank() || it.channel.name.lowercase().contains(queryLower)) }
.toList();
_onDatasetChanged?.invoke(_sortedDataset);
notifyDataSetChanged();
}
......
......@@ -2,16 +2,26 @@ package com.futo.platformplayer.views.overlays
import android.content.Context
import android.util.AttributeSet
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import com.futo.platformplayer.states.StatePlayer
import com.futo.platformplayer.R
import com.futo.platformplayer.UISlideOverlays
import com.futo.platformplayer.constructs.Event0
import com.futo.platformplayer.views.lists.VideoListEditorView
import com.futo.platformplayer.views.overlays.slideup.SlideUpMenuItem
import com.futo.platformplayer.views.overlays.slideup.SlideUpMenuOverlay
import com.futo.platformplayer.views.overlays.slideup.SlideUpMenuTextInput
class QueueEditorOverlay : LinearLayout {
private val _topbar : OverlayTopbar;
private val _editor : VideoListEditorView;
private val _btnSettings: ImageView;
private val _overlayContainer: FrameLayout;
val onClose = Event0();
......@@ -19,6 +29,9 @@ class QueueEditorOverlay : LinearLayout {
inflate(context, R.layout.overlay_queue, this)
_topbar = findViewById(R.id.topbar);
_editor = findViewById(R.id.editor);
_btnSettings = findViewById(R.id.button_settings);
_overlayContainer = findViewById(R.id.overlay_container);
_topbar.onClose.subscribe(this, onClose::emit);
_editor.onVideoOrderChanged.subscribe { StatePlayer.instance.setQueueWithExisting(it) }
......@@ -28,6 +41,10 @@ class QueueEditorOverlay : LinearLayout {
}
_editor.onVideoClicked.subscribe { v -> StatePlayer.instance.setQueuePosition(v) }
_btnSettings.setOnClickListener {
handleSettings();
}
_topbar.setInfo(context.getString(R.string.queue), "");
}
......@@ -40,4 +57,8 @@ class QueueEditorOverlay : LinearLayout {
fun cleanup() {
_topbar.onClose.remove(this);
}
fun handleSettings() {
UISlideOverlays.showQueueOptionsOverlay(context, _overlayContainer);
}
}
\ No newline at end of file
......@@ -16,7 +16,7 @@
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_height="110dp"
android:minHeight="0dp"
app:layout_scrollFlags="scroll"
app:contentInsetStart="0dp"
......@@ -77,7 +77,16 @@
android:layout_height="wrap_content"
android:paddingStart="20dp"
android:paddingEnd="20dp" />
</LinearLayout>
<TextView
android:id="@+id/text_meta"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="9dp"
android:textAlignment="center"
android:textColor="#333333"
android:text="0 creators" />
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
......
......@@ -21,5 +21,20 @@
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/topbar"
app:layout_constraintBottom_toBottomOf="parent" />
<ImageView
android:id="@+id/button_settings"
android:background="@drawable/background_pill"
android:padding="5dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:srcCompat="@drawable/ic_settings" />
<FrameLayout
android:id="@+id/overlay_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment