mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 07:13:00 +00:00 
			
		
		
		
	Save changes to the database and bugfix
This commit is contained in:
		| @@ -24,6 +24,12 @@ public interface PlaylistLocalItem extends LocalItem { | |||||||
|         final List<PlaylistLocalItem> result = new ArrayList<>( |         final List<PlaylistLocalItem> result = new ArrayList<>( | ||||||
|                 localPlaylists.size() + remotePlaylists.size()); |                 localPlaylists.size() + remotePlaylists.size()); | ||||||
|         final List<PlaylistLocalItem> itemsWithSameIndex = new ArrayList<>(); |         final List<PlaylistLocalItem> itemsWithSameIndex = new ArrayList<>(); | ||||||
|  |  | ||||||
|  |         // The data from database may not be in the displayIndex order | ||||||
|  |         Collections.sort(localPlaylists, | ||||||
|  |                 Comparator.comparingLong(PlaylistMetadataEntry::getDisplayIndex)); | ||||||
|  |         Collections.sort(remotePlaylists, | ||||||
|  |                 Comparator.comparingLong(PlaylistRemoteEntity::getDisplayIndex)); | ||||||
|         int i = 0; |         int i = 0; | ||||||
|         int j = 0; |         int j = 0; | ||||||
|         while (i < localPlaylists.size()) { |         while (i < localPlaylists.size()) { | ||||||
| @@ -41,10 +47,6 @@ public interface PlaylistLocalItem extends LocalItem { | |||||||
|         } |         } | ||||||
|         addItemsWithSameIndex(result, itemsWithSameIndex); |         addItemsWithSameIndex(result, itemsWithSameIndex); | ||||||
|  |  | ||||||
|         // If displayIndex does not match actual index, update displayIndex. |  | ||||||
|         // This may happen when a new list is created with default displayIndex = 0. |  | ||||||
|         // todo: update displayIndex |  | ||||||
|  |  | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -52,8 +54,8 @@ public interface PlaylistLocalItem extends LocalItem { | |||||||
|                         final List<PlaylistLocalItem> itemsWithSameIndex) { |                         final List<PlaylistLocalItem> itemsWithSameIndex) { | ||||||
|         if (!itemsWithSameIndex.isEmpty() |         if (!itemsWithSameIndex.isEmpty() | ||||||
|                 && itemsWithSameIndex.get(0).getDisplayIndex() != item.getDisplayIndex()) { |                 && itemsWithSameIndex.get(0).getDisplayIndex() != item.getDisplayIndex()) { | ||||||
|             // The new item has a different displayIndex, |             // The new item has a different displayIndex, add previous items with same | ||||||
|             // add previous items with same index to the result. |             // index to the result. | ||||||
|             addItemsWithSameIndex(result, itemsWithSameIndex); |             addItemsWithSameIndex(result, itemsWithSameIndex); | ||||||
|             itemsWithSameIndex.clear(); |             itemsWithSameIndex.clear(); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -31,6 +31,10 @@ public interface PlaylistRemoteDAO extends BasicDAO<PlaylistRemoteEntity> { | |||||||
|             + " WHERE " + REMOTE_PLAYLIST_SERVICE_ID + " = :serviceId") |             + " WHERE " + REMOTE_PLAYLIST_SERVICE_ID + " = :serviceId") | ||||||
|     Flowable<List<PlaylistRemoteEntity>> listByService(int serviceId); |     Flowable<List<PlaylistRemoteEntity>> listByService(int serviceId); | ||||||
|  |  | ||||||
|  |     @Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE " | ||||||
|  |             + REMOTE_PLAYLIST_ID + " = :playlistId") | ||||||
|  |     Flowable<List<PlaylistRemoteEntity>> getPlaylist(long playlistId); | ||||||
|  |  | ||||||
|     @Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE " |     @Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE " | ||||||
|             + REMOTE_PLAYLIST_URL + " = :url AND " + REMOTE_PLAYLIST_SERVICE_ID + " = :serviceId") |             + REMOTE_PLAYLIST_URL + " = :url AND " + REMOTE_PLAYLIST_SERVICE_ID + " = :serviceId") | ||||||
|     Flowable<List<PlaylistRemoteEntity>> getPlaylist(long serviceId, String url); |     Flowable<List<PlaylistRemoteEntity>> getPlaylist(long serviceId, String url); | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ package org.schabi.newpipe.database.playlist.model; | |||||||
|  |  | ||||||
| import androidx.room.ColumnInfo; | import androidx.room.ColumnInfo; | ||||||
| import androidx.room.Entity; | import androidx.room.Entity; | ||||||
|  | import androidx.room.Ignore; | ||||||
| import androidx.room.Index; | import androidx.room.Index; | ||||||
| import androidx.room.PrimaryKey; | import androidx.room.PrimaryKey; | ||||||
|  |  | ||||||
| @@ -28,11 +29,12 @@ public class PlaylistEntity { | |||||||
|     private String thumbnailUrl; |     private String thumbnailUrl; | ||||||
|  |  | ||||||
|     @ColumnInfo(name = PLAYLIST_DISPLAY_INDEX) |     @ColumnInfo(name = PLAYLIST_DISPLAY_INDEX) | ||||||
|     private long displayIndex = 0; |     private long displayIndex; | ||||||
|  |  | ||||||
|     public PlaylistEntity(final String name, final String thumbnailUrl) { |     public PlaylistEntity(final String name, final String thumbnailUrl, final long displayIndex) { | ||||||
|         this.name = name; |         this.name = name; | ||||||
|         this.thumbnailUrl = thumbnailUrl; |         this.thumbnailUrl = thumbnailUrl; | ||||||
|  |         this.displayIndex = displayIndex; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public long getUid() { |     public long getUid() { | ||||||
|   | |||||||
| @@ -142,6 +142,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public boolean swapItems(final int fromAdapterPosition, final int toAdapterPosition) { |     public boolean swapItems(final int fromAdapterPosition, final int toAdapterPosition) { | ||||||
|  |         // todo: reuse this code? | ||||||
|         final int actualFrom = adapterOffsetWithoutHeader(fromAdapterPosition); |         final int actualFrom = adapterOffsetWithoutHeader(fromAdapterPosition); | ||||||
|         final int actualTo = adapterOffsetWithoutHeader(toAdapterPosition); |         final int actualTo = adapterOffsetWithoutHeader(toAdapterPosition); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -199,6 +199,13 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL | |||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public void onNext(final List<PlaylistLocalItem> subscriptions) { |             public void onNext(final List<PlaylistLocalItem> subscriptions) { | ||||||
|  |  | ||||||
|  |                 // If displayIndex does not match actual index, update displayIndex. | ||||||
|  |                 // This may happen when a new list is created | ||||||
|  |                 // or on the first run after database update | ||||||
|  |                 // or displayIndex is not continuous for some reason. | ||||||
|  |                 checkDisplayIndexUpdate(subscriptions); | ||||||
|  |  | ||||||
|                 handleResult(subscriptions); |                 handleResult(subscriptions); | ||||||
|                 if (databaseSubscription != null) { |                 if (databaseSubscription != null) { | ||||||
|                     databaseSubscription.request(1); |                     databaseSubscription.request(1); | ||||||
| @@ -212,7 +219,8 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public void onComplete() { } |             public void onComplete() { | ||||||
|  |             } | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -316,5 +324,60 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL | |||||||
|                                 "Changing playlist name"))); |                                 "Changing playlist name"))); | ||||||
|         disposables.add(disposable); |         disposables.add(disposable); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private void changeLocalPlaylistDisplayIndex(final long id, final long displayIndex) { | ||||||
|  |  | ||||||
|  |         if (localPlaylistManager == null) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (DEBUG) { | ||||||
|  |             Log.d(TAG, "Updating local playlist id=[" + id + "] " | ||||||
|  |                     + "with new display_index=[" + displayIndex + "]"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         final Disposable disposable = | ||||||
|  |                 localPlaylistManager.changePlaylistDisplayIndex(id, displayIndex) | ||||||
|  |                         .observeOn(AndroidSchedulers.mainThread()) | ||||||
|  |                         .subscribe(longs -> { /*Do nothing on success*/ }, throwable -> showError( | ||||||
|  |                                 new ErrorInfo(throwable, | ||||||
|  |                                         UserAction.REQUESTED_BOOKMARK, | ||||||
|  |                                         "Changing local playlist display_index"))); | ||||||
|  |         disposables.add(disposable); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void changeRemotePlaylistDisplayIndex(final long id, final long displayIndex) { | ||||||
|  |  | ||||||
|  |         if (remotePlaylistManager == null) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (DEBUG) { | ||||||
|  |             Log.d(TAG, "Updating remote playlist id=[" + id + "] " | ||||||
|  |                     + "with new display_index=[" + displayIndex + "]"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         final Disposable disposable = | ||||||
|  |                 remotePlaylistManager.changePlaylistDisplayIndex(id, displayIndex) | ||||||
|  |                         .observeOn(AndroidSchedulers.mainThread()) | ||||||
|  |                         .subscribe(longs -> { /*Do nothing on success*/ }, throwable -> showError( | ||||||
|  |                                 new ErrorInfo(throwable, | ||||||
|  |                                         UserAction.REQUESTED_BOOKMARK, | ||||||
|  |                                         "Changing remote playlist display_index"))); | ||||||
|  |         disposables.add(disposable); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void checkDisplayIndexUpdate(@NonNull final List<PlaylistLocalItem> result) { | ||||||
|  |         for (int i = 0; i < result.size(); i++) { | ||||||
|  |             final PlaylistLocalItem item = result.get(i); | ||||||
|  |             if (item.getDisplayIndex() != i) { | ||||||
|  |                 if (item instanceof PlaylistMetadataEntry) { | ||||||
|  |                     changeLocalPlaylistDisplayIndex(((PlaylistMetadataEntry) item).uid, i); | ||||||
|  |                 } else if (item instanceof PlaylistRemoteEntity) { | ||||||
|  |                     changeRemotePlaylistDisplayIndex(((PlaylistRemoteEntity) item).getUid(), i); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -40,8 +40,11 @@ public class LocalPlaylistManager { | |||||||
|             return Maybe.empty(); |             return Maybe.empty(); | ||||||
|         } |         } | ||||||
|         final StreamEntity defaultStream = streams.get(0); |         final StreamEntity defaultStream = streams.get(0); | ||||||
|  |  | ||||||
|  |         // Make sure the new playlist is always on the top of bookmark. | ||||||
|  |         // The index will be reassigned to non-negative number in BookmarkFragment. | ||||||
|         final PlaylistEntity newPlaylist = |         final PlaylistEntity newPlaylist = | ||||||
|                 new PlaylistEntity(name, defaultStream.getThumbnailUrl()); |                 new PlaylistEntity(name, defaultStream.getThumbnailUrl(), -1); | ||||||
|  |  | ||||||
|         return Maybe.fromCallable(() -> database.runInTransaction(() -> |         return Maybe.fromCallable(() -> database.runInTransaction(() -> | ||||||
|                 upsertStreams(playlistTable.insert(newPlaylist), streams, 0)) |                 upsertStreams(playlistTable.insert(newPlaylist), streams, 0)) | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import org.schabi.newpipe.extractor.playlist.PlaylistInfo; | |||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| import io.reactivex.rxjava3.core.Flowable; | import io.reactivex.rxjava3.core.Flowable; | ||||||
|  | import io.reactivex.rxjava3.core.Maybe; | ||||||
| import io.reactivex.rxjava3.core.Single; | import io.reactivex.rxjava3.core.Single; | ||||||
| import io.reactivex.rxjava3.schedulers.Schedulers; | import io.reactivex.rxjava3.schedulers.Schedulers; | ||||||
|  |  | ||||||
| @@ -33,6 +34,20 @@ public class RemotePlaylistManager { | |||||||
|                 .subscribeOn(Schedulers.io()); |                 .subscribeOn(Schedulers.io()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public Maybe<Integer> changePlaylistDisplayIndex(final long playlistId, | ||||||
|  |                                                      final long displayIndex) { | ||||||
|  |         return playlistRemoteTable.getPlaylist(playlistId) | ||||||
|  |                 .firstElement() | ||||||
|  |                 .filter(playlistRemoteEntities -> !playlistRemoteEntities.isEmpty()) | ||||||
|  |                 .map(playlistRemoteEntities -> { | ||||||
|  |                     final PlaylistRemoteEntity playlist = playlistRemoteEntities.get(0); | ||||||
|  |                     if (displayIndex != -1) { | ||||||
|  |                         playlist.setDisplayIndex(displayIndex); | ||||||
|  |                     } | ||||||
|  |                     return playlistRemoteTable.update(playlist); | ||||||
|  |                 }).subscribeOn(Schedulers.io()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public Single<Long> onBookmark(final PlaylistInfo playlistInfo) { |     public Single<Long> onBookmark(final PlaylistInfo playlistInfo) { | ||||||
|         return Single.fromCallable(() -> { |         return Single.fromCallable(() -> { | ||||||
|             final PlaylistRemoteEntity playlist = new PlaylistRemoteEntity(playlistInfo); |             final PlaylistRemoteEntity playlist = new PlaylistRemoteEntity(playlistInfo); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 GGAutomaton
					GGAutomaton