From 8fc5fa979db75bff71f4cd3d0f32e6289afe283a Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sat, 3 Dec 2022 09:52:04 +0100 Subject: [PATCH 1/7] Added menu with tappable list items --- .../playlist/model/PlaylistEntity.java | 1 + .../local/bookmark/BookmarkFragment.java | 33 +++++++++++++++++++ .../local/playlist/LocalPlaylistFragment.java | 5 ++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java index 71abf2732..37e79f060 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java @@ -15,6 +15,7 @@ public class PlaylistEntity { public static final String PLAYLIST_ID = "uid"; public static final String PLAYLIST_NAME = "name"; public static final String PLAYLIST_THUMBNAIL_URL = "thumbnail_url"; + //TODO: add field @PrimaryKey(autoGenerate = true) @ColumnInfo(name = PLAYLIST_ID) diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index be7414542..2170f7d97 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.local.bookmark; +import android.content.DialogInterface; import android.os.Bundle; import android.os.Parcelable; import android.text.InputType; @@ -23,6 +24,7 @@ import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity; import org.schabi.newpipe.databinding.DialogEditTextBinding; +import org.schabi.newpipe.databinding.DialogTitleBinding; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.BaseLocalListFragment; @@ -256,6 +258,37 @@ public final class BookmarkFragment extends BaseLocalListFragment { + switch (index) { + case 0: showRenameDialog(selectedItem); + break; + case 1: + break; + case 2: + break; + } + }; + + //TODO add rename dialog + + final AlertDialog.Builder builder = new AlertDialog.Builder(activity); + + builder.setItems(items, action) + .create() + .show(); + } + + private void showRenameDialog(final PlaylistMetadataEntry selectedItem) { final DialogEditTextBinding dialogBinding = DialogEditTextBinding.inflate(getLayoutInflater()); dialogBinding.dialogEditText.setHint(R.string.name); 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 d98ce4121..66e7cbf8f 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 @@ -406,6 +406,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment notWatchedItems = new ArrayList<>(); boolean thumbnailVideoRemoved = false; + //TODO: add blocker here if (removePartiallyWatched) { for (final var playlistItem : playlist) { @@ -590,6 +591,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Date: Wed, 7 Dec 2022 02:32:53 +0100 Subject: [PATCH 2/7] Tried to implement the feature --- .../playlist/model/PlaylistEntity.java | 18 ++++++- .../local/bookmark/BookmarkFragment.java | 53 ++++++++++++------- .../local/dialog/PlaylistAppendDialog.java | 2 +- .../local/playlist/LocalPlaylistFragment.java | 26 +++++---- .../local/playlist/LocalPlaylistManager.java | 18 ++++--- app/src/main/res/values/strings.xml | 2 + 6 files changed, 80 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java index 37e79f060..a04a284da 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java @@ -15,7 +15,7 @@ public class PlaylistEntity { public static final String PLAYLIST_ID = "uid"; public static final String PLAYLIST_NAME = "name"; public static final String PLAYLIST_THUMBNAIL_URL = "thumbnail_url"; - //TODO: add field + public static final String PLAYLIST_THUMBNAIL_SET = "isThumbnailSet"; @PrimaryKey(autoGenerate = true) @ColumnInfo(name = PLAYLIST_ID) @@ -27,9 +27,14 @@ public class PlaylistEntity { @ColumnInfo(name = PLAYLIST_THUMBNAIL_URL) private String thumbnailUrl; - public PlaylistEntity(final String name, final String thumbnailUrl) { + @ColumnInfo(name = PLAYLIST_THUMBNAIL_SET) + private boolean isThumbnailSet; + + public PlaylistEntity(final String name, final String thumbnailUrl, + final boolean isThumbnailSet) { this.name = name; this.thumbnailUrl = thumbnailUrl; + this.isThumbnailSet = isThumbnailSet; } public long getUid() { @@ -55,4 +60,13 @@ public class PlaylistEntity { public void setThumbnailUrl(final String thumbnailUrl) { this.thumbnailUrl = thumbnailUrl; } + + public boolean getIsThumbnailSet() { + return isThumbnailSet; + } + + public void setIsThumbnailSet(final boolean isThumbnailSet) { + this.isThumbnailSet = isThumbnailSet; + } + } diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 2170f7d97..65db40d16 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -8,6 +8,8 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -24,7 +26,6 @@ import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity; import org.schabi.newpipe.databinding.DialogEditTextBinding; -import org.schabi.newpipe.databinding.DialogTitleBinding; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.BaseLocalListFragment; @@ -258,32 +259,51 @@ public final class BookmarkFragment extends BaseLocalListFragment arrayAdapter = new ArrayAdapter<>(getContext(), + android.R.layout.simple_list_item_1) { + @Override + public View getView(final int position, final View convertView, + final ViewGroup parent) { + final View v = super.getView(position, convertView, parent); + final TextView textView = v.findViewById(android.R.id.text1); - final DialogTitleBinding dialogBinding = - DialogTitleBinding.inflate(LayoutInflater.from(requireContext())); + if (!isPlaylistThumbnailSet && position == 2) { + textView.setEnabled(false); + return v; + } - dialogBinding.itemRoot.setVisibility(View.GONE); - dialogBinding.itemTitleView.setVisibility(View.GONE); - dialogBinding.itemAdditionalDetails.setVisibility(View.GONE); - final String[] items = new String[]{"Delete", "Rename", "Thumbnail"}; - final DialogInterface.OnClickListener action = (d, index) -> { + textView.setEnabled(true); + return v; + } + }; + arrayAdapter.addAll(getString(R.string.rename), getString(R.string.delete), + getString(R.string.unset_playlist_thumbnail)); + + // Rename = 0; Delete = 1; Unset Thumbnail = 2 + final DialogInterface.OnClickListener action = (dialog, index) -> { switch (index) { case 0: showRenameDialog(selectedItem); break; case 1: + showDeleteDialog(selectedItem.name, + localPlaylistManager.deletePlaylist(selectedItem.uid)); + dialog.dismiss(); break; case 2: + if (isPlaylistThumbnailSet) { + final String ur = "drawable://" + R.drawable.placeholder_thumbnail_playlist; + localPlaylistManager.changePlaylistThumbnail(selectedItem.uid, ur, + false).observeOn(AndroidSchedulers.mainThread()).subscribe(); + } break; } }; - //TODO add rename dialog - - final AlertDialog.Builder builder = new AlertDialog.Builder(activity); - - builder.setItems(items, action) + builder.setAdapter(arrayAdapter, action) .create() .show(); } @@ -302,11 +322,6 @@ public final class BookmarkFragment extends BaseLocalListFragment { - showDeleteDialog(selectedItem.name, - localPlaylistManager.deletePlaylist(selectedItem.uid)); - dialog.dismiss(); - }) .create() .show(); } 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 3d5d16c39..88dec3911 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 @@ -134,7 +134,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog { if (playlist.thumbnailUrl .equals("drawable://" + R.drawable.placeholder_thumbnail_playlist)) { playlistDisposables.add(manager - .changePlaylistThumbnail(playlist.uid, streams.get(0).getThumbnailUrl()) + .changePlaylistThumbnail(playlist.uid, streams.get(0).getThumbnailUrl(), false) .observeOn(AndroidSchedulers.mainThread()) .subscribe(ignored -> successToast.show())); } 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 66e7cbf8f..78e455c78 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 @@ -405,8 +405,9 @@ public class LocalPlaylistFragment extends BaseLocalListFragment { // Remove Watched, Functionality data final List notWatchedItems = new ArrayList<>(); + final boolean isThumbnailSet = playlistManager + .getIsPlaylistThumbnailSet(playlistId); boolean thumbnailVideoRemoved = false; - //TODO: add blocker here if (removePartiallyWatched) { for (final var playlistItem : playlist) { @@ -415,7 +416,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment successToast.show(), throwable -> showError(new ErrorInfo(throwable, UserAction.REQUESTED_BOOKMARK, @@ -612,8 +612,11 @@ public class LocalPlaylistFragment extends BaseLocalListFragment - changeThumbnailUrl(item.getStreamEntity().getThumbnailUrl())) + changeThumbnailUrl(item.getStreamEntity().getThumbnailUrl(), + true)) .setAction( StreamDialogDefaultEntry.DELETE, (f, i) -> deleteItem(item)) 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 33296aa84..2510b284d 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 @@ -41,7 +41,7 @@ public class LocalPlaylistManager { } final StreamEntity defaultStream = streams.get(0); final PlaylistEntity newPlaylist = - new PlaylistEntity(name, defaultStream.getThumbnailUrl()); + new PlaylistEntity(name, defaultStream.getThumbnailUrl(), false); return Maybe.fromCallable(() -> database.runInTransaction(() -> upsertStreams(playlistTable.insert(newPlaylist), streams, 0)) @@ -96,24 +96,29 @@ public class LocalPlaylistManager { } public Maybe renamePlaylist(final long playlistId, final String name) { - return modifyPlaylist(playlistId, name, null); + return modifyPlaylist(playlistId, name, null, false); } public Maybe changePlaylistThumbnail(final long playlistId, - final String thumbnailUrl) { - return modifyPlaylist(playlistId, null, thumbnailUrl); + final String thumbnailUrl, + final boolean isPermanent) { + return modifyPlaylist(playlistId, null, thumbnailUrl, isPermanent); } public String getPlaylistThumbnail(final long playlistId) { return playlistTable.getPlaylist(playlistId).blockingFirst().get(0).getThumbnailUrl(); } + public boolean getIsPlaylistThumbnailSet(final long playlistId) { + return playlistTable.getPlaylist(playlistId).blockingFirst().get(0).getIsThumbnailSet(); + } + private Maybe modifyPlaylist(final long playlistId, @Nullable final String name, - @Nullable final String thumbnailUrl) { + @Nullable final String thumbnailUrl, + final boolean isPermanent) { return playlistTable.getPlaylist(playlistId) .firstElement() - .filter(playlistEntities -> !playlistEntities.isEmpty()) .map(playlistEntities -> { final PlaylistEntity playlist = playlistEntities.get(0); if (name != null) { @@ -121,6 +126,7 @@ public class LocalPlaylistManager { } if (thumbnailUrl != null) { playlist.setThumbnailUrl(thumbnailUrl); + playlist.setIsThumbnailSet(isPermanent); } return playlistTable.update(playlist); }).subscribeOn(Schedulers.io()); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3fa37155a..b79bb2815 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,6 +7,7 @@ Install Cancel OK + Yes Open in browser Mark as watched Open in popup mode @@ -438,6 +439,7 @@ Mute Unmute Set as playlist thumbnail + Unset thumbnail Bookmark Playlist Remove Bookmark Delete this playlist\? From bf1ebf8733c3d55a8443aa13bf599cbff2fa1981 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Thu, 8 Dec 2022 23:31:20 +0100 Subject: [PATCH 3/7] Fixed some bugs and improved code quality --- .../playlist/dao/PlaylistStreamDAO.java | 10 +++ .../local/bookmark/BookmarkFragment.java | 62 ++++++++++--------- .../local/playlist/LocalPlaylistManager.java | 7 +++ 3 files changed, 51 insertions(+), 28 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 4941d9395..df4ef2e52 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 @@ -25,6 +25,7 @@ import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.JO import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.PLAYLIST_STREAM_JOIN_TABLE; 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.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; @@ -53,6 +54,15 @@ public interface PlaylistStreamDAO extends BasicDAO { + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") Flowable getMaximumIndexOf(long playlistId); + @Query("SELECT CASE WHEN COUNT(*) != 0 then " + STREAM_THUMBNAIL_URL + " ELSE :defaultUrl END" + + " FROM " + STREAM_TABLE + + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE + + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID + + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId " + + " LIMIT 1" + ) + Flowable getAutomaticThumbnailUrl(long playlistId, String defaultUrl); + @RewriteQueriesToDropUnusedColumns @Transaction @Query("SELECT * FROM " + STREAM_TABLE + " INNER JOIN " diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 65db40d16..1ef61bf31 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -259,11 +259,42 @@ public final class BookmarkFragment extends BaseLocalListFragment arrayAdapter = new ArrayAdapter<>(getContext(), + final ArrayAdapter arrayAdapter = getLocalDialogArrayAdapter(isPlaylistThumbnailSet, + unsetThumbnail); + arrayAdapter.addAll(rename, delete, unsetThumbnail); + + final DialogInterface.OnClickListener action = (dialog, index) -> { + if (index == arrayAdapter.getPosition(rename)) { + showRenameDialog(selectedItem); + } else if (index == arrayAdapter.getPosition(delete)) { + showDeleteDialog(selectedItem.name, localPlaylistManager + .deletePlaylist(selectedItem.uid)); + dialog.dismiss(); + } else if (isPlaylistThumbnailSet) { + final String thumbnail_url = localPlaylistManager + .getAutomaticPlaylistThumbnail(selectedItem.uid); + localPlaylistManager.changePlaylistThumbnail(selectedItem.uid, thumbnail_url, false) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(); + } + }; + + builder.setAdapter(arrayAdapter, action) + .create() + .show(); + } + + private ArrayAdapter getLocalDialogArrayAdapter(final boolean isPlaylistThumbnailSet, + final String unsetThumbnail) { + return new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1) { @Override public View getView(final int position, final View convertView, @@ -271,7 +302,8 @@ public final class BookmarkFragment extends BaseLocalListFragment { - switch (index) { - case 0: showRenameDialog(selectedItem); - break; - case 1: - showDeleteDialog(selectedItem.name, - localPlaylistManager.deletePlaylist(selectedItem.uid)); - dialog.dismiss(); - break; - case 2: - if (isPlaylistThumbnailSet) { - final String ur = "drawable://" + R.drawable.placeholder_thumbnail_playlist; - localPlaylistManager.changePlaylistThumbnail(selectedItem.uid, ur, - false).observeOn(AndroidSchedulers.mainThread()).subscribe(); - } - break; - } - }; - - builder.setAdapter(arrayAdapter, action) - .create() - .show(); } private void showRenameDialog(final PlaylistMetadataEntry selectedItem) { 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 2510b284d..8d975241b 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 @@ -2,6 +2,7 @@ package org.schabi.newpipe.local.playlist; import androidx.annotation.Nullable; +import org.schabi.newpipe.R; import org.schabi.newpipe.database.AppDatabase; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; @@ -113,12 +114,18 @@ public class LocalPlaylistManager { return playlistTable.getPlaylist(playlistId).blockingFirst().get(0).getIsThumbnailSet(); } + public String getAutomaticPlaylistThumbnail(final long playlistId) { + final String def = "drawable://" + R.drawable.placeholder_thumbnail_playlist; + return playlistStreamTable.getAutomaticThumbnailUrl(playlistId, def).blockingFirst(); + } + private Maybe modifyPlaylist(final long playlistId, @Nullable final String name, @Nullable final String thumbnailUrl, final boolean isPermanent) { return playlistTable.getPlaylist(playlistId) .firstElement() + .filter(playlistEntities -> !playlistEntities.isEmpty()) .map(playlistEntities -> { final PlaylistEntity playlist = playlistEntities.get(0); if (name != null) { From 1ac62541a8b601c15816065ba5d4a2b8702afa8b Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 9 Dec 2022 12:01:59 +0100 Subject: [PATCH 4/7] Formatting, renaming and small fixes --- .../playlist/model/PlaylistEntity.java | 18 +++++++++--------- .../local/bookmark/BookmarkFragment.java | 16 +++++++--------- .../local/playlist/LocalPlaylistFragment.java | 13 +++++++------ .../local/playlist/LocalPlaylistManager.java | 7 ++++--- app/src/main/res/values/strings.xml | 1 - 5 files changed, 27 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java index a04a284da..051b7c318 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java @@ -15,7 +15,7 @@ public class PlaylistEntity { public static final String PLAYLIST_ID = "uid"; public static final String PLAYLIST_NAME = "name"; public static final String PLAYLIST_THUMBNAIL_URL = "thumbnail_url"; - public static final String PLAYLIST_THUMBNAIL_SET = "isThumbnailSet"; + public static final String PLAYLIST_THUMBNAIL_PERMANENT = "isThumbnailSet"; @PrimaryKey(autoGenerate = true) @ColumnInfo(name = PLAYLIST_ID) @@ -27,14 +27,14 @@ public class PlaylistEntity { @ColumnInfo(name = PLAYLIST_THUMBNAIL_URL) private String thumbnailUrl; - @ColumnInfo(name = PLAYLIST_THUMBNAIL_SET) - private boolean isThumbnailSet; + @ColumnInfo(name = PLAYLIST_THUMBNAIL_PERMANENT) + private boolean isThumbnailPermanent; public PlaylistEntity(final String name, final String thumbnailUrl, - final boolean isThumbnailSet) { + final boolean isThumbnailPermanent) { this.name = name; this.thumbnailUrl = thumbnailUrl; - this.isThumbnailSet = isThumbnailSet; + this.isThumbnailPermanent = isThumbnailPermanent; } public long getUid() { @@ -61,12 +61,12 @@ public class PlaylistEntity { this.thumbnailUrl = thumbnailUrl; } - public boolean getIsThumbnailSet() { - return isThumbnailSet; + public boolean getIsThumbnailPermanent() { + return isThumbnailPermanent; } - public void setIsThumbnailSet(final boolean isThumbnailSet) { - this.isThumbnailSet = isThumbnailSet; + public void setIsThumbnailPermanent(final boolean isThumbnailSet) { + this.isThumbnailPermanent = isThumbnailSet; } } diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 1ef61bf31..8cb544e0b 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -262,12 +262,12 @@ public final class BookmarkFragment extends BaseLocalListFragment arrayAdapter = getLocalDialogArrayAdapter(isPlaylistThumbnailSet, + final ArrayAdapter arrayAdapter = getLocalDialogArrayAdapter(isThumbnailPermanent, unsetThumbnail); arrayAdapter.addAll(rename, delete, unsetThumbnail); @@ -277,11 +277,10 @@ public final class BookmarkFragment extends BaseLocalListFragment getLocalDialogArrayAdapter(final boolean isPlaylistThumbnailSet, final String unsetThumbnail) { - return new ArrayAdapter<>(getContext(), - android.R.layout.simple_list_item_1) { + return new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1) { @Override public View getView(final int position, final View convertView, final ViewGroup parent) { 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 78e455c78..d584ceefb 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 @@ -405,8 +405,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment { // Remove Watched, Functionality data final List notWatchedItems = new ArrayList<>(); - final boolean isThumbnailSet = playlistManager - .getIsPlaylistThumbnailSet(playlistId); + final boolean isThumbnailPermanent = playlistManager + .getIsPlaylistThumbnailPermanent(playlistId); boolean thumbnailVideoRemoved = false; if (removePartiallyWatched) { @@ -416,7 +416,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragmentInstall Cancel OK - Yes Open in browser Mark as watched Open in popup mode From fedc26e3cbbb2b3737c609d75d999e0df6743899 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 9 Dec 2022 22:40:54 +0100 Subject: [PATCH 5/7] Added migration to new database --- .../newpipe/database/DatabaseMigrationTest.kt | 40 ++++++++++++++----- .../org/schabi/newpipe/NewPipeDatabase.java | 4 +- .../schabi/newpipe/database/AppDatabase.java | 4 +- .../schabi/newpipe/database/Migrations.java | 9 +++++ .../playlist/model/PlaylistEntity.java | 2 +- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt b/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt index 28dea13e9..be95c8e27 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt @@ -33,7 +33,8 @@ class DatabaseMigrationTest { @get:Rule val testHelper = MigrationTestHelper( InstrumentationRegistry.getInstrumentation(), - AppDatabase::class.java.canonicalName, FrameworkSQLiteOpenHelperFactory() + AppDatabase::class.java.canonicalName, + FrameworkSQLiteOpenHelperFactory() ) @Test @@ -42,7 +43,8 @@ class DatabaseMigrationTest { databaseInV2.run { insert( - "streams", SQLiteDatabase.CONFLICT_FAIL, + "streams", + SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { put("service_id", DEFAULT_SERVICE_ID) put("url", DEFAULT_URL) @@ -54,14 +56,16 @@ class DatabaseMigrationTest { } ) insert( - "streams", SQLiteDatabase.CONFLICT_FAIL, + "streams", + SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { put("service_id", DEFAULT_SECOND_SERVICE_ID) put("url", DEFAULT_SECOND_URL) } ) insert( - "streams", SQLiteDatabase.CONFLICT_FAIL, + "streams", + SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { put("service_id", DEFAULT_SERVICE_ID) } @@ -70,18 +74,31 @@ class DatabaseMigrationTest { } testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, Migrations.DB_VER_3, - true, Migrations.MIGRATION_2_3 + AppDatabase.DATABASE_NAME, + Migrations.DB_VER_3, + true, + Migrations.MIGRATION_2_3 ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, Migrations.DB_VER_4, - true, Migrations.MIGRATION_3_4 + AppDatabase.DATABASE_NAME, + Migrations.DB_VER_4, + true, + Migrations.MIGRATION_3_4 ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, Migrations.DB_VER_5, - true, Migrations.MIGRATION_4_5 + AppDatabase.DATABASE_NAME, + Migrations.DB_VER_5, + true, + Migrations.MIGRATION_4_5 + ) + + testHelper.runMigrationsAndValidate( + AppDatabase.DATABASE_NAME, + Migrations.DB_VER_6, + true, + Migrations.MIGRATION_5_6 ) val migratedDatabaseV3 = getMigratedDatabase() @@ -121,7 +138,8 @@ class DatabaseMigrationTest { private fun getMigratedDatabase(): AppDatabase { val database: AppDatabase = Room.databaseBuilder( ApplicationProvider.getApplicationContext(), - AppDatabase::class.java, AppDatabase.DATABASE_NAME + AppDatabase::class.java, + AppDatabase.DATABASE_NAME ) .build() testHelper.closeWhenFinished(database) diff --git a/app/src/main/java/org/schabi/newpipe/NewPipeDatabase.java b/app/src/main/java/org/schabi/newpipe/NewPipeDatabase.java index 402d4648d..fc3423994 100644 --- a/app/src/main/java/org/schabi/newpipe/NewPipeDatabase.java +++ b/app/src/main/java/org/schabi/newpipe/NewPipeDatabase.java @@ -5,6 +5,7 @@ import static org.schabi.newpipe.database.Migrations.MIGRATION_1_2; import static org.schabi.newpipe.database.Migrations.MIGRATION_2_3; import static org.schabi.newpipe.database.Migrations.MIGRATION_3_4; import static org.schabi.newpipe.database.Migrations.MIGRATION_4_5; +import static org.schabi.newpipe.database.Migrations.MIGRATION_5_6; import android.content.Context; import android.database.Cursor; @@ -24,7 +25,8 @@ public final class NewPipeDatabase { private static AppDatabase getDatabase(final Context context) { return Room .databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME) - .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5) + .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, + MIGRATION_5_6) .build(); } diff --git a/app/src/main/java/org/schabi/newpipe/database/AppDatabase.java b/app/src/main/java/org/schabi/newpipe/database/AppDatabase.java index 28ddc8184..563e80b17 100644 --- a/app/src/main/java/org/schabi/newpipe/database/AppDatabase.java +++ b/app/src/main/java/org/schabi/newpipe/database/AppDatabase.java @@ -1,6 +1,6 @@ package org.schabi.newpipe.database; -import static org.schabi.newpipe.database.Migrations.DB_VER_5; +import static org.schabi.newpipe.database.Migrations.DB_VER_6; import androidx.room.Database; import androidx.room.RoomDatabase; @@ -38,7 +38,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity; FeedEntity.class, FeedGroupEntity.class, FeedGroupSubscriptionEntity.class, FeedLastUpdatedEntity.class }, - version = DB_VER_5 + version = DB_VER_6 ) public abstract class AppDatabase extends RoomDatabase { public static final String DATABASE_NAME = "newpipe.db"; diff --git a/app/src/main/java/org/schabi/newpipe/database/Migrations.java b/app/src/main/java/org/schabi/newpipe/database/Migrations.java index 7de08442c..e301e3f1f 100644 --- a/app/src/main/java/org/schabi/newpipe/database/Migrations.java +++ b/app/src/main/java/org/schabi/newpipe/database/Migrations.java @@ -23,6 +23,7 @@ public final class Migrations { public static final int DB_VER_3 = 3; public static final int DB_VER_4 = 4; public static final int DB_VER_5 = 5; + public static final int DB_VER_6 = 6; private static final String TAG = Migrations.class.getName(); public static final boolean DEBUG = MainActivity.DEBUG; @@ -188,6 +189,14 @@ public final class Migrations { } }; + public static final Migration MIGRATION_5_6 = new Migration(DB_VER_5, DB_VER_6) { + @Override + public void migrate(@NonNull final SupportSQLiteDatabase database) { + database.execSQL("ALTER TABLE `playlists` ADD COLUMN `is_thumbnail_permanent` " + + "INTEGER NOT NULL DEFAULT 0"); + } + }; + private Migrations() { } } diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java index 051b7c318..086362da2 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java @@ -15,7 +15,7 @@ public class PlaylistEntity { public static final String PLAYLIST_ID = "uid"; public static final String PLAYLIST_NAME = "name"; public static final String PLAYLIST_THUMBNAIL_URL = "thumbnail_url"; - public static final String PLAYLIST_THUMBNAIL_PERMANENT = "isThumbnailSet"; + public static final String PLAYLIST_THUMBNAIL_PERMANENT = "is_thumbnail_permanent"; @PrimaryKey(autoGenerate = true) @ColumnInfo(name = PLAYLIST_ID) From dfd6534a1cd2c733d0ca183415d6a0fac29bd9d3 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sat, 10 Dec 2022 17:32:02 +0100 Subject: [PATCH 6/7] Added "6.json" --- .../6.json | 737 ++++++++++++++++++ 1 file changed, 737 insertions(+) create mode 100644 app/schemas/org.schabi.newpipe.database.AppDatabase/6.json diff --git a/app/schemas/org.schabi.newpipe.database.AppDatabase/6.json b/app/schemas/org.schabi.newpipe.database.AppDatabase/6.json new file mode 100644 index 000000000..ee69363cc --- /dev/null +++ b/app/schemas/org.schabi.newpipe.database.AppDatabase/6.json @@ -0,0 +1,737 @@ +{ + "formatVersion": 1, + "database": { + "version": 6, + "identityHash": "4084aa342aef315dc7b558770a7755a9", + "entities": [ + { + "tableName": "subscriptions", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `service_id` INTEGER NOT NULL, `url` TEXT, `name` TEXT, `avatar_url` TEXT, `subscriber_count` INTEGER, `description` TEXT, `notification_mode` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "serviceId", + "columnName": "service_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "avatarUrl", + "columnName": "avatar_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "subscriberCount", + "columnName": "subscriber_count", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "notificationMode", + "columnName": "notification_mode", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_subscriptions_service_id_url", + "unique": true, + "columnNames": [ + "service_id", + "url" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_subscriptions_service_id_url` ON `${TABLE_NAME}` (`service_id`, `url`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "search_history", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`creation_date` INTEGER, `service_id` INTEGER NOT NULL, `search` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "creationDate", + "columnName": "creation_date", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "serviceId", + "columnName": "service_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "search", + "columnName": "search", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_search_history_search", + "unique": false, + "columnNames": [ + "search" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_search_history_search` ON `${TABLE_NAME}` (`search`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "streams", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `service_id` INTEGER NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `stream_type` TEXT NOT NULL, `duration` INTEGER NOT NULL, `uploader` TEXT NOT NULL, `uploader_url` TEXT, `thumbnail_url` TEXT, `view_count` INTEGER, `textual_upload_date` TEXT, `upload_date` INTEGER, `is_upload_date_approximation` INTEGER)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "serviceId", + "columnName": "service_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "streamType", + "columnName": "stream_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "uploader", + "columnName": "uploader", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "uploaderUrl", + "columnName": "uploader_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailUrl", + "columnName": "thumbnail_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "viewCount", + "columnName": "view_count", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "textualUploadDate", + "columnName": "textual_upload_date", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "uploadDate", + "columnName": "upload_date", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "isUploadDateApproximation", + "columnName": "is_upload_date_approximation", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_streams_service_id_url", + "unique": true, + "columnNames": [ + "service_id", + "url" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_streams_service_id_url` ON `${TABLE_NAME}` (`service_id`, `url`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "stream_history", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`stream_id` INTEGER NOT NULL, `access_date` INTEGER NOT NULL, `repeat_count` INTEGER NOT NULL, PRIMARY KEY(`stream_id`, `access_date`), FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "streamUid", + "columnName": "stream_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "accessDate", + "columnName": "access_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "repeatCount", + "columnName": "repeat_count", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "stream_id", + "access_date" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_stream_history_stream_id", + "unique": false, + "columnNames": [ + "stream_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_stream_history_stream_id` ON `${TABLE_NAME}` (`stream_id`)" + } + ], + "foreignKeys": [ + { + "table": "streams", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "stream_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "stream_state", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`stream_id` INTEGER NOT NULL, `progress_time` INTEGER NOT NULL, PRIMARY KEY(`stream_id`), FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "streamUid", + "columnName": "stream_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "progressMillis", + "columnName": "progress_time", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "stream_id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [ + { + "table": "streams", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "stream_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "playlists", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `thumbnail_url` TEXT, `is_thumbnail_permanent` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailUrl", + "columnName": "thumbnail_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isThumbnailPermanent", + "columnName": "is_thumbnail_permanent", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_playlists_name", + "unique": false, + "columnNames": [ + "name" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_playlists_name` ON `${TABLE_NAME}` (`name`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "playlist_stream_join", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`playlist_id` INTEGER NOT NULL, `stream_id` INTEGER NOT NULL, `join_index` INTEGER NOT NULL, PRIMARY KEY(`playlist_id`, `join_index`), FOREIGN KEY(`playlist_id`) REFERENCES `playlists`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "playlistUid", + "columnName": "playlist_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "streamUid", + "columnName": "stream_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "index", + "columnName": "join_index", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "playlist_id", + "join_index" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_playlist_stream_join_playlist_id_join_index", + "unique": true, + "columnNames": [ + "playlist_id", + "join_index" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_playlist_stream_join_playlist_id_join_index` ON `${TABLE_NAME}` (`playlist_id`, `join_index`)" + }, + { + "name": "index_playlist_stream_join_stream_id", + "unique": false, + "columnNames": [ + "stream_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_playlist_stream_join_stream_id` ON `${TABLE_NAME}` (`stream_id`)" + } + ], + "foreignKeys": [ + { + "table": "playlists", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "playlist_id" + ], + "referencedColumns": [ + "uid" + ] + }, + { + "table": "streams", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "stream_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "remote_playlists", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `service_id` INTEGER NOT NULL, `name` TEXT, `url` TEXT, `thumbnail_url` TEXT, `uploader` TEXT, `stream_count` INTEGER)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "serviceId", + "columnName": "service_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailUrl", + "columnName": "thumbnail_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "uploader", + "columnName": "uploader", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "streamCount", + "columnName": "stream_count", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_remote_playlists_name", + "unique": false, + "columnNames": [ + "name" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_remote_playlists_name` ON `${TABLE_NAME}` (`name`)" + }, + { + "name": "index_remote_playlists_service_id_url", + "unique": true, + "columnNames": [ + "service_id", + "url" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_remote_playlists_service_id_url` ON `${TABLE_NAME}` (`service_id`, `url`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "feed", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`stream_id` INTEGER NOT NULL, `subscription_id` INTEGER NOT NULL, PRIMARY KEY(`stream_id`, `subscription_id`), FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`subscription_id`) REFERENCES `subscriptions`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "streamId", + "columnName": "stream_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subscriptionId", + "columnName": "subscription_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "stream_id", + "subscription_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_feed_subscription_id", + "unique": false, + "columnNames": [ + "subscription_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_feed_subscription_id` ON `${TABLE_NAME}` (`subscription_id`)" + } + ], + "foreignKeys": [ + { + "table": "streams", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "stream_id" + ], + "referencedColumns": [ + "uid" + ] + }, + { + "table": "subscriptions", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "subscription_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "feed_group", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `icon_id` INTEGER NOT NULL, `sort_order` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "icon", + "columnName": "icon_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sortOrder", + "columnName": "sort_order", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_feed_group_sort_order", + "unique": false, + "columnNames": [ + "sort_order" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_feed_group_sort_order` ON `${TABLE_NAME}` (`sort_order`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "feed_group_subscription_join", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`group_id` INTEGER NOT NULL, `subscription_id` INTEGER NOT NULL, PRIMARY KEY(`group_id`, `subscription_id`), FOREIGN KEY(`group_id`) REFERENCES `feed_group`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`subscription_id`) REFERENCES `subscriptions`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "feedGroupId", + "columnName": "group_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subscriptionId", + "columnName": "subscription_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "group_id", + "subscription_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_feed_group_subscription_join_subscription_id", + "unique": false, + "columnNames": [ + "subscription_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_feed_group_subscription_join_subscription_id` ON `${TABLE_NAME}` (`subscription_id`)" + } + ], + "foreignKeys": [ + { + "table": "feed_group", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "group_id" + ], + "referencedColumns": [ + "uid" + ] + }, + { + "table": "subscriptions", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "subscription_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "feed_last_updated", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`subscription_id` INTEGER NOT NULL, `last_updated` INTEGER, PRIMARY KEY(`subscription_id`), FOREIGN KEY(`subscription_id`) REFERENCES `subscriptions`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "subscriptionId", + "columnName": "subscription_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastUpdated", + "columnName": "last_updated", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "subscription_id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [ + { + "table": "subscriptions", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "subscription_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '4084aa342aef315dc7b558770a7755a9')" + ] + } +} \ No newline at end of file From 2679a4bf1e712f82bf6bcb40b4eacd973c7206c7 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Wed, 4 Jan 2023 16:21:16 +0100 Subject: [PATCH 7/7] Removed the "Unset Thumbnail" item if you can't use this feature --- .../local/bookmark/BookmarkFragment.java | 52 ++++++------------- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 8cb544e0b..e2f493a8a 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -8,8 +8,6 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -34,6 +32,7 @@ import org.schabi.newpipe.local.playlist.RemotePlaylistManager; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.OnClickGesture; +import java.util.ArrayList; import java.util.List; import icepick.State; @@ -267,49 +266,30 @@ public final class BookmarkFragment extends BaseLocalListFragment arrayAdapter = getLocalDialogArrayAdapter(isThumbnailPermanent, - unsetThumbnail); - arrayAdapter.addAll(rename, delete, unsetThumbnail); + final ArrayList items = new ArrayList<>(); + items.add(rename); + items.add(delete); + if (isThumbnailPermanent) { + items.add(unsetThumbnail); + } - final DialogInterface.OnClickListener action = (dialog, index) -> { - if (index == arrayAdapter.getPosition(rename)) { + final DialogInterface.OnClickListener action = (d, index) -> { + if (items.get(index).equals(rename)) { showRenameDialog(selectedItem); - } else if (index == arrayAdapter.getPosition(delete)) { - showDeleteDialog(selectedItem.name, localPlaylistManager - .deletePlaylist(selectedItem.uid)); - } else if (isThumbnailPermanent) { + } else if (items.get(index).equals(delete)) { + showDeleteDialog(selectedItem.name, + localPlaylistManager.deletePlaylist(selectedItem.uid)); + } else if (isThumbnailPermanent && items.get(index).equals(unsetThumbnail)) { final String thumbnailUrl = localPlaylistManager .getAutomaticPlaylistThumbnail(selectedItem.uid); - localPlaylistManager.changePlaylistThumbnail(selectedItem.uid, thumbnailUrl, false) + localPlaylistManager + .changePlaylistThumbnail(selectedItem.uid, thumbnailUrl, false) .observeOn(AndroidSchedulers.mainThread()) .subscribe(); } }; - builder.setAdapter(arrayAdapter, action) - .create() - .show(); - } - - private ArrayAdapter getLocalDialogArrayAdapter(final boolean isPlaylistThumbnailSet, - final String unsetThumbnail) { - return new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1) { - @Override - public View getView(final int position, final View convertView, - final ViewGroup parent) { - final View v = super.getView(position, convertView, parent); - final TextView textView = v.findViewById(android.R.id.text1); - - // If the PlaylistThumbnail is not set permanently, the unset option is disabled. - if (!isPlaylistThumbnailSet && textView.getText().equals(unsetThumbnail)) { - textView.setEnabled(false); - return v; - } - - textView.setEnabled(true); - return v; - } - }; + builder.setItems(items.toArray(new String[0]), action).create().show(); } private void showRenameDialog(final PlaylistMetadataEntry selectedItem) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 85f82e60c..dd30aaefa 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -438,7 +438,7 @@ Mute Unmute Set as playlist thumbnail - Unset thumbnail + Unset permanent thumbnail Bookmark Playlist Remove Bookmark Delete this playlist\?