-Added support for changing local playlist name and thumbnail url.
-Added query to remove stream table orphans. -Added query for retrieving flattened watch history records. -Added holder for local playlist stream info items. -Refactored info item on select listener as on touch gesture.
This commit is contained in:
parent
d98183a471
commit
c3208aa415
19 changed files with 353 additions and 68 deletions
|
|
@ -62,6 +62,7 @@ import org.schabi.newpipe.fragments.local.PlaylistAppendDialog;
|
|||
import org.schabi.newpipe.history.HistoryListener;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.info_list.InfoItemDialog;
|
||||
import org.schabi.newpipe.info_list.OnInfoItemGesture;
|
||||
import org.schabi.newpipe.player.MainVideoPlayer;
|
||||
import org.schabi.newpipe.player.PopupVideoPlayer;
|
||||
import org.schabi.newpipe.player.helper.PlayerHelper;
|
||||
|
|
@ -471,7 +472,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||
@Override
|
||||
protected void initListeners() {
|
||||
super.initListeners();
|
||||
infoItemBuilder.setOnStreamSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<StreamInfoItem>() {
|
||||
infoItemBuilder.setOnStreamSelectedListener(new OnInfoItemGesture<StreamInfoItem>() {
|
||||
@Override
|
||||
public void selected(StreamInfoItem selectedItem) {
|
||||
selectAndLoadVideo(selectedItem.getServiceId(), selectedItem.getUrl(), selectedItem.getName());
|
||||
|
|
|
|||
|
|
@ -3,19 +3,15 @@ package org.schabi.newpipe.fragments.list;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
|
|
@ -24,12 +20,11 @@ import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
|||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.fragments.BaseStateFragment;
|
||||
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.info_list.InfoItemDialog;
|
||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||
import org.schabi.newpipe.info_list.OnInfoItemGesture;
|
||||
import org.schabi.newpipe.playlist.SinglePlayQueue;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.PermissionHelper;
|
||||
import org.schabi.newpipe.util.StateSaver;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -140,7 +135,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
|
|||
@Override
|
||||
protected void initListeners() {
|
||||
super.initListeners();
|
||||
infoListAdapter.setOnStreamSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<StreamInfoItem>() {
|
||||
infoListAdapter.setOnStreamSelectedListener(new OnInfoItemGesture<StreamInfoItem>() {
|
||||
@Override
|
||||
public void selected(StreamInfoItem selectedItem) {
|
||||
onItemSelected(selectedItem);
|
||||
|
|
@ -155,7 +150,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
|
|||
}
|
||||
});
|
||||
|
||||
infoListAdapter.setOnChannelSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<ChannelInfoItem>() {
|
||||
infoListAdapter.setOnChannelSelectedListener(new OnInfoItemGesture<ChannelInfoItem>() {
|
||||
@Override
|
||||
public void selected(ChannelInfoItem selectedItem) {
|
||||
onItemSelected(selectedItem);
|
||||
|
|
@ -163,12 +158,9 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
|
|||
useAsFrontPage?getParentFragment().getFragmentManager():getFragmentManager(),
|
||||
selectedItem.getServiceId(), selectedItem.getUrl(), selectedItem.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void held(ChannelInfoItem selectedItem) {}
|
||||
});
|
||||
|
||||
infoListAdapter.setOnPlaylistSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<PlaylistInfoItem>() {
|
||||
infoListAdapter.setOnPlaylistSelectedListener(new OnInfoItemGesture<PlaylistInfoItem>() {
|
||||
@Override
|
||||
public void selected(PlaylistInfoItem selectedItem) {
|
||||
onItemSelected(selectedItem);
|
||||
|
|
@ -176,9 +168,6 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
|
|||
useAsFrontPage?getParentFragment().getFragmentManager():getFragmentManager(),
|
||||
selectedItem.getServiceId(), selectedItem.getUrl(), selectedItem.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void held(PlaylistInfoItem selectedItem) {}
|
||||
});
|
||||
|
||||
itemsList.clearOnScrollListeners();
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
|
|||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
||||
import org.schabi.newpipe.fragments.BaseStateFragment;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.info_list.InfoItemDialog;
|
||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||
import org.schabi.newpipe.info_list.OnInfoItemGesture;
|
||||
import org.schabi.newpipe.info_list.stored.LocalPlaylistInfoItem;
|
||||
import org.schabi.newpipe.report.UserAction;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
|
|
@ -33,10 +33,8 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import icepick.State;
|
||||
import io.reactivex.Observer;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
|
||||
|
|
@ -143,7 +141,7 @@ public class BookmarkFragment extends BaseStateFragment<List<PlaylistMetadataEnt
|
|||
protected void initListeners() {
|
||||
super.initListeners();
|
||||
|
||||
infoListAdapter.setOnPlaylistSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<PlaylistInfoItem>() {
|
||||
infoListAdapter.setOnPlaylistSelectedListener(new OnInfoItemGesture<PlaylistInfoItem>() {
|
||||
@Override
|
||||
public void selected(PlaylistInfoItem selectedItem) {
|
||||
// Requires the parent fragment to find holder for fragment replacement
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import org.schabi.newpipe.database.stream.model.StreamEntity;
|
|||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.fragments.list.BaseListFragment;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.info_list.InfoItemDialog;
|
||||
import org.schabi.newpipe.info_list.OnInfoItemGesture;
|
||||
import org.schabi.newpipe.playlist.PlayQueue;
|
||||
import org.schabi.newpipe.playlist.SinglePlayQueue;
|
||||
import org.schabi.newpipe.report.UserAction;
|
||||
|
|
@ -141,7 +141,7 @@ public class LocalPlaylistFragment extends BaseListFragment<List<StreamEntity>,
|
|||
protected void initListeners() {
|
||||
super.initListeners();
|
||||
|
||||
infoListAdapter.setOnStreamSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<StreamInfoItem>() {
|
||||
infoListAdapter.setOnStreamSelectedListener(new OnInfoItemGesture<StreamInfoItem>() {
|
||||
@Override
|
||||
public void selected(StreamInfoItem selectedItem) {
|
||||
// Requires the parent fragment to find holder for fragment replacement
|
||||
|
|
@ -219,7 +219,7 @@ public class LocalPlaylistFragment extends BaseListFragment<List<StreamEntity>,
|
|||
super.startLoading(forceLoad);
|
||||
resetFragment();
|
||||
|
||||
playlistManager.getPlaylist(playlistId)
|
||||
playlistManager.getPlaylistStreams(playlistId)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(getPlaylistObserver());
|
||||
}
|
||||
|
|
@ -317,7 +317,7 @@ public class LocalPlaylistFragment extends BaseListFragment<List<StreamEntity>,
|
|||
if (super.onError(exception)) return true;
|
||||
|
||||
onUnrecoverableError(exception, UserAction.SOMETHING_ELSE,
|
||||
"none", "Subscriptions", R.string.general_error);
|
||||
"none", "Local Playlist", R.string.general_error);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package org.schabi.newpipe.fragments.local;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.schabi.newpipe.database.AppDatabase;
|
||||
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
|
||||
import org.schabi.newpipe.database.playlist.dao.PlaylistDAO;
|
||||
|
|
@ -82,7 +84,7 @@ public class LocalPlaylistManager {
|
|||
return playlistStreamTable.getPlaylistMetadata().subscribeOn(Schedulers.io());
|
||||
}
|
||||
|
||||
public Flowable<List<StreamEntity>> getPlaylist(final long playlistId) {
|
||||
public Flowable<List<StreamEntity>> getPlaylistStreams(final long playlistId) {
|
||||
return playlistStreamTable.getOrderedStreamsOf(playlistId).subscribeOn(Schedulers.io());
|
||||
}
|
||||
|
||||
|
|
@ -90,4 +92,28 @@ public class LocalPlaylistManager {
|
|||
return Single.fromCallable(() -> playlistTable.deletePlaylist(playlistId))
|
||||
.subscribeOn(Schedulers.io());
|
||||
}
|
||||
|
||||
public Maybe<Integer> renamePlaylist(final long playlistId, final String name) {
|
||||
return modifyPlaylist(playlistId, name, null);
|
||||
}
|
||||
|
||||
public Maybe<Integer> changePlaylistThumbnail(final long playlistId,
|
||||
final String thumbnailUrl) {
|
||||
return modifyPlaylist(playlistId, null, thumbnailUrl);
|
||||
}
|
||||
|
||||
private Maybe<Integer> modifyPlaylist(final long playlistId,
|
||||
@Nullable final String name,
|
||||
@Nullable final String thumbnailUrl) {
|
||||
return playlistTable.getPlaylist(playlistId)
|
||||
.firstElement()
|
||||
.filter(playlistEntities -> !playlistEntities.isEmpty())
|
||||
.map(playlistEntities -> {
|
||||
PlaylistEntity playlist = playlistEntities.get(0);
|
||||
if (name != null) playlist.setName(name);
|
||||
if (thumbnailUrl != null) playlist.setThumbnailUrl(thumbnailUrl);
|
||||
return playlistTable.update(playlist);
|
||||
}).subscribeOn(Schedulers.io());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import org.schabi.newpipe.extractor.InfoItem;
|
|||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||
import org.schabi.newpipe.info_list.OnInfoItemGesture;
|
||||
import org.schabi.newpipe.info_list.stored.LocalPlaylistInfoItem;
|
||||
import org.schabi.newpipe.playlist.PlayQueueItem;
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
|
|||
|
||||
newPlaylistButton.setOnClickListener(ignored -> openCreatePlaylistDialog());
|
||||
|
||||
playlistAdapter.setOnPlaylistSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<PlaylistInfoItem>() {
|
||||
playlistAdapter.setOnPlaylistSelectedListener(new OnInfoItemGesture<PlaylistInfoItem>() {
|
||||
@Override
|
||||
public void selected(PlaylistInfoItem selectedItem) {
|
||||
if (!(selectedItem instanceof LocalPlaylistInfoItem) || getStreams() == null)
|
||||
|
|
@ -113,9 +113,6 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
|
|||
|
||||
getDialog().dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void held(PlaylistInfoItem selectedItem) {}
|
||||
});
|
||||
|
||||
playlistManager.getPlaylists()
|
||||
|
|
|
|||
|
|
@ -35,8 +35,7 @@ public final class PlaylistCreationDialog extends PlaylistDialog {
|
|||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
if (getStreams() == null) return super.onCreateDialog(savedInstanceState);
|
||||
|
||||
View dialogView = View.inflate(getContext(),
|
||||
R.layout.dialog_create_playlist, null);
|
||||
View dialogView = View.inflate(getContext(), R.layout.dialog_playlist_name, null);
|
||||
EditText nameInput = dialogView.findViewById(R.id.playlist_name);
|
||||
|
||||
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext())
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import org.schabi.newpipe.database.stream.StreamStatisticsEntry;
|
|||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.fragments.list.BaseListFragment;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.info_list.InfoItemDialog;
|
||||
import org.schabi.newpipe.info_list.OnInfoItemGesture;
|
||||
import org.schabi.newpipe.info_list.stored.StreamStatisticsInfoItem;
|
||||
import org.schabi.newpipe.playlist.PlayQueue;
|
||||
import org.schabi.newpipe.playlist.SinglePlayQueue;
|
||||
|
|
@ -127,7 +127,7 @@ public abstract class StatisticsPlaylistFragment
|
|||
protected void initListeners() {
|
||||
super.initListeners();
|
||||
|
||||
infoListAdapter.setOnStreamSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<StreamInfoItem>() {
|
||||
infoListAdapter.setOnStreamSelectedListener(new OnInfoItemGesture<StreamInfoItem>() {
|
||||
@Override
|
||||
public void selected(StreamInfoItem selectedItem) {
|
||||
NavigationHelper.openVideoDetailFragment(getFragmentManager(),
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity;
|
|||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||
import org.schabi.newpipe.fragments.BaseStateFragment;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||
import org.schabi.newpipe.info_list.OnInfoItemGesture;
|
||||
import org.schabi.newpipe.report.UserAction;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
|
||||
|
|
@ -125,24 +125,17 @@ public class SubscriptionFragment extends BaseStateFragment<List<SubscriptionEnt
|
|||
protected void initListeners() {
|
||||
super.initListeners();
|
||||
|
||||
infoListAdapter.setOnChannelSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<ChannelInfoItem>() {
|
||||
infoListAdapter.setOnChannelSelectedListener(new OnInfoItemGesture<ChannelInfoItem>() {
|
||||
@Override
|
||||
public void selected(ChannelInfoItem selectedItem) {
|
||||
// Requires the parent fragment to find holder for fragment replacement
|
||||
NavigationHelper.openChannelFragment(getParentFragment().getFragmentManager(), selectedItem.getServiceId(), selectedItem.url, selectedItem.getName());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void held(ChannelInfoItem selectedItem) {}
|
||||
});
|
||||
|
||||
headerRootLayout.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
NavigationHelper.openWhatsNewFragment(getParentFragment().getFragmentManager());
|
||||
NavigationHelper.openChannelFragment(getParentFragment().getFragmentManager(),
|
||||
selectedItem.getServiceId(), selectedItem.url, selectedItem.getName());
|
||||
}
|
||||
});
|
||||
|
||||
headerRootLayout.setOnClickListener(view ->
|
||||
NavigationHelper.openWhatsNewFragment(getParentFragment().getFragmentManager()));
|
||||
}
|
||||
|
||||
private void resetFragment() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue