diff --git a/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java b/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java index 7daf21e6e..c716a2d91 100644 --- a/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java @@ -49,6 +49,13 @@ public abstract class StreamHistoryDAO implements HistoryDAO> getHistory(); + + @Query("SELECT * FROM " + STREAM_TABLE + + " INNER JOIN " + STREAM_HISTORY_TABLE + + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID + + " ORDER BY " + STREAM_ID + " ASC") + public abstract Flowable> getHistorySortedById(); + @Query("SELECT * FROM " + STREAM_HISTORY_TABLE + " WHERE " + JOIN_STREAM_ID + " = :streamId ORDER BY " + STREAM_ACCESS_DATE + " DESC LIMIT 1") @Nullable diff --git a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java index ba90ae05a..96a385ca8 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java @@ -120,6 +120,10 @@ public class HistoryRecordManager { return streamHistoryTable.getHistory().subscribeOn(Schedulers.io()); } + public Flowable> getStreamHistorySortedById() { + return streamHistoryTable.getHistorySortedById().subscribeOn(Schedulers.io()); + } + public Flowable> getStreamStatistics() { return streamHistoryTable.getStatistics().subscribeOn(Schedulers.io()); } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 1b52705b2..edfdc022f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -375,74 +375,54 @@ public class LocalPlaylistFragment extends BaseLocalListFragment playlist) -> { - List localItems = new ArrayList<>(); - boolean thumbnailVideoRemoved = false; - Long removedItemCount = 0l; + HistoryRecordManager recordManager = new HistoryRecordManager(getContext()); + Iterator playlistIter = playlist.iterator(); + Iterator historyIter = recordManager + .getStreamHistorySortedById().blockingFirst().iterator(); - HistoryRecordManager recordManager = new HistoryRecordManager(getContext()); + // already sorted by ^ getStreamHistorySortedById(), binary search can be used + ArrayList historyStreamIds = new ArrayList<>(); + while(historyIter.hasNext()) { + historyStreamIds.add(historyIter.next().getStreamId()); + } - Iterator it_playlist = playlist.iterator(); - PlaylistStreamEntry playlist_item = null; + List notWatchedItems = new ArrayList<>(); + boolean thumbnailVideoRemoved = false; + while(playlistIter.hasNext()) { + PlaylistStreamEntry playlistItem = playlistIter.next(); + int indexInHistory = Collections.binarySearch(historyStreamIds, playlistItem.getStreamId()); - boolean isNonDuplicate; - - Iterator it_history = recordManager.getStreamHistory().blockingFirst().iterator(); - ArrayList history_streamIds = new ArrayList<>(); - - while(it_history.hasNext()) - { - history_streamIds.add(it_history.next().getStreamId()); - } - - while(it_playlist.hasNext()) - { - playlist_item = it_playlist.next(); - isNonDuplicate = true; - - for (long history_id : history_streamIds) { - if (history_id == playlist_item.getStreamId()) { - isNonDuplicate = false; - break; - } - } - - if (isNonDuplicate) { - localItems.add(playlist_item); - } else { - removedItemCount++; - if (!thumbnailVideoRemoved && playlistManager.getPlaylistThumbnail(playlistId).equals(playlist_item.getStreamEntity().getThumbnailUrl())) { - thumbnailVideoRemoved = true; - } - } - } - - return Flowable.just(localItems, removedItemCount, thumbnailVideoRemoved); + if (indexInHistory < 0) { + notWatchedItems.add(playlistItem); + } else if (!thumbnailVideoRemoved && playlistManager.getPlaylistThumbnail(playlistId).equals(playlistItem.getStreamEntity().getThumbnailUrl())) { + thumbnailVideoRemoved = true; } - ) + } + + return Flowable.just(notWatchedItems, thumbnailVideoRemoved); + }) .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - flow -> { - List localItems = (List) flow.blockingFirst(); - Boolean thumbnailVideoRemoved = (Boolean) flow.blockingLast(); + .subscribe(flow -> { + List notWatchedItems = (List) flow.blockingFirst(); + boolean thumbnailVideoRemoved = (Boolean) flow.blockingLast(); - itemListAdapter.clearStreamItemList(); - itemListAdapter.addItems(localItems); - localItems.clear(); + itemListAdapter.clearStreamItemList(); + itemListAdapter.addItems(notWatchedItems); + saveChanges(); - if (thumbnailVideoRemoved) - updateThumbnailUrl(); - int amountOfVideos = itemListAdapter.getItemsList().size(); - setVideoCount(amountOfVideos); + if (thumbnailVideoRemoved) { + updateThumbnailUrl(); + } - saveChanges(); - hideLoading(); + long videoCount = itemListAdapter.getItemsList().size(); + setVideoCount(videoCount); + if (videoCount == 0) { + showEmptyState(); + } - if (amountOfVideos == 0) - showEmptyState(); - }, (@io.reactivex.annotations.NonNull Throwable throwable) -> { - onError(throwable); - } + hideLoading(); + }, this::onError ); }