From fdfeac081ad9fe6094582d29a8df72d00e7d2271 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Mon, 5 Dec 2022 00:15:05 +0100 Subject: [PATCH 01/11] Implemented a warning before adding duplicate to playlist. --- .../playlist/dao/PlaylistStreamDAO.java | 11 +++++++ .../local/dialog/PlaylistAppendDialog.java | 32 ++++++++++++++++++- .../local/playlist/LocalPlaylistManager.java | 4 +++ app/src/main/res/values/strings.xml | 3 ++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index 2036dc205..911baf7f3 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -26,6 +26,7 @@ import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.PL import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_ID; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_TABLE; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_THUMBNAIL_URL; +import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_URL; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID_ALIAS; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_STATE_TABLE; @@ -49,6 +50,16 @@ public interface PlaylistStreamDAO extends BasicDAO { + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") void deleteBatch(long playlistId); + @Query("SELECT COALESCE(COUNT(*), 0)" + + " FROM " + STREAM_TABLE + + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE + + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID + + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId " + + " AND " + STREAM_URL + " = :streamURL" + ) + Flowable getDuplicates(long playlistId, String streamURL); + + @Query("SELECT COALESCE(MAX(" + JOIN_INDEX + "), -1)" + " FROM " + PLAYLIST_STREAM_JOIN_TABLE + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 88dec3911..c80e919bf 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.local.dialog; +import android.app.AlertDialog; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -128,6 +129,19 @@ public final class PlaylistAppendDialog extends PlaylistDialog { private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager, @NonNull final PlaylistMetadataEntry playlist, @NonNull final List streams) { + + final int numOfDuplicates = manager.getPlaylistDuplicates(playlist.uid, + streams.get(0).getUrl()).blockingFirst(); + if (numOfDuplicates > 0) { + createDuplicateDialog(numOfDuplicates, manager, playlist, streams); + } else { + addStreamToPlaylist(manager, playlist, streams); + } + } + + private void addStreamToPlaylist(@NonNull final LocalPlaylistManager manager, + @NonNull final PlaylistMetadataEntry playlist, + @NonNull final List streams) { final Toast successToast = Toast.makeText(getContext(), R.string.playlist_add_stream_success, Toast.LENGTH_SHORT); @@ -142,7 +156,23 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistDisposables.add(manager.appendToPlaylist(playlist.uid, streams) .observeOn(AndroidSchedulers.mainThread()) .subscribe(ignored -> successToast.show())); - requireDialog().dismiss(); } + + private void createDuplicateDialog(final int duplicates, + @NonNull final LocalPlaylistManager manager, + @NonNull final PlaylistMetadataEntry playlist, + @NonNull final List streams) { + //TODO: change color + final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); + builder.setTitle(R.string.duplicate_stream_in_playlist_title); + builder.setMessage(getString(R.string.duplicate_stream_in_playlist_description, + duplicates)); + + builder.setPositiveButton(android.R.string.yes, (dialog, i) -> { + addStreamToPlaylist(manager, playlist, streams); + }); + builder.setNeutralButton(R.string.cancel, null); + builder.create().show(); + } } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index 4007d0e09..807c3c051 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -91,6 +91,10 @@ public class LocalPlaylistManager { return playlistStreamTable.getOrderedStreamsOf(playlistId).subscribeOn(Schedulers.io()); } + public Flowable getPlaylistDuplicates(final long playlistId, final String streamURL) { + return playlistStreamTable.getDuplicates(playlistId, streamURL); + } + public Single deletePlaylist(final long playlistId) { return Single.fromCallable(() -> playlistTable.deletePlaylist(playlistId)) .subscribeOn(Schedulers.io()); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c9e0bb492..5b398abd1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -447,6 +447,9 @@ Playlisted Playlist thumbnail changed. Auto-generated (no uploader found) + Duplicated Video Found + The playlist contains this stream + already %d time(s).\nDo you want to add it one more time? No Captions Fit From ac15339911a86399903c9bd974d6632c2b3088b6 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sat, 10 Dec 2022 13:15:49 +0100 Subject: [PATCH 02/11] Started working on a way to show that items are already in a playlist --- .../playlist/dao/PlaylistStreamDAO.java | 8 +++++ .../newpipe/local/LocalItemListAdapter.java | 11 +++++++ .../local/dialog/PlaylistAppendDialog.java | 32 ++++++++++++++++++- .../local/playlist/LocalPlaylistManager.java | 4 +++ .../res/layout/list_playlist_mini_item.xml | 12 +++++++ 5 files changed, 66 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index 911baf7f3..a9719c9fa 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -59,6 +59,14 @@ public interface PlaylistStreamDAO extends BasicDAO { ) Flowable getDuplicates(long playlistId, String streamURL); + @Query("SELECT " + JOIN_PLAYLIST_ID + + " FROM " + STREAM_TABLE + + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE + + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID + + " WHERE " + STREAM_URL + " = :streamURL" + ) + Flowable> getDuplicatePlaylists(String streamURL); + @Query("SELECT COALESCE(MAX(" + JOIN_INDEX + "), -1)" + " FROM " + PLAYLIST_STREAM_JOIN_TABLE diff --git a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java index 05e2fdac0..93ea12b97 100644 --- a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java @@ -11,6 +11,7 @@ import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import org.schabi.newpipe.database.LocalItem; +import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.stream.model.StreamStateEntity; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.holder.LocalItemHolder; @@ -344,6 +345,16 @@ public class LocalItemListAdapter extends RecyclerView.Adapter { final List entities = getStreamEntities(); if (selectedItem instanceof PlaylistMetadataEntry && entities != null) { @@ -123,6 +125,35 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistAdapter.clearStreamItemList(); playlistAdapter.addItems(playlists); playlistRecyclerView.setVisibility(View.VISIBLE); + + final LocalPlaylistManager playlistManager = + new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); + final List duplicateIds = playlistManager.getDuplicatePlaylist(getStreamEntities() + .get(0).getUrl()).blockingFirst(); + + final HashMap map = new HashMap<>(); + for (int i = 0; i < playlists.size(); i++) { + map.put(i, playlists.get(i).uid); + } + + playlistRecyclerView.postDelayed(new Runnable() { + @Override + public void run() { + if (playlistRecyclerView.getAdapter() == null) { + return; + } + final int count = playlistRecyclerView.getAdapter().getItemCount(); + System.out.println(" kasjdflkalk" + playlistRecyclerView.getAdapter() + .getItemId(0)); + for (int i = 0; i < count; i++) { + if (playlistRecyclerView.findViewHolderForAdapterPosition(i) != null + && duplicateIds.contains(playlistAdapter.getItemId(i))) { + playlistRecyclerView.findViewHolderForAdapterPosition(i).itemView + .findViewById(R.id.checkmark2).setVisibility(View.VISIBLE); + } + } + } + }, 1000); } } @@ -163,7 +194,6 @@ public final class PlaylistAppendDialog extends PlaylistDialog { @NonNull final LocalPlaylistManager manager, @NonNull final PlaylistMetadataEntry playlist, @NonNull final List streams) { - //TODO: change color final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); builder.setTitle(R.string.duplicate_stream_in_playlist_title); builder.setMessage(getString(R.string.duplicate_stream_in_playlist_description, diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index 807c3c051..d017eac6c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -95,6 +95,10 @@ public class LocalPlaylistManager { return playlistStreamTable.getDuplicates(playlistId, streamURL); } + public Flowable> getDuplicatePlaylist(final String streamURL) { + return playlistStreamTable.getDuplicatePlaylists(streamURL); + } + public Single deletePlaylist(final long playlistId) { return Single.fromCallable(() -> playlistTable.deletePlaylist(playlistId)) .subscribeOn(Schedulers.io()); diff --git a/app/src/main/res/layout/list_playlist_mini_item.xml b/app/src/main/res/layout/list_playlist_mini_item.xml index a1f70144d..1b7065f23 100644 --- a/app/src/main/res/layout/list_playlist_mini_item.xml +++ b/app/src/main/res/layout/list_playlist_mini_item.xml @@ -1,5 +1,6 @@ + + + Date: Sat, 10 Dec 2022 16:54:46 +0100 Subject: [PATCH 03/11] Continued working on a way to show that items are already in a playlist --- .../newpipe/local/LocalItemListAdapter.java | 2 +- .../local/dialog/PlaylistAppendDialog.java | 62 +++++++++++-------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java index 93ea12b97..ea7bc290d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java @@ -347,7 +347,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter duplicateIds = playlistManager.getDuplicatePlaylist(getStreamEntities() - .get(0).getUrl()).blockingFirst(); + playlistRecyclerView.addOnScrollListener(new DefaultItemListOnScrolledDownListener()); + initDuplicateIndicators(playlistRecyclerView); + } + } - final HashMap map = new HashMap<>(); - for (int i = 0; i < playlists.size(); i++) { - map.put(i, playlists.get(i).uid); + public class DefaultItemListOnScrolledDownListener extends OnScrollBelowItemsListener { + @Override + public void onScrolledDown(final RecyclerView recyclerView) { + showDuplicateIndicators(recyclerView); + } + } + + public void initDuplicateIndicators(@NonNull final RecyclerView view) { + view.postDelayed(new Runnable() { + @Override + public void run() { + showDuplicateIndicators(view); } + }, 50); + } - playlistRecyclerView.postDelayed(new Runnable() { - @Override - public void run() { - if (playlistRecyclerView.getAdapter() == null) { - return; - } - final int count = playlistRecyclerView.getAdapter().getItemCount(); - System.out.println(" kasjdflkalk" + playlistRecyclerView.getAdapter() - .getItemId(0)); - for (int i = 0; i < count; i++) { - if (playlistRecyclerView.findViewHolderForAdapterPosition(i) != null - && duplicateIds.contains(playlistAdapter.getItemId(i))) { - playlistRecyclerView.findViewHolderForAdapterPosition(i).itemView - .findViewById(R.id.checkmark2).setVisibility(View.VISIBLE); - } - } - } - }, 1000); + public void showDuplicateIndicators(final RecyclerView view) { + final LocalPlaylistManager playlistManager = + new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); + final List duplicateIds = playlistManager.getDuplicatePlaylist(getStreamEntities() + .get(0).getUrl()).blockingFirst(); + + if (view.getAdapter() == null) { + return; + } + + final int count = view.getAdapter().getItemCount(); + for (int i = 0; i < count; i++) { + if (view.findViewHolderForAdapterPosition(i) != null + && duplicateIds.contains(playlistAdapter.getItemId(i))) { + view.findViewHolderForAdapterPosition(i).itemView + .findViewById(R.id.checkmark2).setVisibility(View.VISIBLE); + } } } From 8b6e110635a0404a1faea8bba252823fffa49f31 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Mon, 12 Dec 2022 20:12:06 +0100 Subject: [PATCH 04/11] Fixed the functionality, improved performance & general code cleanup --- .../playlist/dao/PlaylistStreamDAO.java | 3 +- .../local/dialog/PlaylistAppendDialog.java | 68 +++++++++++-------- .../local/playlist/LocalPlaylistManager.java | 7 +- app/src/main/res/layout/dialog_playlists.xml | 17 ++++- .../res/layout/list_playlist_mini_item.xml | 12 ---- app/src/main/res/values/strings.xml | 1 + 6 files changed, 60 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index a9719c9fa..27eb34b90 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -57,7 +57,7 @@ public interface PlaylistStreamDAO extends BasicDAO { + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId " + " AND " + STREAM_URL + " = :streamURL" ) - Flowable getDuplicates(long playlistId, String streamURL); + Flowable getDuplicateCount(long playlistId, String streamURL); @Query("SELECT " + JOIN_PLAYLIST_ID + " FROM " + STREAM_TABLE @@ -67,7 +67,6 @@ public interface PlaylistStreamDAO extends BasicDAO { ) Flowable> getDuplicatePlaylists(String streamURL); - @Query("SELECT COALESCE(MAX(" + JOIN_INDEX + "), -1)" + " FROM " + PLAYLIST_STREAM_JOIN_TABLE + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 9616b06b3..5767d6163 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -16,7 +16,6 @@ import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.R; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.stream.model.StreamEntity; -import org.schabi.newpipe.fragments.OnScrollBelowItemsListener; import org.schabi.newpipe.local.LocalItemListAdapter; import org.schabi.newpipe.local.playlist.LocalPlaylistManager; @@ -28,8 +27,12 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable; public final class PlaylistAppendDialog extends PlaylistDialog { private static final String TAG = PlaylistAppendDialog.class.getCanonicalName(); + private static final float DEFAULT_ALPHA = 1f; + private static final float GRAYED_OUT_ALPHA = 0.3f; + private RecyclerView playlistRecyclerView; private LocalItemListAdapter playlistAdapter; + private List duplicateIds; private final CompositeDisposable playlistDisposables = new CompositeDisposable(); @@ -62,6 +65,9 @@ public final class PlaylistAppendDialog extends PlaylistDialog { final LocalPlaylistManager playlistManager = new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); + duplicateIds = playlistManager.getDuplicatePlaylists(getStreamEntities().get(0).getUrl()) + .blockingFirst(); + playlistAdapter = new LocalItemListAdapter(getActivity()); playlistAdapter.setHasStableIds(true); playlistAdapter.setSelectedListener(selectedItem -> { @@ -126,43 +132,43 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistAdapter.addItems(playlists); playlistRecyclerView.setVisibility(View.VISIBLE); - playlistRecyclerView.addOnScrollListener(new DefaultItemListOnScrolledDownListener()); + playlistRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, + final int dy) { + showDuplicateIndicators(recyclerView); + } + }); initDuplicateIndicators(playlistRecyclerView); } } - public class DefaultItemListOnScrolledDownListener extends OnScrollBelowItemsListener { - @Override - public void onScrolledDown(final RecyclerView recyclerView) { - showDuplicateIndicators(recyclerView); + public void initDuplicateIndicators(@NonNull final RecyclerView view) { + showDuplicateIndicators(view); + + if (!duplicateIds.isEmpty()) { + final View indicatorExplanation = getView() + .findViewById(R.id.playlist_duplicate); + indicatorExplanation.setVisibility(View.VISIBLE); } } - public void initDuplicateIndicators(@NonNull final RecyclerView view) { - view.postDelayed(new Runnable() { - @Override - public void run() { - showDuplicateIndicators(view); - } - }, 50); - } - - public void showDuplicateIndicators(final RecyclerView view) { - final LocalPlaylistManager playlistManager = - new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); - final List duplicateIds = playlistManager.getDuplicatePlaylist(getStreamEntities() - .get(0).getUrl()).blockingFirst(); - + public void showDuplicateIndicators(@NonNull final RecyclerView view) { if (view.getAdapter() == null) { return; } final int count = view.getAdapter().getItemCount(); for (int i = 0; i < count; i++) { - if (view.findViewHolderForAdapterPosition(i) != null - && duplicateIds.contains(playlistAdapter.getItemId(i))) { - view.findViewHolderForAdapterPosition(i).itemView - .findViewById(R.id.checkmark2).setVisibility(View.VISIBLE); + + final RecyclerView.ViewHolder viewHolder = view.findViewHolderForAdapterPosition(i); + if (viewHolder != null) { + if (duplicateIds.contains(view.getAdapter().getItemId(i))) { + viewHolder.itemView.setAlpha(GRAYED_OUT_ALPHA); + } else { + viewHolder.itemView.setAlpha(DEFAULT_ALPHA); + } + } } } @@ -171,10 +177,10 @@ public final class PlaylistAppendDialog extends PlaylistDialog { @NonNull final PlaylistMetadataEntry playlist, @NonNull final List streams) { - final int numOfDuplicates = manager.getPlaylistDuplicates(playlist.uid, + final int numberOfDuplicates = manager.getPlaylistDuplicateCount(playlist.uid, streams.get(0).getUrl()).blockingFirst(); - if (numOfDuplicates > 0) { - createDuplicateDialog(numOfDuplicates, manager, playlist, streams); + if (numberOfDuplicates > 0) { + createDuplicateDialog(numberOfDuplicates, manager, playlist, streams); } else { addStreamToPlaylist(manager, playlist, streams); } @@ -197,22 +203,24 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistDisposables.add(manager.appendToPlaylist(playlist.uid, streams) .observeOn(AndroidSchedulers.mainThread()) .subscribe(ignored -> successToast.show())); + requireDialog().dismiss(); } - private void createDuplicateDialog(final int duplicates, + private void createDuplicateDialog(final int numberOfDuplicates, @NonNull final LocalPlaylistManager manager, @NonNull final PlaylistMetadataEntry playlist, @NonNull final List streams) { final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); builder.setTitle(R.string.duplicate_stream_in_playlist_title); builder.setMessage(getString(R.string.duplicate_stream_in_playlist_description, - duplicates)); + numberOfDuplicates)); builder.setPositiveButton(android.R.string.yes, (dialog, i) -> { addStreamToPlaylist(manager, playlist, streams); }); builder.setNeutralButton(R.string.cancel, null); + builder.create().show(); } } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index d017eac6c..eaccb1e71 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -91,11 +91,12 @@ public class LocalPlaylistManager { return playlistStreamTable.getOrderedStreamsOf(playlistId).subscribeOn(Schedulers.io()); } - public Flowable getPlaylistDuplicates(final long playlistId, final String streamURL) { - return playlistStreamTable.getDuplicates(playlistId, streamURL); + public Flowable getPlaylistDuplicateCount(final long playlistId, + final String streamURL) { + return playlistStreamTable.getDuplicateCount(playlistId, streamURL); } - public Flowable> getDuplicatePlaylist(final String streamURL) { + public Flowable> getDuplicatePlaylists(final String streamURL) { return playlistStreamTable.getDuplicatePlaylists(streamURL); } diff --git a/app/src/main/res/layout/dialog_playlists.xml b/app/src/main/res/layout/dialog_playlists.xml index 18b08d93c..5771b400f 100644 --- a/app/src/main/res/layout/dialog_playlists.xml +++ b/app/src/main/res/layout/dialog_playlists.xml @@ -34,11 +34,26 @@ tools:ignore="RtlHardcoded" /> + + diff --git a/app/src/main/res/layout/list_playlist_mini_item.xml b/app/src/main/res/layout/list_playlist_mini_item.xml index 1b7065f23..a1f70144d 100644 --- a/app/src/main/res/layout/list_playlist_mini_item.xml +++ b/app/src/main/res/layout/list_playlist_mini_item.xml @@ -1,6 +1,5 @@ - - - "Loading requested content" New Playlist + The playlists that are grayed out already contain this item. Rename Name Add to playlist From 5fb7b3266b965cd725b0b4f72cb43e3f4427f3d6 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 16 Dec 2022 00:29:22 +0100 Subject: [PATCH 05/11] Removed the duplicate dialog and added another toast option --- .../local/dialog/PlaylistAppendDialog.java | 39 ++++--------------- app/src/main/res/values/strings.xml | 4 +- 2 files changed, 9 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 5767d6163..3414d95ab 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -1,6 +1,5 @@ package org.schabi.newpipe.local.dialog; -import android.app.AlertDialog; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -177,20 +176,15 @@ public final class PlaylistAppendDialog extends PlaylistDialog { @NonNull final PlaylistMetadataEntry playlist, @NonNull final List streams) { - final int numberOfDuplicates = manager.getPlaylistDuplicateCount(playlist.uid, - streams.get(0).getUrl()).blockingFirst(); - if (numberOfDuplicates > 0) { - createDuplicateDialog(numberOfDuplicates, manager, playlist, streams); - } else { - addStreamToPlaylist(manager, playlist, streams); - } - } + final int numOfDuplicates = manager.getPlaylistDuplicateCount(playlist.uid, + streams.get(0).getUrl()).blockingFirst(); + String toastText = getString(R.string.playlist_add_stream_success); - private void addStreamToPlaylist(@NonNull final LocalPlaylistManager manager, - @NonNull final PlaylistMetadataEntry playlist, - @NonNull final List streams) { - final Toast successToast = Toast.makeText(getContext(), - R.string.playlist_add_stream_success, Toast.LENGTH_SHORT); + if (numOfDuplicates > 0) { + toastText = getString(R.string.playlist_add_stream_success_duplicate); + } + + final Toast successToast = Toast.makeText(getContext(), toastText, Toast.LENGTH_SHORT); if (playlist.thumbnailUrl .equals("drawable://" + R.drawable.placeholder_thumbnail_playlist)) { @@ -206,21 +200,4 @@ public final class PlaylistAppendDialog extends PlaylistDialog { requireDialog().dismiss(); } - - private void createDuplicateDialog(final int numberOfDuplicates, - @NonNull final LocalPlaylistManager manager, - @NonNull final PlaylistMetadataEntry playlist, - @NonNull final List streams) { - final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); - builder.setTitle(R.string.duplicate_stream_in_playlist_title); - builder.setMessage(getString(R.string.duplicate_stream_in_playlist_description, - numberOfDuplicates)); - - builder.setPositiveButton(android.R.string.yes, (dialog, i) -> { - addStreamToPlaylist(manager, playlist, streams); - }); - builder.setNeutralButton(R.string.cancel, null); - - builder.create().show(); - } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 70687b8f4..4067381f4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -446,11 +446,9 @@ Delete this playlist\? Playlist created Playlisted + Playlisted duplicate Playlist thumbnail changed. Auto-generated (no uploader found) - Duplicated Video Found - The playlist contains this stream - already %d time(s).\nDo you want to add it one more time? No Captions Fit From b3554a6a49206f35197341308aab26380667af96 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 30 Dec 2022 16:36:33 +0100 Subject: [PATCH 06/11] Added the number of duplicates to the toast text. --- .../org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java | 2 +- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 3414d95ab..85bce7784 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -181,7 +181,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog { String toastText = getString(R.string.playlist_add_stream_success); if (numOfDuplicates > 0) { - toastText = getString(R.string.playlist_add_stream_success_duplicate); + toastText = getString(R.string.playlist_add_stream_success_duplicate, numOfDuplicates); } final Toast successToast = Toast.makeText(getContext(), toastText, Toast.LENGTH_SHORT); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4067381f4..cf4039262 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -446,7 +446,7 @@ Delete this playlist\? Playlist created Playlisted - Playlisted duplicate + Duplicate added %d time(s) Playlist thumbnail changed. Auto-generated (no uploader found) From ef4a6238c88f26e50ba794caa071432a08da66e7 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 14 Jan 2023 18:00:40 +0100 Subject: [PATCH 07/11] See if playlists already contain a stream from db --- .../playlist/PlaylistDuplicatesEntry.java | 24 +++++++ .../playlist/dao/PlaylistStreamDAO.java | 39 +++++----- .../local/dialog/PlaylistAppendDialog.java | 72 ++++--------------- .../local/holder/LocalPlaylistItemHolder.java | 11 +++ .../local/playlist/LocalPlaylistManager.java | 22 +++--- 5 files changed, 84 insertions(+), 84 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistDuplicatesEntry.java diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistDuplicatesEntry.java b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistDuplicatesEntry.java new file mode 100644 index 000000000..0fcb4ced4 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistDuplicatesEntry.java @@ -0,0 +1,24 @@ +package org.schabi.newpipe.database.playlist; + +import androidx.room.ColumnInfo; + +/** + * This class adds a field to {@link PlaylistMetadataEntry} that contains an integer representing + * how many times a specific stream is already contained inside a local playlist. Used to be able + * to grey out playlists which already contain the current stream in the playlist append dialog. + * @see org.schabi.newpipe.local.playlist.LocalPlaylistManager#getPlaylistDuplicates(String) + */ +public class PlaylistDuplicatesEntry extends PlaylistMetadataEntry { + public static final String PLAYLIST_TIMES_STREAM_IS_CONTAINED = "timesStreamIsContained"; + @ColumnInfo(name = PLAYLIST_TIMES_STREAM_IS_CONTAINED) + public final long timesStreamIsContained; + + public PlaylistDuplicatesEntry(final long uid, + final String name, + final String thumbnailUrl, + final long streamCount, + final long timesStreamIsContained) { + super(uid, name, thumbnailUrl, streamCount); + this.timesStreamIsContained = timesStreamIsContained; + } +} diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index 27eb34b90..f173ab0bc 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -6,6 +6,7 @@ import androidx.room.RewriteQueriesToDropUnusedColumns; import androidx.room.Transaction; import org.schabi.newpipe.database.BasicDAO; +import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity; @@ -14,6 +15,7 @@ import java.util.List; import io.reactivex.rxjava3.core.Flowable; +import static org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry.PLAYLIST_TIMES_STREAM_IS_CONTAINED; import static org.schabi.newpipe.database.playlist.PlaylistMetadataEntry.PLAYLIST_STREAM_COUNT; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_ID; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_NAME; @@ -50,23 +52,6 @@ public interface PlaylistStreamDAO extends BasicDAO { + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") void deleteBatch(long playlistId); - @Query("SELECT COALESCE(COUNT(*), 0)" - + " FROM " + STREAM_TABLE - + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE - + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID - + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId " - + " AND " + STREAM_URL + " = :streamURL" - ) - Flowable getDuplicateCount(long playlistId, String streamURL); - - @Query("SELECT " + JOIN_PLAYLIST_ID - + " FROM " + STREAM_TABLE - + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE - + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID - + " WHERE " + STREAM_URL + " = :streamURL" - ) - Flowable> getDuplicatePlaylists(String streamURL); - @Query("SELECT COALESCE(MAX(" + JOIN_INDEX + "), -1)" + " FROM " + PLAYLIST_STREAM_JOIN_TABLE + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") @@ -111,4 +96,24 @@ public interface PlaylistStreamDAO extends BasicDAO { + " GROUP BY " + PLAYLIST_ID + " ORDER BY " + PLAYLIST_NAME + " COLLATE NOCASE ASC") Flowable> getPlaylistMetadata(); + + @Transaction + @Query("SELECT " + PLAYLIST_TABLE + "." + PLAYLIST_ID + ", " + + PLAYLIST_NAME + ", " + + PLAYLIST_TABLE + "." + PLAYLIST_THUMBNAIL_URL + ", " + + "COALESCE(COUNT(" + JOIN_PLAYLIST_ID + "), 0) AS " + PLAYLIST_STREAM_COUNT + ", " + + "COALESCE(SUM(" + STREAM_URL + " = :streamUrl), 0) AS " + + PLAYLIST_TIMES_STREAM_IS_CONTAINED + + + " FROM " + PLAYLIST_TABLE + + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE + + " ON " + PLAYLIST_TABLE + "." + PLAYLIST_ID + " = " + JOIN_PLAYLIST_ID + + + " LEFT JOIN " + STREAM_TABLE + + " ON " + STREAM_TABLE + "." + STREAM_ID + " = " + JOIN_STREAM_ID + + " AND :streamUrl = :streamUrl" + + + " GROUP BY " + JOIN_PLAYLIST_ID + + " ORDER BY " + PLAYLIST_NAME + " COLLATE NOCASE ASC") + Flowable> getPlaylistDuplicatesMetadata(String streamUrl); } diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 85bce7784..79a355f52 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -13,7 +13,7 @@ import androidx.recyclerview.widget.RecyclerView; import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.R; -import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; +import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.local.LocalItemListAdapter; import org.schabi.newpipe.local.playlist.LocalPlaylistManager; @@ -26,12 +26,8 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable; public final class PlaylistAppendDialog extends PlaylistDialog { private static final String TAG = PlaylistAppendDialog.class.getCanonicalName(); - private static final float DEFAULT_ALPHA = 1f; - private static final float GRAYED_OUT_ALPHA = 0.3f; - private RecyclerView playlistRecyclerView; private LocalItemListAdapter playlistAdapter; - private List duplicateIds; private final CompositeDisposable playlistDisposables = new CompositeDisposable(); @@ -64,15 +60,13 @@ public final class PlaylistAppendDialog extends PlaylistDialog { final LocalPlaylistManager playlistManager = new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); - duplicateIds = playlistManager.getDuplicatePlaylists(getStreamEntities().get(0).getUrl()) - .blockingFirst(); - playlistAdapter = new LocalItemListAdapter(getActivity()); playlistAdapter.setHasStableIds(true); playlistAdapter.setSelectedListener(selectedItem -> { final List entities = getStreamEntities(); - if (selectedItem instanceof PlaylistMetadataEntry && entities != null) { - onPlaylistSelected(playlistManager, (PlaylistMetadataEntry) selectedItem, entities); + if (selectedItem instanceof PlaylistDuplicatesEntry && entities != null) { + onPlaylistSelected(playlistManager, + (PlaylistDuplicatesEntry) selectedItem, entities); } }); @@ -83,7 +77,8 @@ public final class PlaylistAppendDialog extends PlaylistDialog { final View newPlaylistButton = view.findViewById(R.id.newPlaylist); newPlaylistButton.setOnClickListener(ignored -> openCreatePlaylistDialog()); - playlistDisposables.add(playlistManager.getPlaylists() + playlistDisposables.add(playlistManager + .getPlaylistDuplicates(getStreamEntities().get(0).getUrl()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::onPlaylistsReceived)); } @@ -125,63 +120,24 @@ public final class PlaylistAppendDialog extends PlaylistDialog { requireDialog().dismiss(); } - private void onPlaylistsReceived(@NonNull final List playlists) { + private void onPlaylistsReceived(@NonNull final List playlists) { if (playlistAdapter != null && playlistRecyclerView != null) { playlistAdapter.clearStreamItemList(); playlistAdapter.addItems(playlists); playlistRecyclerView.setVisibility(View.VISIBLE); - - playlistRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, - final int dy) { - showDuplicateIndicators(recyclerView); - } - }); - initDuplicateIndicators(playlistRecyclerView); - } - } - - public void initDuplicateIndicators(@NonNull final RecyclerView view) { - showDuplicateIndicators(view); - - if (!duplicateIds.isEmpty()) { - final View indicatorExplanation = getView() - .findViewById(R.id.playlist_duplicate); - indicatorExplanation.setVisibility(View.VISIBLE); - } - } - - public void showDuplicateIndicators(@NonNull final RecyclerView view) { - if (view.getAdapter() == null) { - return; - } - - final int count = view.getAdapter().getItemCount(); - for (int i = 0; i < count; i++) { - - final RecyclerView.ViewHolder viewHolder = view.findViewHolderForAdapterPosition(i); - if (viewHolder != null) { - if (duplicateIds.contains(view.getAdapter().getItemId(i))) { - viewHolder.itemView.setAlpha(GRAYED_OUT_ALPHA); - } else { - viewHolder.itemView.setAlpha(DEFAULT_ALPHA); - } - - } } } private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager, - @NonNull final PlaylistMetadataEntry playlist, + @NonNull final PlaylistDuplicatesEntry playlist, @NonNull final List streams) { - final int numOfDuplicates = manager.getPlaylistDuplicateCount(playlist.uid, - streams.get(0).getUrl()).blockingFirst(); - String toastText = getString(R.string.playlist_add_stream_success); - - if (numOfDuplicates > 0) { - toastText = getString(R.string.playlist_add_stream_success_duplicate, numOfDuplicates); + final String toastText; + if (playlist.timesStreamIsContained > 0) { + toastText = getString(R.string.playlist_add_stream_success_duplicate, + playlist.timesStreamIsContained); + } else { + toastText = getString(R.string.playlist_add_stream_success); } final Toast successToast = Toast.makeText(getContext(), toastText, Toast.LENGTH_SHORT); diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java index f8c5176ec..240ca0462 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java @@ -4,6 +4,7 @@ import android.view.View; import android.view.ViewGroup; import org.schabi.newpipe.database.LocalItem; +import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; @@ -13,6 +14,9 @@ import org.schabi.newpipe.util.Localization; import java.time.format.DateTimeFormatter; public class LocalPlaylistItemHolder extends PlaylistItemHolder { + + private static final float GRAYED_OUT_ALPHA = 0.6f; + public LocalPlaylistItemHolder(final LocalItemBuilder infoItemBuilder, final ViewGroup parent) { super(infoItemBuilder, parent); } @@ -38,6 +42,13 @@ public class LocalPlaylistItemHolder extends PlaylistItemHolder { PicassoHelper.loadPlaylistThumbnail(item.thumbnailUrl).into(itemThumbnailView); + if (item instanceof PlaylistDuplicatesEntry + && ((PlaylistDuplicatesEntry) item).timesStreamIsContained > 0) { + itemView.setAlpha(GRAYED_OUT_ALPHA); + } else { + itemView.setAlpha(1.0f); + } + super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter); } } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index eaccb1e71..8ea64f343 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -4,6 +4,7 @@ import androidx.annotation.Nullable; import org.schabi.newpipe.R; import org.schabi.newpipe.database.AppDatabase; +import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; import org.schabi.newpipe.database.playlist.dao.PlaylistDAO; @@ -87,19 +88,22 @@ public class LocalPlaylistManager { return playlistStreamTable.getPlaylistMetadata().subscribeOn(Schedulers.io()); } + /** + * Get playlists with attached information about how many times the provided stream is already + * contained in each playlist. + * + * @param streamUrl the stream url for which to check for duplicates + * @return a list of {@link PlaylistDuplicatesEntry} + */ + public Flowable> getPlaylistDuplicates(final String streamUrl) { + return playlistStreamTable.getPlaylistDuplicatesMetadata(streamUrl) + .subscribeOn(Schedulers.io()); + } + public Flowable> getPlaylistStreams(final long playlistId) { return playlistStreamTable.getOrderedStreamsOf(playlistId).subscribeOn(Schedulers.io()); } - public Flowable getPlaylistDuplicateCount(final long playlistId, - final String streamURL) { - return playlistStreamTable.getDuplicateCount(playlistId, streamURL); - } - - public Flowable> getDuplicatePlaylists(final String streamURL) { - return playlistStreamTable.getDuplicatePlaylists(streamURL); - } - public Single deletePlaylist(final long playlistId) { return Single.fromCallable(() -> playlistTable.deletePlaylist(playlistId)) .subscribeOn(Schedulers.io()); From a69f74f51bf49d0bdbfd83502d0a01ebc1d1752e Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 20 Jan 2023 18:39:16 +0100 Subject: [PATCH 08/11] Add snippet to ensure baseline.profm file is sorted Thanks to obfusk, see https://issuetracker.google.com/issues/231837768 and #6486 --- app/build.gradle | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index 79e07a190..2c0f03e38 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,3 +1,7 @@ +import com.android.tools.profgen.ArtProfileKt +import com.android.tools.profgen.ArtProfileSerializer +import com.android.tools.profgen.DexFile + plugins { id "com.android.application" id "kotlin-android" @@ -308,3 +312,24 @@ static String getGitWorkingBranch() { return "" } } + +project.afterEvaluate { + tasks.compileReleaseArtProfile.doLast { + outputs.files.each { file -> + if (file.toString().endsWith(".profm")) { + println("Sorting ${file} ...") + def version = ArtProfileSerializer.valueOf("METADATA_0_0_2") + def profile = ArtProfileKt.ArtProfile(file) + def keys = new ArrayList(profile.profileData.keySet()) + def sortedData = new LinkedHashMap() + Collections.sort keys, new DexFile.Companion() + keys.each { key -> sortedData[key] = profile.profileData[key] } + new FileOutputStream(file).with { + write(version.magicBytes$profgen) + write(version.versionBytes$profgen) + version.write$profgen(it, sortedData, "") + } + } + } + } +} From c70ce791dbfb659cd45d4a91a5de5a23e9eaa9ac Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 27 Jan 2023 15:37:33 +0100 Subject: [PATCH 09/11] Added the duplicate indicator explanation & removed some unnecessary functions --- .../schabi/newpipe/local/LocalItemListAdapter.java | 11 ----------- .../newpipe/local/dialog/PlaylistAppendDialog.java | 13 ++++++++++++- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java index ea7bc290d..05e2fdac0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java @@ -11,7 +11,6 @@ import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import org.schabi.newpipe.database.LocalItem; -import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.stream.model.StreamStateEntity; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.holder.LocalItemHolder; @@ -345,16 +344,6 @@ public class LocalItemListAdapter extends RecyclerView.Adapter { final List entities = getStreamEntities(); if (selectedItem instanceof PlaylistDuplicatesEntry && entities != null) { @@ -125,8 +124,20 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistAdapter.clearStreamItemList(); playlistAdapter.addItems(playlists); playlistRecyclerView.setVisibility(View.VISIBLE); + setDuplicateIndicatorExplanation(playlists); } } + private void setDuplicateIndicatorExplanation(final List playlists) { + for (final PlaylistDuplicatesEntry entry : playlists) { + if (entry.timesStreamIsContained > 0) { + final View indicatorExplanation = getView() + .findViewById(R.id.playlist_duplicate); + indicatorExplanation.setVisibility(View.VISIBLE); + return; + } + } + + } private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager, @NonNull final PlaylistDuplicatesEntry playlist, From 102975aeb3fabb18f2a87811d51aef463b30c5a0 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 29 Jan 2023 10:32:32 +0100 Subject: [PATCH 10/11] Improve handling playlist duplicate indicator --- .../local/dialog/PlaylistAppendDialog.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index b45f6bd9c..5aeca06ed 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -4,6 +4,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -28,6 +29,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog { private RecyclerView playlistRecyclerView; private LocalItemListAdapter playlistAdapter; + private TextView playlistDuplicateIndicator; private final CompositeDisposable playlistDisposables = new CompositeDisposable(); @@ -73,6 +75,8 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); playlistRecyclerView.setAdapter(playlistAdapter); + playlistDuplicateIndicator = view.findViewById(R.id.playlist_duplicate); + final View newPlaylistButton = view.findViewById(R.id.newPlaylist); newPlaylistButton.setOnClickListener(ignored -> openCreatePlaylistDialog()); @@ -120,23 +124,20 @@ public final class PlaylistAppendDialog extends PlaylistDialog { } private void onPlaylistsReceived(@NonNull final List playlists) { - if (playlistAdapter != null && playlistRecyclerView != null) { + if (playlistAdapter != null + && playlistRecyclerView != null + && playlistDuplicateIndicator != null) { playlistAdapter.clearStreamItemList(); playlistAdapter.addItems(playlists); playlistRecyclerView.setVisibility(View.VISIBLE); - setDuplicateIndicatorExplanation(playlists); + playlistDuplicateIndicator.setVisibility( + anyPlaylistContainsDuplicates(playlists) ? View.VISIBLE : View.GONE); } } - private void setDuplicateIndicatorExplanation(final List playlists) { - for (final PlaylistDuplicatesEntry entry : playlists) { - if (entry.timesStreamIsContained > 0) { - final View indicatorExplanation = getView() - .findViewById(R.id.playlist_duplicate); - indicatorExplanation.setVisibility(View.VISIBLE); - return; - } - } + private boolean anyPlaylistContainsDuplicates(final List playlists) { + return playlists.stream() + .anyMatch(playlist -> playlist.timesStreamIsContained > 0); } private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager, From 711345eff7c46269797de66e61f030cfbc72fa1c Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 29 Jan 2023 10:32:44 +0100 Subject: [PATCH 11/11] Improve playlist duplicate indicator layout --- app/src/main/res/layout/dialog_playlists.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/res/layout/dialog_playlists.xml b/app/src/main/res/layout/dialog_playlists.xml index 5771b400f..ab4691fa9 100644 --- a/app/src/main/res/layout/dialog_playlists.xml +++ b/app/src/main/res/layout/dialog_playlists.xml @@ -37,17 +37,17 @@ + android:gravity="center" + android:text="@string/duplicate_in_playlist" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textSize="13sp" + android:visibility="gone" + tools:text="@tools:sample/lorem[20]" + tools:visibility="visible" />