Skip to content

Commit 4591c09

Browse files
committed
Apply review
1 parent e1ce3fe commit 4591c09

10 files changed

Lines changed: 123 additions & 141 deletions

File tree

app/src/main/java/org/schabi/newpipe/database/Migrations.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -258,19 +258,19 @@ public void migrate(@NonNull final SupportSQLiteDatabase database) {
258258
+ "(`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "
259259
+ "`name` TEXT, `is_thumbnail_permanent` INTEGER NOT NULL, "
260260
+ "`thumbnail_stream_id` INTEGER NOT NULL, "
261-
+ "`display_index` INTEGER NOT NULL DEFAULT 0)");
261+
+ "`display_index` INTEGER NOT NULL)");
262262
database.execSQL("INSERT INTO `playlists_tmp` "
263-
+ "(`uid`, `name`, `is_thumbnail_permanent`, `thumbnail_stream_id`) "
264-
+ "SELECT `uid`, `name`, `is_thumbnail_permanent`, `thumbnail_stream_id` "
263+
+ "(`uid`, `name`, `is_thumbnail_permanent`, `thumbnail_stream_id`, "
264+
+ "`display_index`) "
265+
+ "SELECT `uid`, `name`, `is_thumbnail_permanent`, `thumbnail_stream_id`, "
266+
+ "-1 "
265267
+ "FROM `playlists`");
266268

267-
// Replace the old table.
269+
// Replace the old table, note that this also removes the index on the name which
270+
// we don't need anymore.
268271
database.execSQL("DROP TABLE `playlists`");
269272
database.execSQL("ALTER TABLE `playlists_tmp` RENAME TO `playlists`");
270273

271-
// Create index on the new table.
272-
database.execSQL("CREATE INDEX `index_playlists_name` ON `playlists` (`name`)");
273-
274274

275275
// Update remote_playlists.
276276
// Create a temp table to initialize display_index.
@@ -285,13 +285,12 @@ public void migrate(@NonNull final SupportSQLiteDatabase database) {
285285
+ "SELECT `uid`, `service_id`, `name`, `url`, `thumbnail_url`, `uploader`, "
286286
+ "`stream_count` FROM `remote_playlists`");
287287

288-
// Replace the old table.
288+
// Replace the old table, note that this also removes the index on the name which
289+
// we don't need anymore.
289290
database.execSQL("DROP TABLE `remote_playlists`");
290291
database.execSQL("ALTER TABLE `remote_playlists_tmp` RENAME TO `remote_playlists`");
291292

292293
// Create index on the new table.
293-
database.execSQL("CREATE INDEX `index_remote_playlists_name` "
294-
+ "ON `remote_playlists` (`name`)");
295294
database.execSQL("CREATE UNIQUE INDEX `index_remote_playlists_service_id_url` "
296295
+ "ON `remote_playlists` (`service_id`, `url`)");
297296

