diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java index 486350fc9..e2f2c8b08 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java @@ -71,6 +71,14 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { info.getUploaderName(), info.getStreamCount()); } + @Ignore + public boolean isIdenticalTo(final PlaylistInfo info) { + return getServiceId() == info.getServiceId() && getName().equals(info.getName()) && + getStreamCount() == info.getStreamCount() && getUrl().equals(info.getUrl()) && + getThumbnailUrl().equals(info.getThumbnailUrl()) && + getUploader().equals(info.getUploaderName()); + } + public long getUid() { return uid; } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index 68c0a11ff..ab2182a68 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -56,12 +56,14 @@ import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.services.youtube.YoutubeStreamExtractor; import org.schabi.newpipe.extractor.stream.AudioStream; +import org.schabi.newpipe.extractor.stream.Stream; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.fragments.BackPressable; import org.schabi.newpipe.fragments.BaseStateFragment; +import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.StreamItemAdapter; import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper; import org.schabi.newpipe.local.dialog.PlaylistAppendDialog; @@ -128,7 +130,7 @@ public class VideoDetailFragment private StreamInfo currentInfo; private Disposable currentWorker; - private CompositeDisposable disposables = new CompositeDisposable(); + @NonNull private CompositeDisposable disposables = new CompositeDisposable(); private List sortedVideoStreams; private int selectedVideoStreamIndex = -1; @@ -872,10 +874,7 @@ public class VideoDetailFragment if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 16) { openNormalBackgroundPlayer(append); } else { - NavigationHelper.playOnExternalPlayer(activity, - currentInfo.getName(), - currentInfo.getUploaderName(), - audioStream); + startOnExternalPlayer(activity, currentInfo, audioStream); } } @@ -902,10 +901,7 @@ public class VideoDetailFragment if (PreferenceManager.getDefaultSharedPreferences(activity) .getBoolean(this.getString(R.string.use_external_video_player_key), false)) { - NavigationHelper.playOnExternalPlayer(activity, - currentInfo.getName(), - currentInfo.getUploaderName(), - selectedVideoStream); + startOnExternalPlayer(activity, currentInfo, selectedVideoStream); } else { openNormalPlayer(selectedVideoStream); } @@ -949,6 +945,20 @@ public class VideoDetailFragment this.autoPlayEnabled = autoplay; } + private void startOnExternalPlayer(@NonNull final Context context, + @NonNull final StreamInfo info, + @NonNull final Stream selectedStream) { + NavigationHelper.playOnExternalPlayer(context, currentInfo.getName(), + currentInfo.getUploaderName(), selectedStream); + + final HistoryRecordManager recordManager = new HistoryRecordManager(requireContext()); + disposables.add(recordManager.onViewed(info).onErrorComplete() + .subscribe( + ignored -> {/* successful */}, + error -> Log.e(TAG, "Register view failure: ", error) + )); + } + @Nullable private VideoStream getSelectedVideoStream() { return sortedVideoStreams != null ? sortedVideoStreams.get(selectedVideoStreamIndex) : null; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 0498c95c5..3481805a8 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -29,8 +29,8 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; -import org.schabi.newpipe.local.playlist.RemotePlaylistManager; import org.schabi.newpipe.info_list.InfoItemDialog; +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.player.playqueue.SinglePlayQueue; @@ -44,6 +44,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import io.reactivex.Flowable; import io.reactivex.Single; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; @@ -93,7 +94,8 @@ public class PlaylistFragment extends BaseListInfoFragment { super.onCreate(savedInstanceState); disposables = new CompositeDisposable(); isBookmarkButtonReady = new AtomicBoolean(false); - remotePlaylistManager = new RemotePlaylistManager(NewPipeDatabase.getInstance(getContext())); + remotePlaylistManager = new RemotePlaylistManager(NewPipeDatabase.getInstance( + requireContext())); } @Override @@ -281,14 +283,11 @@ public class PlaylistFragment extends BaseListInfoFragment { } remotePlaylistManager.getPlaylist(result) + .flatMap(lists -> getUpdateProcessor(lists, result), (lists, id) -> lists) .onBackpressureLatest() .observeOn(AndroidSchedulers.mainThread()) .subscribe(getPlaylistBookmarkSubscriber()); - remotePlaylistManager.onUpdate(result) - .subscribeOn(AndroidSchedulers.mainThread()) - .subscribe(integer -> {/* Do nothing*/}, this::onError); - headerPlayAllButton.setOnClickListener(view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue())); headerPopupButton.setOnClickListener(view -> @@ -344,6 +343,17 @@ public class PlaylistFragment extends BaseListInfoFragment { // Utils //////////////////////////////////////////////////////////////////////////*/ + private Flowable getUpdateProcessor(@NonNull List playlists, + @NonNull PlaylistInfo result) { + final Flowable noItemToUpdate = Flowable.just(/*noItemToUpdate=*/-1); + if (playlists.isEmpty()) return noItemToUpdate; + + final PlaylistRemoteEntity playlistEntity = playlists.get(0); + if (playlistEntity.isIdenticalTo(result)) return noItemToUpdate; + + return remotePlaylistManager.onUpdate(playlists.get(0).getUid(), result).toFlowable(); + } + private Subscriber> getPlaylistBookmarkSubscriber() { return new Subscriber>() { @Override @@ -416,4 +426,4 @@ public class PlaylistFragment extends BaseListInfoFragment { playlistBookmarkButton.setIcon(ThemeHelper.resolveResourceIdFromAttr(activity, iconAttr)); playlistBookmarkButton.setTitle(titleRes); } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java index 526b49c15..1ae8a22a8 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java @@ -40,8 +40,11 @@ public class RemotePlaylistManager { }).subscribeOn(Schedulers.io()); } - public Single onUpdate(final PlaylistInfo playlistInfo) { - return Single.fromCallable(() -> playlistRemoteTable.update(new PlaylistRemoteEntity(playlistInfo))) - .subscribeOn(Schedulers.io()); + public Single onUpdate(final long playlistId, final PlaylistInfo playlistInfo) { + return Single.fromCallable(() -> { + PlaylistRemoteEntity playlist = new PlaylistRemoteEntity(playlistInfo); + playlist.setUid(playlistId); + return playlistRemoteTable.update(playlist); + }).subscribeOn(Schedulers.io()); } }