mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-30 01:39:28 +01:00
Compare commits
No commits in common. "7f83204b24d7948874a5cad79419d655bb53423f" and "979a4b7c732439b9baf193e71adfae6c87b30f0f" have entirely different histories.
7f83204b24
...
979a4b7c73
4
TODO.md
4
TODO.md
@ -14,10 +14,14 @@
|
|||||||
- [ ] Library list display modes
|
- [ ] Library list display modes
|
||||||
- [ ] Search
|
- [ ] Search
|
||||||
- [ ] Individual "more" results pages
|
- [ ] Individual "more" results pages
|
||||||
|
- [ ] Radio modes
|
||||||
|
- [ ] Artist
|
||||||
- [ ] Now playing gestures
|
- [ ] Now playing gestures
|
||||||
- [ ] Swipe bar/album to skip
|
- [ ] Swipe bar/album to skip
|
||||||
- [ ] Double-tap to seek forward/back (bar only)
|
- [ ] Double-tap to seek forward/back (bar only)
|
||||||
- [ ] Settings
|
- [ ] Settings
|
||||||
|
- [ ] Sources
|
||||||
|
- [ ] Use plaintext password
|
||||||
- [ ] Music
|
- [ ] Music
|
||||||
- [ ] Scrobble
|
- [ ] Scrobble
|
||||||
- [ ] Downloads
|
- [ ] Downloads
|
||||||
|
|||||||
@ -1,19 +1,13 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
import '../../database/database.dart';
|
|
||||||
import '../../models/query.dart';
|
|
||||||
import '../../models/support.dart';
|
|
||||||
import '../../services/audio_service.dart';
|
|
||||||
import '../../state/music.dart';
|
import '../../state/music.dart';
|
||||||
import '../../state/settings.dart';
|
import '../../state/settings.dart';
|
||||||
import '../app_router.dart';
|
import '../app_router.dart';
|
||||||
import '../buttons.dart';
|
|
||||||
import '../images.dart';
|
import '../images.dart';
|
||||||
import '../items.dart';
|
import '../items.dart';
|
||||||
|
|
||||||
@ -33,26 +27,6 @@ class ArtistPage extends HookConsumerWidget {
|
|||||||
final albums = ref.watch(albumsByArtistIdProvider(id));
|
final albums = ref.watch(albumsByArtistIdProvider(id));
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
floatingActionButton: RadioPlayFab(
|
|
||||||
onPressed: () => artist.hasValue
|
|
||||||
? ref.read(audioControlProvider).playRadio(
|
|
||||||
context: QueueContextType.artist,
|
|
||||||
contextId: artist.valueOrNull!.id,
|
|
||||||
query: ListQuery(
|
|
||||||
filters: IList([
|
|
||||||
FilterWith.equals(
|
|
||||||
column: 'artist_id',
|
|
||||||
value: artist.valueOrNull!.id,
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
getSongs: (query) => ref
|
|
||||||
.read(databaseProvider)
|
|
||||||
.songsList(ref.read(sourceIdProvider), query)
|
|
||||||
.get(),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
slivers: [
|
slivers: [
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
|
|||||||
@ -41,7 +41,6 @@ class SourcePage extends HookConsumerWidget {
|
|||||||
label: l.settingsServersFieldsAddress,
|
label: l.settingsServersFieldsAddress,
|
||||||
initialValue: source?.address.toString(),
|
initialValue: source?.address.toString(),
|
||||||
keyboardType: TextInputType.url,
|
keyboardType: TextInputType.url,
|
||||||
autofillHints: const [AutofillHints.url],
|
|
||||||
required: true,
|
required: true,
|
||||||
validator: (value, label) {
|
validator: (value, label) {
|
||||||
if (Uri.tryParse(value!) == null) {
|
if (Uri.tryParse(value!) == null) {
|
||||||
@ -53,14 +52,12 @@ class SourcePage extends HookConsumerWidget {
|
|||||||
final username = LabeledTextField(
|
final username = LabeledTextField(
|
||||||
label: l.settingsServersFieldsUsername,
|
label: l.settingsServersFieldsUsername,
|
||||||
initialValue: source?.username,
|
initialValue: source?.username,
|
||||||
autofillHints: const [AutofillHints.username],
|
|
||||||
required: true,
|
required: true,
|
||||||
);
|
);
|
||||||
final password = LabeledTextField(
|
final password = LabeledTextField(
|
||||||
label: l.settingsServersFieldsPassword,
|
label: l.settingsServersFieldsPassword,
|
||||||
initialValue: source?.password,
|
initialValue: source?.password,
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
autofillHints: const [AutofillHints.password],
|
|
||||||
required: true,
|
required: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -178,7 +175,6 @@ class SourcePage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
body: Form(
|
body: Form(
|
||||||
key: form,
|
key: form,
|
||||||
child: AutofillGroup(
|
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 96 - kToolbarHeight),
|
const SizedBox(height: 96 - kToolbarHeight),
|
||||||
@ -202,7 +198,6 @@ class SourcePage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,7 +208,6 @@ class LabeledTextField extends HookConsumerWidget {
|
|||||||
final bool obscureText;
|
final bool obscureText;
|
||||||
final bool required;
|
final bool required;
|
||||||
final TextInputType? keyboardType;
|
final TextInputType? keyboardType;
|
||||||
final Iterable<String>? autofillHints;
|
|
||||||
final String? Function(String? value, String label)? validator;
|
final String? Function(String? value, String label)? validator;
|
||||||
|
|
||||||
// ignore: prefer_const_constructors_in_immutables
|
// ignore: prefer_const_constructors_in_immutables
|
||||||
@ -224,7 +218,6 @@ class LabeledTextField extends HookConsumerWidget {
|
|||||||
this.obscureText = false,
|
this.obscureText = false,
|
||||||
this.keyboardType,
|
this.keyboardType,
|
||||||
this.validator,
|
this.validator,
|
||||||
this.autofillHints,
|
|
||||||
this.required = false,
|
this.required = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -256,7 +249,6 @@ class LabeledTextField extends HookConsumerWidget {
|
|||||||
controller: _controller,
|
controller: _controller,
|
||||||
obscureText: obscureText,
|
obscureText: obscureText,
|
||||||
keyboardType: keyboardType,
|
keyboardType: keyboardType,
|
||||||
autofillHints: autofillHints,
|
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
String? error;
|
String? error;
|
||||||
|
|
||||||
|
|||||||
@ -17,10 +17,6 @@ import 'converters.dart';
|
|||||||
|
|
||||||
part 'database.g.dart';
|
part 'database.g.dart';
|
||||||
|
|
||||||
// don't exceed SQLITE_MAX_VARIABLE_NUMBER (32766 for version >= 3.32.0)
|
|
||||||
// https://www.sqlite.org/limits.html
|
|
||||||
const kSqliteMaxVariableNumber = 32766;
|
|
||||||
|
|
||||||
@DriftDatabase(include: {'tables.drift'})
|
@DriftDatabase(include: {'tables.drift'})
|
||||||
class SubtracksDatabase extends _$SubtracksDatabase {
|
class SubtracksDatabase extends _$SubtracksDatabase {
|
||||||
SubtracksDatabase() : super(_openConnection());
|
SubtracksDatabase() : super(_openConnection());
|
||||||
@ -173,28 +169,13 @@ class SubtracksDatabase extends _$SubtracksDatabase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteArtistsNotIn(int sourceId, Set<String> ids) {
|
Future<void> deleteArtistsNotIn(int sourceId, Iterable<String> ids) async {
|
||||||
return transaction(() async {
|
|
||||||
final allIds = (await (selectOnly(artists)
|
|
||||||
..addColumns([artists.id])
|
|
||||||
..where(artists.sourceId.equals(sourceId)))
|
|
||||||
.map((row) => row.read(artists.id))
|
|
||||||
.get())
|
|
||||||
.whereNotNull()
|
|
||||||
.toSet();
|
|
||||||
final downloadIds = (await artistIdsWithDownloadStatus(sourceId).get())
|
|
||||||
.whereNotNull()
|
|
||||||
.toSet();
|
|
||||||
|
|
||||||
final diff = allIds.difference(downloadIds).difference(ids);
|
|
||||||
for (var slice in diff.slices(kSqliteMaxVariableNumber)) {
|
|
||||||
await (delete(artists)
|
await (delete(artists)
|
||||||
..where(
|
..where(
|
||||||
(tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isIn(slice)))
|
(tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isNotIn(ids),
|
||||||
|
))
|
||||||
.go();
|
.go();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> saveAlbums(Iterable<AlbumsCompanion> albums) async {
|
Future<void> saveAlbums(Iterable<AlbumsCompanion> albums) async {
|
||||||
await batch((batch) {
|
await batch((batch) {
|
||||||
@ -202,28 +183,16 @@ class SubtracksDatabase extends _$SubtracksDatabase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteAlbumsNotIn(int sourceId, Set<String> ids) {
|
Future<void> deleteAlbumsNotIn(int sourceId, Iterable<String> ids) async {
|
||||||
return transaction(() async {
|
final alsoKeep = (await albumIdsWithDownloaded(sourceId).get()).toSet();
|
||||||
final allIds = (await (selectOnly(albums)
|
|
||||||
..addColumns([albums.id])
|
|
||||||
..where(albums.sourceId.equals(sourceId)))
|
|
||||||
.map((row) => row.read(albums.id))
|
|
||||||
.get())
|
|
||||||
.whereNotNull()
|
|
||||||
.toSet();
|
|
||||||
final downloadIds = (await albumIdsWithDownloadStatus(sourceId).get())
|
|
||||||
.whereNotNull()
|
|
||||||
.toSet();
|
|
||||||
|
|
||||||
final diff = allIds.difference(downloadIds).difference(ids);
|
ids = ids.toList()..addAll(alsoKeep);
|
||||||
for (var slice in diff.slices(kSqliteMaxVariableNumber)) {
|
|
||||||
await (delete(albums)
|
await (delete(albums)
|
||||||
..where(
|
..where(
|
||||||
(tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isIn(slice)))
|
(tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isNotIn(ids),
|
||||||
|
))
|
||||||
.go();
|
.go();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> savePlaylists(
|
Future<void> savePlaylists(
|
||||||
Iterable<PlaylistWithSongsCompanion> playlistsWithSongs,
|
Iterable<PlaylistWithSongsCompanion> playlistsWithSongs,
|
||||||
@ -246,32 +215,19 @@ class SubtracksDatabase extends _$SubtracksDatabase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deletePlaylistsNotIn(int sourceId, Set<String> ids) {
|
Future<void> deletePlaylistsNotIn(int sourceId, Iterable<String> ids) async {
|
||||||
return transaction(() async {
|
|
||||||
final allIds = (await (selectOnly(playlists)
|
|
||||||
..addColumns([playlists.id])
|
|
||||||
..where(playlists.sourceId.equals(sourceId)))
|
|
||||||
.map((row) => row.read(playlists.id))
|
|
||||||
.get())
|
|
||||||
.whereNotNull()
|
|
||||||
.toSet();
|
|
||||||
final downloadIds = (await playlistIdsWithDownloadStatus(sourceId).get())
|
|
||||||
.whereNotNull()
|
|
||||||
.toSet();
|
|
||||||
|
|
||||||
final diff = allIds.difference(downloadIds).difference(ids);
|
|
||||||
for (var slice in diff.slices(kSqliteMaxVariableNumber)) {
|
|
||||||
await (delete(playlists)
|
await (delete(playlists)
|
||||||
..where(
|
..where(
|
||||||
(tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isIn(slice)))
|
(tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isNotIn(ids),
|
||||||
|
))
|
||||||
.go();
|
.go();
|
||||||
await (delete(playlistSongs)
|
await (delete(playlistSongs)
|
||||||
..where((tbl) =>
|
..where(
|
||||||
tbl.sourceId.equals(sourceId) & tbl.playlistId.isIn(slice)))
|
(tbl) =>
|
||||||
|
tbl.sourceId.equals(sourceId) & tbl.playlistId.isNotIn(ids),
|
||||||
|
))
|
||||||
.go();
|
.go();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> savePlaylistSongs(
|
Future<void> savePlaylistSongs(
|
||||||
int sourceId,
|
int sourceId,
|
||||||
@ -294,33 +250,29 @@ class SubtracksDatabase extends _$SubtracksDatabase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteSongsNotIn(int sourceId, Set<String> ids) {
|
Future<void> deleteSongsNotIn(int sourceId, Iterable<String> ids) async {
|
||||||
return transaction(() async {
|
|
||||||
final allIds = (await (selectOnly(songs)
|
|
||||||
..addColumns([songs.id])
|
|
||||||
..where(
|
|
||||||
songs.sourceId.equals(sourceId) &
|
|
||||||
songs.downloadFilePath.isNull() &
|
|
||||||
songs.downloadTaskId.isNull(),
|
|
||||||
))
|
|
||||||
.map((row) => row.read(songs.id))
|
|
||||||
.get())
|
|
||||||
.whereNotNull()
|
|
||||||
.toSet();
|
|
||||||
|
|
||||||
final diff = allIds.difference(ids);
|
|
||||||
for (var slice in diff.slices(kSqliteMaxVariableNumber)) {
|
|
||||||
await (delete(songs)
|
await (delete(songs)
|
||||||
..where(
|
..where(
|
||||||
(tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isIn(slice)))
|
(tbl) =>
|
||||||
.go();
|
tbl.sourceId.equals(sourceId) &
|
||||||
await (delete(playlistSongs)
|
tbl.id.isNotIn(ids) &
|
||||||
..where(
|
tbl.downloadFilePath.isNull() &
|
||||||
(tbl) => tbl.sourceId.equals(sourceId) & tbl.songId.isIn(slice),
|
tbl.downloadTaskId.isNull(),
|
||||||
|
))
|
||||||
|
.go();
|
||||||
|
final remainingIds = (await (selectOnly(songs)
|
||||||
|
..addColumns([songs.id])
|
||||||
|
..where(songs.sourceId.equals(sourceId)))
|
||||||
|
.map((row) => row.read(songs.id))
|
||||||
|
.get())
|
||||||
|
.whereNotNull();
|
||||||
|
await (delete(playlistSongs)
|
||||||
|
..where(
|
||||||
|
(tbl) =>
|
||||||
|
tbl.sourceId.equals(sourceId) &
|
||||||
|
tbl.songId.isNotIn(remainingIds),
|
||||||
))
|
))
|
||||||
.go();
|
.go();
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Selectable<LastBottomNavStateData> getLastBottomNavState() {
|
Selectable<LastBottomNavStateData> getLastBottomNavState() {
|
||||||
|
|||||||
@ -4596,7 +4596,7 @@ abstract class _$SubtracksDatabase extends GeneratedDatabase {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Selectable<String> albumIdsWithDownloadStatus(int sourceId) {
|
Selectable<String> albumIdsWithDownloaded(int sourceId) {
|
||||||
return customSelect(
|
return customSelect(
|
||||||
'SELECT albums.id FROM albums JOIN songs ON songs.source_id = albums.source_id AND songs.album_id = albums.id WHERE albums.source_id = ?1 AND(songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)GROUP BY albums.id',
|
'SELECT albums.id FROM albums JOIN songs ON songs.source_id = albums.source_id AND songs.album_id = albums.id WHERE albums.source_id = ?1 AND(songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)GROUP BY albums.id',
|
||||||
variables: [
|
variables: [
|
||||||
@ -4608,32 +4608,6 @@ abstract class _$SubtracksDatabase extends GeneratedDatabase {
|
|||||||
}).map((QueryRow row) => row.read<String>('id'));
|
}).map((QueryRow row) => row.read<String>('id'));
|
||||||
}
|
}
|
||||||
|
|
||||||
Selectable<String> artistIdsWithDownloadStatus(int sourceId) {
|
|
||||||
return customSelect(
|
|
||||||
'SELECT artists.id FROM artists LEFT JOIN albums ON artists.source_id = albums.source_id AND artists.id = albums.artist_id LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id WHERE artists.source_id = ?1 AND(songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)GROUP BY artists.id',
|
|
||||||
variables: [
|
|
||||||
Variable<int>(sourceId)
|
|
||||||
],
|
|
||||||
readsFrom: {
|
|
||||||
artists,
|
|
||||||
albums,
|
|
||||||
songs,
|
|
||||||
}).map((QueryRow row) => row.read<String>('id'));
|
|
||||||
}
|
|
||||||
|
|
||||||
Selectable<String> playlistIdsWithDownloadStatus(int sourceId) {
|
|
||||||
return customSelect(
|
|
||||||
'SELECT playlists.id FROM playlists LEFT JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id LEFT JOIN songs ON playlist_songs.source_id = songs.source_id AND playlist_songs.song_id = songs.id WHERE playlists.source_id = ?1 AND(songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)GROUP BY playlists.id',
|
|
||||||
variables: [
|
|
||||||
Variable<int>(sourceId)
|
|
||||||
],
|
|
||||||
readsFrom: {
|
|
||||||
playlists,
|
|
||||||
playlistSongs,
|
|
||||||
songs,
|
|
||||||
}).map((QueryRow row) => row.read<String>('id'));
|
|
||||||
}
|
|
||||||
|
|
||||||
Selectable<int> searchArtists(String query, int limit, int offset) {
|
Selectable<int> searchArtists(String query, int limit, int offset) {
|
||||||
return customSelect(
|
return customSelect(
|
||||||
'SELECT "rowid" FROM artists_fts WHERE artists_fts MATCH ?1 ORDER BY rank LIMIT ?2 OFFSET ?3',
|
'SELECT "rowid" FROM artists_fts WHERE artists_fts MATCH ?1 ORDER BY rank LIMIT ?2 OFFSET ?3',
|
||||||
|
|||||||
@ -244,7 +244,7 @@ allSubsonicSources WITH SubsonicSettings:
|
|||||||
FROM sources
|
FROM sources
|
||||||
JOIN subsonic_sources ON subsonic_sources.source_id = sources.id;
|
JOIN subsonic_sources ON subsonic_sources.source_id = sources.id;
|
||||||
|
|
||||||
albumIdsWithDownloadStatus:
|
albumIdsWithDownloaded:
|
||||||
SELECT albums.id
|
SELECT albums.id
|
||||||
FROM albums
|
FROM albums
|
||||||
JOIN songs on songs.source_id = albums.source_id AND songs.album_id = albums.id
|
JOIN songs on songs.source_id = albums.source_id AND songs.album_id = albums.id
|
||||||
@ -253,26 +253,6 @@ albumIdsWithDownloadStatus:
|
|||||||
AND (songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)
|
AND (songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)
|
||||||
GROUP BY albums.id;
|
GROUP BY albums.id;
|
||||||
|
|
||||||
artistIdsWithDownloadStatus:
|
|
||||||
SELECT artists.id
|
|
||||||
FROM artists
|
|
||||||
LEFT JOIN albums ON artists.source_id = albums.source_id AND artists.id = albums.artist_id
|
|
||||||
LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id
|
|
||||||
WHERE
|
|
||||||
artists.source_id = :source_id
|
|
||||||
AND (songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)
|
|
||||||
GROUP BY artists.id;
|
|
||||||
|
|
||||||
playlistIdsWithDownloadStatus:
|
|
||||||
SELECT playlists.id
|
|
||||||
FROM playlists
|
|
||||||
LEFT JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id
|
|
||||||
LEFT JOIN songs ON playlist_songs.source_id = songs.source_id AND playlist_songs.song_id = songs.id
|
|
||||||
WHERE
|
|
||||||
playlists.source_id = :source_id
|
|
||||||
AND (songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)
|
|
||||||
GROUP BY playlists.id;
|
|
||||||
|
|
||||||
searchArtists:
|
searchArtists:
|
||||||
SELECT rowid
|
SELECT rowid
|
||||||
FROM artists_fts
|
FROM artists_fts
|
||||||
|
|||||||
@ -68,8 +68,7 @@ enum QueueContextType {
|
|||||||
album('album'),
|
album('album'),
|
||||||
playlist('playlist'),
|
playlist('playlist'),
|
||||||
library('library'),
|
library('library'),
|
||||||
genre('genre'),
|
genre('genre');
|
||||||
artist('artist');
|
|
||||||
|
|
||||||
const QueueContextType(this.value);
|
const QueueContextType(this.value);
|
||||||
final String value;
|
final String value;
|
||||||
|
|||||||
@ -28,7 +28,6 @@ const _$QueueContextTypeEnumMap = {
|
|||||||
QueueContextType.playlist: 'playlist',
|
QueueContextType.playlist: 'playlist',
|
||||||
QueueContextType.library: 'library',
|
QueueContextType.library: 'library',
|
||||||
QueueContextType.genre: 'genre',
|
QueueContextType.genre: 'genre',
|
||||||
QueueContextType.artist: 'artist',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_$_MediaItemData _$$_MediaItemDataFromJson(Map<String, dynamic> json) =>
|
_$_MediaItemData _$$_MediaItemDataFromJson(Map<String, dynamic> json) =>
|
||||||
|
|||||||
@ -214,7 +214,7 @@ class DownloadService extends _$DownloadService {
|
|||||||
Future<void> deleteAll(int sourceId) async {
|
Future<void> deleteAll(int sourceId) async {
|
||||||
final db = ref.read(databaseProvider);
|
final db = ref.read(databaseProvider);
|
||||||
|
|
||||||
final albumIds = await db.albumIdsWithDownloadStatus(sourceId).get();
|
final albumIds = await db.albumIdsWithDownloaded(sourceId).get();
|
||||||
for (var id in albumIds) {
|
for (var id in albumIds) {
|
||||||
await deleteAlbum(await (db.albumById(sourceId, id)).getSingle());
|
await deleteAlbum(await (db.albumById(sourceId, id)).getSingle());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ part of 'download_service.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$downloadServiceHash() => r'c72c49f980e307f3013467e76b6564d14a34a736';
|
String _$downloadServiceHash() => r'92e963b5c070f4d1edb0cd81899b16393c2b9a70';
|
||||||
|
|
||||||
/// See also [DownloadService].
|
/// See also [DownloadService].
|
||||||
@ProviderFor(DownloadService)
|
@ProviderFor(DownloadService)
|
||||||
|
|||||||
@ -31,7 +31,7 @@ class SyncService extends _$SyncService {
|
|||||||
final source = ref.read(musicSourceProvider);
|
final source = ref.read(musicSourceProvider);
|
||||||
final db = ref.read(databaseProvider);
|
final db = ref.read(databaseProvider);
|
||||||
|
|
||||||
final ids = <String>{};
|
final ids = <String>[];
|
||||||
await for (var artists in source.allArtists()) {
|
await for (var artists in source.allArtists()) {
|
||||||
ids.addAll(artists.map((e) => e.id.value));
|
ids.addAll(artists.map((e) => e.id.value));
|
||||||
await db.saveArtists(artists);
|
await db.saveArtists(artists);
|
||||||
@ -44,7 +44,7 @@ class SyncService extends _$SyncService {
|
|||||||
final source = ref.read(musicSourceProvider);
|
final source = ref.read(musicSourceProvider);
|
||||||
final db = ref.read(databaseProvider);
|
final db = ref.read(databaseProvider);
|
||||||
|
|
||||||
final ids = <String>{};
|
final ids = <String>[];
|
||||||
await for (var albums in source.allAlbums()) {
|
await for (var albums in source.allAlbums()) {
|
||||||
ids.addAll(albums.map((e) => e.id.value));
|
ids.addAll(albums.map((e) => e.id.value));
|
||||||
await db.saveAlbums(albums);
|
await db.saveAlbums(albums);
|
||||||
@ -57,7 +57,7 @@ class SyncService extends _$SyncService {
|
|||||||
final source = ref.read(musicSourceProvider);
|
final source = ref.read(musicSourceProvider);
|
||||||
final db = ref.read(databaseProvider);
|
final db = ref.read(databaseProvider);
|
||||||
|
|
||||||
final ids = <String>{};
|
final ids = <String>[];
|
||||||
await for (var playlists in source.allPlaylists()) {
|
await for (var playlists in source.allPlaylists()) {
|
||||||
ids.addAll(playlists.map((e) => e.playist.id.value));
|
ids.addAll(playlists.map((e) => e.playist.id.value));
|
||||||
await db.savePlaylists(playlists);
|
await db.savePlaylists(playlists);
|
||||||
@ -70,7 +70,7 @@ class SyncService extends _$SyncService {
|
|||||||
final source = ref.read(musicSourceProvider);
|
final source = ref.read(musicSourceProvider);
|
||||||
final db = ref.read(databaseProvider);
|
final db = ref.read(databaseProvider);
|
||||||
|
|
||||||
final ids = <String>{};
|
final ids = <String>[];
|
||||||
await for (var songs in source.allSongs()) {
|
await for (var songs in source.allSongs()) {
|
||||||
ids.addAll(songs.map((e) => e.id.value));
|
ids.addAll(songs.map((e) => e.id.value));
|
||||||
await db.saveSongs(songs);
|
await db.saveSongs(songs);
|
||||||
|
|||||||
@ -6,7 +6,7 @@ part of 'sync_service.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$syncServiceHash() => r'58ebee4e6f055b64ee6789ae43d63c0e15c679e0';
|
String _$syncServiceHash() => r'2b8da374c3143bc56f17115440d57bc70468a17e';
|
||||||
|
|
||||||
/// See also [SyncService].
|
/// See also [SyncService].
|
||||||
@ProviderFor(SyncService)
|
@ProviderFor(SyncService)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user