Use LongPressMenu in BookmarkFragment

This commit is contained in:
Stypox 2025-02-14 14:08:08 +01:00
parent e0b24c7529
commit 1bb298be84
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
3 changed files with 113 additions and 34 deletions

View File

@ -2,8 +2,8 @@ package org.schabi.newpipe.local.bookmark;
import static org.schabi.newpipe.local.bookmark.MergedPlaylistManager.getMergedOrderedPlaylists;
import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout;
import static org.schabi.newpipe.ui.components.menu.LongPressMenuKt.openLongPressMenuInActivity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.InputType;
@ -40,6 +40,8 @@ import org.schabi.newpipe.local.holder.LocalBookmarkPlaylistItemHolder;
import org.schabi.newpipe.local.holder.RemoteBookmarkPlaylistItemHolder;
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
import org.schabi.newpipe.ui.components.menu.LongPressAction;
import org.schabi.newpipe.ui.components.menu.LongPressable;
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec;
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
import org.schabi.newpipe.util.NavigationHelper;
@ -163,7 +165,7 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL
if (selectedItem instanceof PlaylistMetadataEntry) {
showLocalDialog((PlaylistMetadataEntry) selectedItem);
} else if (selectedItem instanceof PlaylistRemoteEntity) {
showRemoteDeleteDialog((PlaylistRemoteEntity) selectedItem);
showRemoteDialog((PlaylistRemoteEntity) selectedItem);
}
}
@ -493,42 +495,31 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL
// Utils
///////////////////////////////////////////////////////////////////////////
private void showRemoteDeleteDialog(final PlaylistRemoteEntity item) {
showDeleteDialog(item.getOrderingName(), item);
private void showRemoteDialog(final PlaylistRemoteEntity item) {
openLongPressMenuInActivity(
requireActivity(),
LongPressable.fromPlaylistRemoteEntity(item),
LongPressAction.fromPlaylistRemoteEntity(
item,
() -> showDeleteDialog(item.getOrderingName(), item)
)
);
}
private void showLocalDialog(final PlaylistMetadataEntry selectedItem) {
final String rename = getString(R.string.rename);
final String delete = getString(R.string.delete);
final String unsetThumbnail = getString(R.string.unset_playlist_thumbnail);
final boolean isThumbnailPermanent = localPlaylistManager
.getIsPlaylistThumbnailPermanent(selectedItem.getUid());
final ArrayList<String> items = new ArrayList<>();
items.add(rename);
items.add(delete);
if (isThumbnailPermanent) {
items.add(unsetThumbnail);
}
final DialogInterface.OnClickListener action = (d, index) -> {
if (items.get(index).equals(rename)) {
showRenameDialog(selectedItem);
} else if (items.get(index).equals(delete)) {
showDeleteDialog(selectedItem.getOrderingName(), selectedItem);
} else if (isThumbnailPermanent && items.get(index).equals(unsetThumbnail)) {
final long thumbnailStreamId = localPlaylistManager
.getAutomaticPlaylistThumbnailStreamId(selectedItem.getUid());
localPlaylistManager
.changePlaylistThumbnail(selectedItem.getUid(), thumbnailStreamId, false)
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
}
};
new AlertDialog.Builder(activity)
.setItems(items.toArray(new String[0]), action)
.show();
openLongPressMenuInActivity(
requireActivity(),
LongPressable.fromPlaylistMetadataEntry(selectedItem),
LongPressAction.fromPlaylistMetadataEntry(
selectedItem,
() -> showRenameDialog(selectedItem),
() -> showDeleteDialog(selectedItem.getOrderingName(), selectedItem),
isThumbnailPermanent ? () -> unsetPermanentThumbnail(selectedItem) : null
)
);
}
private void showRenameDialog(final PlaylistMetadataEntry selectedItem) {
@ -561,4 +552,13 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL
.setNegativeButton(R.string.cancel, null)
.show();
}
private void unsetPermanentThumbnail(final PlaylistMetadataEntry item) {
final long thumbnailStreamId = localPlaylistManager
.getAutomaticPlaylistThumbnailStreamId(item.getUid());
localPlaylistManager
.changePlaylistThumbnail(item.getUid(), thumbnailStreamId, false)
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
}
}

View File

