Use getPlayQueueStartingAt in BaseListFragment

Instead of overriding the whole showInfoItemDialog
This commit is contained in:
Stypox 2026-02-09 10:24:18 +01:00
parent 3b19d637c9
commit f65094b5fd
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
4 changed files with 45 additions and 46 deletions

View File

@ -30,6 +30,7 @@ import org.schabi.newpipe.fragments.BaseStateFragment;
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
import org.schabi.newpipe.info_list.InfoListAdapter;
import org.schabi.newpipe.info_list.ItemViewMode;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.ui.components.menu.LongPressAction;
import org.schabi.newpipe.ui.components.menu.LongPressable;
import org.schabi.newpipe.util.NavigationHelper;
@ -42,6 +43,8 @@ import java.util.List;
import java.util.Queue;
import java.util.function.Supplier;
import kotlin.jvm.functions.Function0;
public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
implements ListViewContract<I, N>, StateSaver.WriteRead,
SharedPreferences.OnSharedPreferenceChangeListener {
@ -267,8 +270,12 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
}
@Override
public void held(final StreamInfoItem selectedItem) {
showInfoItemDialog(selectedItem);
public void held(final StreamInfoItem item) {
openLongPressMenuInActivity(
requireActivity(),
LongPressable.fromStreamInfoItem(item),
LongPressAction.fromStreamInfoItem(item, getPlayQueueStartingAt(item))
);
}
});
@ -325,13 +332,15 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
useNormalItemListScrollListener();
}
protected void showInfoItemDialog(final StreamInfoItem item) {
openLongPressMenuInActivity(
requireActivity(),
LongPressable.fromStreamInfoItem(item),
// TODO generalize obtaining queue from here when fully migrating to Compose
LongPressAction.fromStreamInfoItem(item, null)
);
/**
* @param item an item in the list, from which the built queue should start
* @return a builder for a queue containing all of the items in this list, with the queue index
* set to the item passed as parameter; return {@code null} if no "start playing from here"
* options should be shown
*/
@Nullable
protected Function0<PlayQueue> getPlayQueueStartingAt(@NonNull final StreamInfoItem item) {
return null; // disable "play from here" options by default (e.g. in search, kiosks)
}
/**

View File

@ -1,7 +1,5 @@
package org.schabi.newpipe.fragments.list.channel;
import static org.schabi.newpipe.ui.components.menu.LongPressMenuKt.openLongPressMenuInActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
@ -28,8 +26,6 @@ import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder;
import org.schabi.newpipe.player.playqueue.ChannelTabPlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.ui.components.menu.LongPressAction;
import org.schabi.newpipe.ui.components.menu.LongPressable;
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
import org.schabi.newpipe.util.ChannelTabHelper;
import org.schabi.newpipe.util.ExtractorHelper;
@ -41,6 +37,7 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import io.reactivex.rxjava3.core.Single;
import kotlin.jvm.functions.Function0;
public class ChannelTabFragment extends BaseListInfoFragment<InfoItem, ChannelTabInfo>
implements PlaylistControlViewHolder {
@ -169,19 +166,6 @@ public class ChannelTabFragment extends BaseListInfoFragment<InfoItem, ChannelTa
}
}
@Override
protected void showInfoItemDialog(final StreamInfoItem item) {
openLongPressMenuInActivity(
requireActivity(),
LongPressable.fromStreamInfoItem(item),
LongPressAction.fromStreamInfoItem(item, () -> getPlayQueueStartingAt(item))
);
}
private PlayQueue getPlayQueueStartingAt(final StreamInfoItem infoItem) {
return getPlayQueue(streamItems -> Math.max(streamItems.indexOf(infoItem), 0));
}
public PlayQueue getPlayQueue(final Function<List<StreamInfoItem>, Integer> index) {
final List<StreamInfoItem> streamItems = infoListAdapter.getItemsList().stream()
.filter(StreamInfoItem.class::isInstance)
@ -196,4 +180,10 @@ public class ChannelTabFragment extends BaseListInfoFragment<InfoItem, ChannelTa
public PlayQueue getPlayQueue() {
return getPlayQueue(streamItems -> 0);
}
@Nullable
@Override
protected Function0<PlayQueue> getPlayQueueStartingAt(@NonNull final StreamInfoItem item) {
return () -> getPlayQueue(streamItems -> Math.max(streamItems.indexOf(item), 0));
}
}

View File

@ -3,7 +3,6 @@ package org.schabi.newpipe.fragments.list.playlist;
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
import static org.schabi.newpipe.ui.components.menu.LongPressMenuKt.openLongPressMenuInActivity;
import static org.schabi.newpipe.util.ServiceHelper.getServiceById;
import android.os.Bundle;
@ -46,8 +45,6 @@ import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
import org.schabi.newpipe.ui.components.menu.LongPressAction;
import org.schabi.newpipe.ui.components.menu.LongPressable;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
@ -68,6 +65,7 @@ import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;
import kotlin.jvm.functions.Function0;
public class PlaylistFragment extends BaseListInfoFragment<StreamInfoItem, PlaylistInfo>
implements PlaylistControlViewHolder {
@ -144,19 +142,6 @@ public class PlaylistFragment extends BaseListInfoFragment<StreamInfoItem, Playl
infoListAdapter.setUseMiniVariant(true);
}
private PlayQueue getPlayQueueStartingAt(final StreamInfoItem infoItem) {
return getPlayQueue(Math.max(infoListAdapter.getItemsList().indexOf(infoItem), 0));
}
@Override
protected void showInfoItemDialog(final StreamInfoItem item) {
openLongPressMenuInActivity(
activity,
LongPressable.fromStreamInfoItem(item),
LongPressAction.fromStreamInfoItem(item, () -> getPlayQueueStartingAt(item))
);
}
@Override
public void onCreateOptionsMenu(@NonNull final Menu menu,
@NonNull final MenuInflater inflater) {
@ -361,10 +346,6 @@ public class PlaylistFragment extends BaseListInfoFragment<StreamInfoItem, Playl
PlayButtonHelper.initPlaylistControlClickListener(activity, playlistControlBinding, this);
}
public PlayQueue getPlayQueue() {
return getPlayQueue(0);
}
private PlayQueue getPlayQueue(final int index) {
final List<StreamInfoItem> infoItems = new ArrayList<>();
for (final InfoItem i : infoListAdapter.getItemsList()) {
@ -381,6 +362,17 @@ public class PlaylistFragment extends BaseListInfoFragment<StreamInfoItem, Playl
);
}
@Override
public PlayQueue getPlayQueue() {
return getPlayQueue(0);
}
@Nullable
@Override
protected Function0<PlayQueue> getPlayQueueStartingAt(@NonNull final StreamInfoItem item) {
return () -> getPlayQueue(Math.max(infoListAdapter.getItemsList().indexOf(item), 0));
}
/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/

View File

@ -141,6 +141,14 @@ data class LongPressAction(
)
}
/**
* Instead of queueFromHere, this function could possibly take a
* `() -> List<StreamInfoItem/StreamEntity/...>` plus the `StreamInfoItem/StreamEntity/...`
* that was long-pressed, and take care of searching through the list to find the item
* index, and finally take care of building the queue. It would deduplicate some code in
* fragments, but it's probably not possible to do because of all the different types of
* the items involved.
*/
private fun buildPlayerFromHereActionList(queueFromHere: () -> PlayQueue): List<LongPressAction> {
return listOf(
Type.BackgroundFromHere.buildAction { context ->