app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistDuplicatesEntry.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class PlaylistDuplicatesEntry extends PlaylistMetadataEntry {
1313
@ColumnInfo(name = PLAYLIST_TIMES_STREAM_IS_CONTAINED)
1414
public final long timesStreamIsContained;
1515

16+
@SuppressWarnings("checkstyle:ParameterNumber")
1617
public PlaylistDuplicatesEntry(final long uid,
1718
final String name,
1819
final String thumbnailUrl,
Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
package org.schabi.newpipe.database.playlist;
22

33
import org.schabi.newpipe.database.LocalItem;
4-
import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity;
5-
6-
import java.util.ArrayList;
7-
import java.util.Collections;
8-
import java.util.Comparator;
9-
import java.util.List;
104

115
public interface PlaylistLocalItem extends LocalItem {
126
String getOrderingName();
@@ -16,72 +10,4 @@ public interface PlaylistLocalItem extends LocalItem {
1610
long getUid();
1711

1812
void setDisplayIndex(long displayIndex);
19-
20-
/**
21-
* Merge localPlaylists and remotePlaylists by the display index.
22-
* If two items have the same display index, sort them in {@code CASE_INSENSITIVE_ORDER}.
23-
*
24-
* @param localPlaylists local playlists
25-
* @param remotePlaylists remote playlists
26-
* @return merged playlists
27-
*/
28-
static List<PlaylistLocalItem> merge(
29-
final List<PlaylistMetadataEntry> localPlaylists,
30-
final List<PlaylistRemoteEntity> remotePlaylists) {
31-
Collections.sort(localPlaylists,
32-
Comparator.comparingLong(PlaylistMetadataEntry::getDisplayIndex));
33-
Collections.sort(remotePlaylists,
34-
Comparator.comparingLong(PlaylistRemoteEntity::getDisplayIndex));
35-
36-
// This algorithm is similar to the merge operation in merge sort.
37-
38-
final List<PlaylistLocalItem> result = new ArrayList<>(
39-
localPlaylists.size() + remotePlaylists.size());
40-
final List<PlaylistLocalItem> itemsWithSameIndex = new ArrayList<>();
41-
42-
int i = 0;
43-
int j = 0;
44-
while (i < localPlaylists.size()) {
45-
while (j < remotePlaylists.size()) {
46-
if (remotePlaylists.get(j).getDisplayIndex()
47-
<= localPlaylists.get(i).getDisplayIndex()) {
48-
addItem(result, remotePlaylists.get(j), itemsWithSameIndex);
49-
j++;
50-
} else {
51-
break;
52-
}
53-
}
54-
addItem(result, localPlaylists.get(i), itemsWithSameIndex);
55-
i++;
56-
}
57-
while (j < remotePlaylists.size()) {
58-
addItem(result, remotePlaylists.get(j), itemsWithSameIndex);
59-
j++;
60-
}
61-
addItemsWithSameIndex(result, itemsWithSameIndex);
62-
63-
return result;
64-
}
65-
66-
static void addItem(final List<PlaylistLocalItem> result, final PlaylistLocalItem item,
67-
final List<PlaylistLocalItem> itemsWithSameIndex) {
68-
if (!itemsWithSameIndex.isEmpty()
69-
&& itemsWithSameIndex.get(0).getDisplayIndex() != item.getDisplayIndex()) {
70-
// The new item has a different display index, add previous items with same
71-
// index to the result.
72-
addItemsWithSameIndex(result, itemsWithSameIndex);
73-
itemsWithSameIndex.clear();
74-
}
75-
itemsWithSameIndex.add(item);
76-
}
77-
78-
static void addItemsWithSameIndex(final List<PlaylistLocalItem> result,
79-
final List<PlaylistLocalItem> itemsWithSameIndex) {
80-
if (itemsWithSameIndex.size() > 1) {
81-
Collections.sort(itemsWithSameIndex,
82-
Comparator.comparing(PlaylistLocalItem::getOrderingName,
83-
Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER)));
84-
}
85-
result.addAll(itemsWithSameIndex);
86-
}
8713
}

app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public interface PlaylistRemoteDAO extends BasicDAO<PlaylistRemoteEntity> {
4242

4343
@Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE
4444
+ " ORDER BY " + REMOTE_PLAYLIST_DISPLAY_INDEX)
45-
Flowable<List<PlaylistRemoteEntity>> getDisplayIndexOrderedPlaylists();
45+
Flowable<List<PlaylistRemoteEntity>> getPlaylists();
4646

4747
@Query("SELECT " + REMOTE_PLAYLIST_ID + " FROM " + REMOTE_PLAYLIST_TABLE
4848
+ " WHERE " + REMOTE_PLAYLIST_URL + " = :url "

app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -92,26 +92,6 @@ default Flowable<List<PlaylistStreamEntity>> listByService(final int serviceId)
9292
+ " ORDER BY " + JOIN_INDEX + " ASC")
9393
Flowable<List<PlaylistStreamEntry>> getOrderedStreamsOf(long playlistId);
9494

95-
@Transaction
96-
@Query("SELECT " + PLAYLIST_ID + ", " + PLAYLIST_NAME + ", "
97-
+ PLAYLIST_THUMBNAIL_PERMANENT + ", " + PLAYLIST_THUMBNAIL_STREAM_ID + ", "
98-
+ PLAYLIST_DISPLAY_INDEX + ", "
99-
100-
+ " CASE WHEN " + PLAYLIST_THUMBNAIL_STREAM_ID + " = "
101-
+ PlaylistEntity.DEFAULT_THUMBNAIL_ID + " THEN " + "'" + DEFAULT_THUMBNAIL + "'"
102-
+ " ELSE (SELECT " + STREAM_THUMBNAIL_URL
103-
+ " FROM " + STREAM_TABLE
104-
+ " WHERE " + STREAM_TABLE + "." + STREAM_ID + " = " + PLAYLIST_THUMBNAIL_STREAM_ID
105-
+ " ) END AS " + PLAYLIST_THUMBNAIL_URL + ", "
106-
107-
+ "COALESCE(COUNT(" + JOIN_PLAYLIST_ID + "), 0) AS " + PLAYLIST_STREAM_COUNT
108-
+ " FROM " + PLAYLIST_TABLE
109-
+ " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE
110-
+ " ON " + PLAYLIST_TABLE + "." + PLAYLIST_ID + " = " + JOIN_PLAYLIST_ID
111-
+ " GROUP BY " + PLAYLIST_ID
112-
+ " ORDER BY " + PLAYLIST_NAME + " COLLATE NOCASE ASC")
113-
Flowable<List<PlaylistMetadataEntry>> getPlaylistMetadata();
114-
11595
@Transaction
11696
@Query("SELECT " + PLAYLIST_ID + ", " + PLAYLIST_NAME + ", "
11797
+ PLAYLIST_THUMBNAIL_PERMANENT + ", " + PLAYLIST_THUMBNAIL_STREAM_ID + ", "
@@ -130,7 +110,7 @@ default Flowable<List<PlaylistStreamEntity>> listByService(final int serviceId)
130110
+ " ON " + PLAYLIST_TABLE + "." + PLAYLIST_ID + " = " + JOIN_PLAYLIST_ID
131111
+ " GROUP BY " + PLAYLIST_ID
132112
+ " ORDER BY " + PLAYLIST_DISPLAY_INDEX)
133-
Flowable<List<PlaylistMetadataEntry>> getDisplayIndexOrderedPlaylistMetadata();
113+
Flowable<List<PlaylistMetadataEntry>> getPlaylistMetadata();
134114

135115
@RewriteQueriesToDropUnusedColumns
136116
@Transaction

app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.schabi.newpipe.local.bookmark;
22

3+
import static org.schabi.newpipe.local.bookmark.MergedPlaylistManager.getMergedOrderedPlaylists;
34
import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout;
45

56
import android.content.DialogInterface;
@@ -47,7 +48,6 @@
4748

4849
import icepick.State;
4950
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
50-
import io.reactivex.rxjava3.core.Flowable;
5151
import io.reactivex.rxjava3.disposables.CompositeDisposable;
5252
import io.reactivex.rxjava3.disposables.Disposable;
5353

@@ -184,9 +184,7 @@ public void startLoading(final boolean forceLoad) {
184184
}
185185
isLoadingComplete.set(false);
186186

187-
Flowable.combineLatest(localPlaylistManager.getDisplayIndexOrderedPlaylists(),
188-
remotePlaylistManager.getDisplayIndexOrderedPlaylists(),
189-
PlaylistLocalItem::merge)
187+
getMergedOrderedPlaylists(localPlaylistManager, remotePlaylistManager)
190188
.onBackpressureLatest()
191189
.observeOn(AndroidSchedulers.mainThread())
192190
.subscribe(getPlaylistsSubscriber());
@@ -400,16 +398,14 @@ public void saveImmediate() {
400398
for (int i = 0; i < items.size(); i++) {
401399
final LocalItem item = items.get(i);
402400

403-
if (item instanceof PlaylistMetadataEntry) {
404-
if (((PlaylistMetadataEntry) item).getDisplayIndex() != i) {
405-
((PlaylistMetadataEntry) item).setDisplayIndex(i);
406-
localItemsUpdate.add((PlaylistMetadataEntry) item);
407-
}
408-
} else if (item instanceof PlaylistRemoteEntity) {
409-
if (((PlaylistRemoteEntity) item).getDisplayIndex() != i) {
410-
((PlaylistRemoteEntity) item).setDisplayIndex(i);
411-
remoteItemsUpdate.add((PlaylistRemoteEntity) item);
412-
}
401+
if (item instanceof PlaylistMetadataEntry
402+
&& ((PlaylistMetadataEntry) item).getDisplayIndex() != i) {
403+
((PlaylistMetadataEntry) item).setDisplayIndex(i);
404+
localItemsUpdate.add((PlaylistMetadataEntry) item);
405+
} else if (item instanceof PlaylistRemoteEntity
406+
&& ((PlaylistRemoteEntity) item).getDisplayIndex() != i) {
407+
((PlaylistRemoteEntity) item).setDisplayIndex(i);
408+
remoteItemsUpdate.add((PlaylistRemoteEntity) item);
413409
}
414410
}
415411

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package org.schabi.newpipe.local.bookmark;
2+
3+
import org.schabi.newpipe.database.playlist.PlaylistLocalItem;
4+
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
5+
import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity;
6+
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
7+
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
8+
9+
import java.util.ArrayList;
10+
import java.util.Collections;
11+
import java.util.Comparator;
12+
import java.util.List;
13+
14+
import io.reactivex.rxjava3.core.Flowable;
15+
16+
/**
17+
* Takes care of remote and local playlists at once, hence "merged".
18+
*/
19+
public final class MergedPlaylistManager {
20+
21+
private MergedPlaylistManager() {
22+
}
23+
24+
public static Flowable<List<PlaylistLocalItem>> getMergedOrderedPlaylists(
25+
final LocalPlaylistManager localPlaylistManager,
26+
final RemotePlaylistManager remotePlaylistManager) {
27+
return Flowable.combineLatest(
28+
localPlaylistManager.getPlaylists(),
29+
remotePlaylistManager.getPlaylists(),
30+
MergedPlaylistManager::merge
31+
);
32+
}
33+
34+
/**
35+
* Merge localPlaylists and remotePlaylists by the display index.
36+
* If two items have the same display index, sort them in {@code CASE_INSENSITIVE_ORDER}.
37+
*
38+
* @param localPlaylists local playlists, already sorted by display index
39+
* @param remotePlaylists remote playlists, already sorted by display index
40+
* @return merged playlists
41+
*/
42+
private static List<PlaylistLocalItem> merge(
43+
final List<PlaylistMetadataEntry> localPlaylists,
44+
final List<PlaylistRemoteEntity> remotePlaylists) {
45+
46+
// This algorithm is similar to the merge operation in merge sort.
47+
final List<PlaylistLocalItem> result = new ArrayList<>(
48+
localPlaylists.size() + remotePlaylists.size());
49+
final List<PlaylistLocalItem> itemsWithSameIndex = new ArrayList<>();
50+
51+
int i = 0;
52+
int j = 0;
53+
while (i < localPlaylists.size()) {
54+
while (j < remotePlaylists.size()) {
55+
if (remotePlaylists.get(j).getDisplayIndex()
56+
<= localPlaylists.get(i).getDisplayIndex()) {
57+
addItem(result, remotePlaylists.get(j), itemsWithSameIndex);
58+
j++;
59+
} else {
60+
break;
61+
}
62+
}
63+
addItem(result, localPlaylists.get(i), itemsWithSameIndex);
64+
i++;
65+
}
66+
while (j < remotePlaylists.size()) {
67+
addItem(result, remotePlaylists.get(j), itemsWithSameIndex);
68+
j++;
69+
}
70+
addItemsWithSameIndex(result, itemsWithSameIndex);
71+
72+
return result;
73+
}
74+
75+
private static void addItem(final List<PlaylistLocalItem> result,
76+
final PlaylistLocalItem item,
77+
final List<PlaylistLocalItem> itemsWithSameIndex) {
78+
if (!itemsWithSameIndex.isEmpty()
79+
&& itemsWithSameIndex.get(0).getDisplayIndex() != item.getDisplayIndex()) {
80+
// The new item has a different display index, add previous items with same
81+
// index to the result.
82+
addItemsWithSameIndex(result, itemsWithSameIndex);
83+
itemsWithSameIndex.clear();
84+
}
85+
itemsWithSameIndex.add(item);
86+
}
87+
88+
private static void addItemsWithSameIndex(final List<PlaylistLocalItem> result,
89+
final List<PlaylistLocalItem> itemsWithSameIndex) {
90+
Collections.sort(itemsWithSameIndex,
91+
Comparator.comparing(PlaylistLocalItem::getOrderingName,
92+
Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER)));
93+
result.addAll(itemsWithSameIndex);
94+
}
95+
}

app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import io.reactivex.rxjava3.core.Completable;
2020
import io.reactivex.rxjava3.core.Flowable;
2121
import io.reactivex.rxjava3.core.Maybe;
22-
import io.reactivex.rxjava3.core.Single;
2322
import io.reactivex.rxjava3.schedulers.Schedulers;
2423

2524
public class LocalPlaylistManager {
@@ -108,10 +107,6 @@ public Completable updatePlaylists(final List<PlaylistMetadataEntry> updateItems
108107
})).subscribeOn(Schedulers.io());
109108
}
110109

111-
public Flowable<List<PlaylistMetadataEntry>> getPlaylists() {
112-
return playlistStreamTable.getPlaylistMetadata().subscribeOn(Schedulers.io());
113-
}
114-
115110
public Flowable<List<PlaylistStreamEntry>> getDistinctPlaylistStreams(final long playlistId) {
116111
return playlistStreamTable
117112
.getStreamsWithoutDuplicates(playlistId).subscribeOn(Schedulers.io());
@@ -129,20 +124,14 @@ public Flowable<List<PlaylistDuplicatesEntry>> getPlaylistDuplicates(final Strin
129124
.subscribeOn(Schedulers.io());
130125
}
131126

132-
public Flowable<List<PlaylistMetadataEntry>> getDisplayIndexOrderedPlaylists() {
133-
return playlistStreamTable.getDisplayIndexOrderedPlaylistMetadata()
134-
.subscribeOn(Schedulers.io());
127+
public Flowable<List<PlaylistMetadataEntry>> getPlaylists() {
128+
return playlistStreamTable.getPlaylistMetadata().subscribeOn(Schedulers.io());
135129
}
136130

137131
public Flowable<List<PlaylistStreamEntry>> getPlaylistStreams(final long playlistId) {
138132
return playlistStreamTable.getOrderedStreamsOf(playlistId).subscribeOn(Schedulers.io());
139133
}
140134

141-
public Single<Integer> deletePlaylist(final long playlistId) {
142-
return Single.fromCallable(() -> playlistTable.deletePlaylist(playlistId))
143-
.subscribeOn(Schedulers.io());
144-
}
145-
146135
public Maybe<Integer> renamePlaylist(final long playlistId, final String name) {
147136
return modifyPlaylist(playlistId, name, THUMBNAIL_ID_LEAVE_UNCHANGED, false, -1);
148137
}

app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,7 @@ public RemotePlaylistManager(final AppDatabase db) {
2323
}
2424

2525
public Flowable<List<PlaylistRemoteEntity>> getPlaylists() {
26-
return playlistRemoteTable.getAll().subscribeOn(Schedulers.io());
27-
}
28-
29-
public Flowable<List<PlaylistRemoteEntity>> getDisplayIndexOrderedPlaylists() {
30-
return playlistRemoteTable.getDisplayIndexOrderedPlaylists().subscribeOn(Schedulers.io());
26+
return playlistRemoteTable.getPlaylists().subscribeOn(Schedulers.io());
3127
}
3228

3329
public Flowable<List<PlaylistRemoteEntity>> getPlaylist(final PlaylistInfo info) {

0 commit comments

Comments
 (0)