@ -10,9 +10,11 @@ import androidx.compose.material.icons.filled.Cast
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.icons.filled.Download
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.Headset
import androidx.compose.material.icons.filled.HideImage
import androidx.compose.material.icons.filled.Image
import androidx.compose.material.icons.filled.OpenInBrowser
import androidx.compose.material.icons.filled.Panorama
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.PictureInPicture
import androidx.compose.material.icons.filled.PlayArrow
@ -21,7 +23,9 @@ import androidx.compose.material.icons.filled.Share
import androidx.compose.ui.graphics.vector.ImageVector
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import org.schabi.newpipe.R
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry
import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity
import org.schabi.newpipe.database.stream.StreamStatisticsEntry
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.download.DownloadDialog
@ -62,7 +66,9 @@ data class LongPressAction(
ShowChannelDetails(R.string.show_channel_details, Icons.Default.Person),
MarkAsWatched(R.string.mark_as_watched, Icons.Default.Done),
Delete(R.string.delete, Icons.Default.Delete),
SetAsPlaylistThumbnail(R.string.set_as_playlist_thumbnail, Icons.Default.Panorama),
Rename(R.string.rename, Icons.Default.Edit),
SetAsPlaylistThumbnail(R.string.set_as_playlist_thumbnail, Icons.Default.Image),
UnsetPlaylistThumbnail(R.string.unset_playlist_thumbnail, Icons.Default.HideImage),
;
// TODO allow actions to return disposables
@ -106,6 +112,17 @@ data class LongPressAction(
)
}
private fun buildShareActionList(name: String, url: String, thumbnailUrl: String?): List<LongPressAction> {
return listOf(
Type.Share.buildAction { context ->
ShareUtils.shareText(context, name, url, thumbnailUrl)
},
Type.OpenInBrowser.buildAction { context ->
ShareUtils.openUrlInBrowser(context, url)
},
)
}
@JvmStatic
fun fromStreamInfoItem(
item: StreamInfoItem,
@ -209,6 +226,7 @@ data class LongPressAction(
@JvmStatic
fun fromPlaylistStreamEntry(
item: PlaylistStreamEntry,
// TODO possibly embed these two actions here
onDelete: Runnable,
onSetAsPlaylistThumbnail: Runnable,
): List<LongPressAction> {
@ -218,5 +236,36 @@ data class LongPressAction(
Type.SetAsPlaylistThumbnail.buildAction { onSetAsPlaylistThumbnail.run() }
)
}
@JvmStatic
fun fromPlaylistMetadataEntry(
item: PlaylistMetadataEntry,
onRename: Runnable,
onDelete: Runnable,
unsetPlaylistThumbnail: Runnable?,
): List<LongPressAction> {
return listOf(
Type.Rename.buildAction { onRename.run() },
Type.Delete.buildAction { onDelete.run() },
Type.UnsetPlaylistThumbnail.buildAction(
enabled = { unsetPlaylistThumbnail != null }
) { unsetPlaylistThumbnail?.run() }
)
}
@JvmStatic
fun fromPlaylistRemoteEntity(
item: PlaylistRemoteEntity,
onDelete: Runnable,
): List<LongPressAction> {
return buildShareActionList(
item.orderingName ?: "",
item.url ?: "",
item.thumbnailUrl
) +
listOf(
Type.Delete.buildAction { onDelete.run() },
)
}
}
}

View File

@ -1,7 +1,10 @@
package org.schabi.newpipe.ui.components.menu
import androidx.compose.runtime.Stable
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry
import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.extractor.ListExtractor
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.extractor.stream.StreamType
import org.schabi.newpipe.extractor.stream.StreamType.AUDIO_LIVE_STREAM
@ -62,5 +65,32 @@ data class LongPressable(
?: item.textualUploadDate?.let { Either.left(it) },
decoration = Decoration.from(item.streamType, item.duration),
)
@JvmStatic
fun fromPlaylistMetadataEntry(item: PlaylistMetadataEntry) = LongPressable(
// many fields are null because this is a local playlist
title = item.orderingName ?: "",
url = null,
thumbnailUrl = item.thumbnailUrl,
uploader = null,
uploaderUrl = null,
viewCount = null,
uploadDate = null,
decoration = Decoration.Playlist(item.streamCount),
)
@JvmStatic
fun fromPlaylistRemoteEntity(item: PlaylistRemoteEntity) = LongPressable(
title = item.orderingName ?: "",
url = item.url,
thumbnailUrl = item.thumbnailUrl,
uploader = item.uploader,
uploaderUrl = null,
viewCount = null,
uploadDate = null,
decoration = Decoration.Playlist(
item.streamCount ?: ListExtractor.ITEM_COUNT_UNKNOWN
),
)
}
}