Changed "Remove Watched":

- Will now execute on the io thread
- Added confirmation dialog
  - Warning the user, and asking if they also want to remove partially watched videos
This commit is contained in:
Grady Clark 2020-04-14 13:15:07 -05:00
parent 92ca1e6e09
commit fe1646caa0
No known key found for this signature in database
GPG key ID: F7AFAC4616D2FF5E
2 changed files with 63 additions and 18 deletions

View file

@ -2,6 +2,7 @@ package org.schabi.newpipe.local.playlist;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.text.TextUtils; import android.text.TextUtils;
@ -29,6 +30,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.database.LocalItem; import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.history.model.StreamHistoryEntry; import org.schabi.newpipe.database.history.model.StreamHistoryEntry;
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.info_list.InfoItemDialog; import org.schabi.newpipe.info_list.InfoItemDialog;
@ -360,7 +362,18 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
public boolean onOptionsItemSelected(final MenuItem item) { public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.menu_item_removeWatched: case R.id.menu_item_removeWatched:
removeWatchedStreams(); android.app.AlertDialog.Builder builder =
new android.app.AlertDialog.Builder(getActivity());
builder.setMessage(R.string.remove_watched_popup_warning)
.setTitle(R.string.remove_watched_popup_title)
.setPositiveButton(R.string.remove_watched_popup_yes,
(DialogInterface d, int id) -> removeWatchedStreams(false))
.setNeutralButton(
R.string.remove_watched_popup_yes_and_partially_watched_videos,
(DialogInterface d, int id) -> removeWatchedStreams(true))
.setNegativeButton(R.string.remove_watched_popup_cancel,
(DialogInterface d, int id) -> d.cancel());
builder.create().show();
break; break;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
@ -368,21 +381,32 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
return true; return true;
} }
public void removeWatchedStreams() { public void removeWatchedStreams(final boolean removePartiallyWatched) {
if (removeWatchedDisposable != null && !removeWatchedDisposable.isDisposed()) { if (removeWatchedDisposable != null && !removeWatchedDisposable.isDisposed()) {
// already running // already running
return; return;
} }
showLoading(); showLoading();
removeWatchedDisposable = Flowable.just( removeWatchedDisposable = Flowable.just(Flowable.just(removePartiallyWatched,
playlistManager.getPlaylistStreams(playlistId).blockingFirst()) playlistManager.getPlaylistStreams(playlistId).blockingFirst()))
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.io())
.map((@NonNull List<PlaylistStreamEntry> playlist) -> { .map(flow -> {
boolean localRemovePartiallyWatched = (boolean) flow.blockingFirst();
List<PlaylistStreamEntry> playlist
= (List<PlaylistStreamEntry>) flow.blockingLast();
HistoryRecordManager recordManager = new HistoryRecordManager(getContext()); HistoryRecordManager recordManager = new HistoryRecordManager(getContext());
Iterator<PlaylistStreamEntry> playlistIter = playlist.iterator(); Iterator<PlaylistStreamEntry> playlistIter = playlist.iterator();
Iterator<StreamHistoryEntry> historyIter = recordManager Iterator<StreamHistoryEntry> historyIter = recordManager
.getStreamHistorySortedById().blockingFirst().iterator(); .getStreamHistorySortedById().blockingFirst().iterator();
List<PlaylistStreamEntry> notWatchedItems = new ArrayList<>();
Iterator<StreamStateEntity> streamStatesIter = null;
boolean thumbnailVideoRemoved = false;
if (!localRemovePartiallyWatched) {
streamStatesIter = recordManager.loadLocalStreamStateBatch(playlist)
.blockingGet().iterator();
}
// already sorted by ^ getStreamHistorySortedById(), binary search can be used // already sorted by ^ getStreamHistorySortedById(), binary search can be used
ArrayList<Long> historyStreamIds = new ArrayList<>(); ArrayList<Long> historyStreamIds = new ArrayList<>();
@ -390,19 +414,35 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
historyStreamIds.add(historyIter.next().getStreamId()); historyStreamIds.add(historyIter.next().getStreamId());
} }
List<PlaylistStreamEntry> notWatchedItems = new ArrayList<>(); if (localRemovePartiallyWatched) {
boolean thumbnailVideoRemoved = false; while (playlistIter.hasNext()) {
while (playlistIter.hasNext()) { PlaylistStreamEntry playlistItem = playlistIter.next();
PlaylistStreamEntry playlistItem = playlistIter.next(); int indexInHistory = Collections.binarySearch(historyStreamIds,
int indexInHistory = Collections.binarySearch(historyStreamIds, playlistItem.getStreamId());
playlistItem.getStreamId());
if (indexInHistory < 0) { if (indexInHistory < 0) {
notWatchedItems.add(playlistItem); notWatchedItems.add(playlistItem);
} else if (!thumbnailVideoRemoved } else if (!thumbnailVideoRemoved
&& playlistManager.getPlaylistThumbnail(playlistId) && playlistManager.getPlaylistThumbnail(playlistId)
.equals(playlistItem.getStreamEntity().getThumbnailUrl())) { .equals(playlistItem.getStreamEntity().getThumbnailUrl())) {
thumbnailVideoRemoved = true; thumbnailVideoRemoved = true;
}
}
} else {
boolean hasState = false;
while (playlistIter.hasNext()) {
PlaylistStreamEntry playlistItem = playlistIter.next();
int indexInHistory = Collections.binarySearch(historyStreamIds,
playlistItem.getStreamId());
hasState = streamStatesIter.next() != null;
if (indexInHistory < 0 || hasState) {
notWatchedItems.add(playlistItem);
} else if (!thumbnailVideoRemoved
&& playlistManager.getPlaylistThumbnail(playlistId)
.equals(playlistItem.getStreamEntity().getThumbnailUrl())) {
thumbnailVideoRemoved = true;
}
} }
} }

View file

@ -594,6 +594,11 @@
<string name="app_language_title">App language</string> <string name="app_language_title">App language</string>
<string name="systems_language">System default</string> <string name="systems_language">System default</string>
<string name="remove_watched">Remove watched</string> <string name="remove_watched">Remove watched</string>
<string name="remove_watched_popup_title">Remove watched videos?</string>
<string name="remove_watched_popup_warning">"Videos that have been watched\nbefore and after being added to the playlist will be removed.\nAre you sure? This cannot be undone!</string>
<string name="remove_watched_popup_yes">Yes</string>
<string name="remove_watched_popup_cancel">Cancel</string>
<string name="remove_watched_popup_yes_and_partially_watched_videos">Yes, and partially watched videos</string>
<string name="new_seek_duration_toast">Due to ExoPlayer constraints the seek duration was set to %d seconds</string> <string name="new_seek_duration_toast">Due to ExoPlayer constraints the seek duration was set to %d seconds</string>
<!-- Time duration plurals --> <!-- Time duration plurals -->
<plurals name="seconds"> <plurals name="seconds">