diff --git a/lib/app/screens/album_screen.dart b/lib/app/screens/album_screen.dart index 44f18f6..530afb2 100644 --- a/lib/app/screens/album_screen.dart +++ b/lib/app/screens/album_screen.dart @@ -41,9 +41,9 @@ class AlbumScreen extends HookConsumerWidget { sourceId: sourceId, filter: IList([SongsFilter.albumId(album.id)]), sort: IList([ - SongsSortingTerm(dir: SortDirection.asc, by: SongsColumn.disc), - SongsSortingTerm(dir: SortDirection.asc, by: SongsColumn.track), - SongsSortingTerm(dir: SortDirection.asc, by: SongsColumn.title), + SortingTerm.songsAsc(SongsColumn.disc), + SortingTerm.songsAsc(SongsColumn.track), + SortingTerm.songsAsc(SongsColumn.title), ]), ); diff --git a/lib/app/screens/library_screen.dart b/lib/app/screens/library_screen.dart index 1882de1..03db87b 100644 --- a/lib/app/screens/library_screen.dart +++ b/lib/app/screens/library_screen.dart @@ -12,6 +12,7 @@ import '../state/source.dart'; import '../ui/lists/albums_grid.dart'; import '../ui/lists/artists_list.dart'; import '../ui/lists/items.dart'; +import '../ui/lists/playlists_list.dart'; import '../ui/lists/songs_list.dart'; import '../util/custom_scroll_fix.dart'; @@ -79,11 +80,11 @@ class LibraryTabBarView extends HookConsumerWidget { final songsQuery = SongsQuery( sourceId: sourceId, sort: IList([ - SongsSortingTerm(dir: SortDirection.asc, by: SongsColumn.albumArtist), - SongsSortingTerm(dir: SortDirection.asc, by: SongsColumn.album), - SongsSortingTerm(dir: SortDirection.asc, by: SongsColumn.disc), - SongsSortingTerm(dir: SortDirection.asc, by: SongsColumn.track), - SongsSortingTerm(dir: SortDirection.asc, by: SongsColumn.title), + SortingTerm.songsAsc(SongsColumn.albumArtist), + SortingTerm.songsAsc(SongsColumn.album), + SortingTerm.songsAsc(SongsColumn.disc), + SortingTerm.songsAsc(SongsColumn.track), + SortingTerm.songsAsc(SongsColumn.title), ]), ); @@ -96,6 +97,7 @@ class LibraryTabBarView extends HookConsumerWidget { sliver: switch (tab) { LibraryTab.albums => AlbumsGrid(), LibraryTab.artists => ArtistsList(), + LibraryTab.playlists => PlaylistsList(), LibraryTab.songs => SongsList( query: songsQuery, itemBuilder: (context, item, index) => SongListTile( diff --git a/lib/app/ui/lists/albums_grid.dart b/lib/app/ui/lists/albums_grid.dart index 2cac710..00c4011 100644 --- a/lib/app/ui/lists/albums_grid.dart +++ b/lib/app/ui/lists/albums_grid.dart @@ -27,10 +27,7 @@ class AlbumsGrid extends HookConsumerWidget { AlbumsQuery( sourceId: ref.read(sourceIdProvider), sort: IList([ - AlbumsSortingTerm( - dir: SortDirection.desc, - by: AlbumsColumn.created, - ), + SortingTerm.albumsDesc(AlbumsColumn.created), ]), limit: kPageSize, offset: (pageKey - 1) * kPageSize, diff --git a/lib/app/ui/lists/artists_list.dart b/lib/app/ui/lists/artists_list.dart index 7b3e9b3..5e564b8 100644 --- a/lib/app/ui/lists/artists_list.dart +++ b/lib/app/ui/lists/artists_list.dart @@ -27,10 +27,7 @@ class ArtistsList extends HookConsumerWidget { ArtistsQuery( sourceId: ref.read(sourceIdProvider), sort: IList([ - ArtistsSortingTerm( - dir: SortDirection.asc, - by: ArtistsColumn.name, - ), + SortingTerm.artistsAsc(ArtistsColumn.name), ]), limit: kPageSize, offset: (pageKey - 1) * kPageSize, diff --git a/lib/app/ui/lists/items.dart b/lib/app/ui/lists/items.dart index 89eb7e2..f25d1a8 100644 --- a/lib/app/ui/lists/items.dart +++ b/lib/app/ui/lists/items.dart @@ -38,12 +38,12 @@ class ArtistListTile extends StatelessWidget { const ArtistListTile({ super.key, required this.artist, - this.albumCount, + required this.albumCount, this.onTap, }); final Artist artist; - final int? albumCount; + final int albumCount; final void Function()? onTap; @override @@ -56,7 +56,33 @@ class ArtistListTile extends StatelessWidget { ), ), title: Text(artist.name), - subtitle: albumCount != null ? Text('$albumCount albums') : null, + subtitle: Text('$albumCount albums'), + onTap: onTap, + ); + } +} + +class PlaylistListTile extends StatelessWidget { + const PlaylistListTile({ + super.key, + required this.playlist, + this.albumCount, + this.onTap, + }); + + final Playlist playlist; + final int? albumCount; + final void Function()? onTap; + + @override + Widget build(BuildContext context) { + return ListTile( + leading: CoverArtImage( + coverArt: playlist.coverArt, + thumbnail: true, + ), + title: Text(playlist.name), + subtitle: Text(playlist.comment ?? ''), onTap: onTap, ); } diff --git a/lib/app/ui/lists/playlists_list.dart b/lib/app/ui/lists/playlists_list.dart new file mode 100644 index 0000000..b4c964e --- /dev/null +++ b/lib/app/ui/lists/playlists_list.dart @@ -0,0 +1,58 @@ +import 'package:fast_immutable_collections/fast_immutable_collections.dart'; +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; + +import '../../../database/query.dart'; +import '../../../sources/models.dart'; +import '../../hooks/use_on_source.dart'; +import '../../hooks/use_paging_controller.dart'; +import '../../state/database.dart'; +import '../../state/source.dart'; +import 'items.dart'; + +const kPageSize = 30; + +class PlaylistsList extends HookConsumerWidget { + const PlaylistsList({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final db = ref.watch(databaseProvider); + final controller = usePagingController( + getNextPageKey: (state) => + state.lastPageIsEmpty ? null : state.nextIntPageKey, + fetchPage: (pageKey) => db.libraryDao.listPlaylists( + PlaylistsQuery( + sourceId: ref.read(sourceIdProvider), + sort: IList([ + SortingTerm.playlistsDesc(PlaylistsColumn.created), + ]), + limit: kPageSize, + offset: (pageKey - 1) * kPageSize, + ), + ), + ); + + useOnSourceChange(ref, (_) => controller.refresh()); + useOnSourceSync(ref, controller.refresh); + + return PagingListener( + controller: controller, + builder: (context, state, fetchNextPage) { + return PagedSliverList( + state: state, + fetchNextPage: fetchNextPage, + builderDelegate: PagedChildBuilderDelegate( + itemBuilder: (context, item, index) { + return PlaylistListTile( + playlist: item, + onTap: () {}, + ); + }, + ), + ); + }, + ); + } +} diff --git a/lib/database/dao/library_dao.dart b/lib/database/dao/library_dao.dart index 6515a50..2cec8fa 100644 --- a/lib/database/dao/library_dao.dart +++ b/lib/database/dao/library_dao.dart @@ -8,7 +8,7 @@ part 'library_dao.g.dart'; typedef AristListItem = ({ models.Artist artist, - int? albumCount, + int albumCount, }); typedef SongListItem = ({ @@ -182,6 +182,42 @@ class LibraryDao extends DatabaseAccessor .get(); } + Future> listPlaylists(PlaylistsQuery q) { + final query = playlists.select() + ..where((playlists) { + var filter = playlists.sourceId.equals(q.sourceId); + for (final queryFilter in q.filter) { + filter &= switch (queryFilter) { + PlaylistsFilterPublic(:final public) => playlists.public.equals( + public, + ), + PlaylistsFilterNameSearch() => CustomExpression(''), + _ => CustomExpression(''), + }; + } + + return filter; + }) + ..orderBy( + q.sort + .map( + (sort) => + (albums) => OrderingTerm( + expression: switch (sort.by) { + PlaylistsColumn.name => playlists.name, + PlaylistsColumn.created => playlists.created, + }, + mode: sort.dir.toMode(), + ), + ) + .toList(), + ); + + _limitQuery(query: query, limit: q.limit, offset: q.offset); + + return query.get(); + } + Selectable getAlbum(int sourceId, String id) { return db.managers.albums.filter( (f) => f.sourceId.equals(sourceId) & f.id.equals(id), diff --git a/lib/database/database.g.dart b/lib/database/database.g.dart index f24724b..a33975a 100644 --- a/lib/database/database.g.dart +++ b/lib/database/database.g.dart @@ -1471,6 +1471,15 @@ class Playlists extends Table with TableInfo { requiredDuringInsert: true, $customConstraints: 'NOT NULL', ); + static const VerificationMeta _publicMeta = const VerificationMeta('public'); + late final GeneratedColumn public = GeneratedColumn( + 'public', + aliasedName, + true, + type: DriftSqlType.bool, + requiredDuringInsert: false, + $customConstraints: '', + ); @override List get $columns => [ sourceId, @@ -1480,6 +1489,7 @@ class Playlists extends Table with TableInfo { coverArt, created, changed, + public, ]; @override String get aliasedName => _alias ?? actualTableName; @@ -1542,6 +1552,12 @@ class Playlists extends Table with TableInfo { } else if (isInserting) { context.missing(_changedMeta); } + if (data.containsKey('public')) { + context.handle( + _publicMeta, + public.isAcceptableOrUnknown(data['public']!, _publicMeta), + ); + } return context; } @@ -1575,6 +1591,10 @@ class Playlists extends Table with TableInfo { DriftSqlType.string, data['${effectivePrefix}cover_art'], ), + public: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}public'], + ), ); } @@ -1600,6 +1620,7 @@ class PlaylistsCompanion extends UpdateCompanion { final Value coverArt; final Value created; final Value changed; + final Value public; final Value rowid; const PlaylistsCompanion({ this.sourceId = const Value.absent(), @@ -1609,6 +1630,7 @@ class PlaylistsCompanion extends UpdateCompanion { this.coverArt = const Value.absent(), this.created = const Value.absent(), this.changed = const Value.absent(), + this.public = const Value.absent(), this.rowid = const Value.absent(), }); PlaylistsCompanion.insert({ @@ -1619,6 +1641,7 @@ class PlaylistsCompanion extends UpdateCompanion { this.coverArt = const Value.absent(), required DateTime created, required DateTime changed, + this.public = const Value.absent(), this.rowid = const Value.absent(), }) : sourceId = Value(sourceId), id = Value(id), @@ -1633,6 +1656,7 @@ class PlaylistsCompanion extends UpdateCompanion { Expression? coverArt, Expression? created, Expression? changed, + Expression? public, Expression? rowid, }) { return RawValuesInsertable({ @@ -1643,6 +1667,7 @@ class PlaylistsCompanion extends UpdateCompanion { if (coverArt != null) 'cover_art': coverArt, if (created != null) 'created': created, if (changed != null) 'changed': changed, + if (public != null) 'public': public, if (rowid != null) 'rowid': rowid, }); } @@ -1655,6 +1680,7 @@ class PlaylistsCompanion extends UpdateCompanion { Value? coverArt, Value? created, Value? changed, + Value? public, Value? rowid, }) { return PlaylistsCompanion( @@ -1665,6 +1691,7 @@ class PlaylistsCompanion extends UpdateCompanion { coverArt: coverArt ?? this.coverArt, created: created ?? this.created, changed: changed ?? this.changed, + public: public ?? this.public, rowid: rowid ?? this.rowid, ); } @@ -1693,6 +1720,9 @@ class PlaylistsCompanion extends UpdateCompanion { if (changed.present) { map['changed'] = Variable(changed.value); } + if (public.present) { + map['public'] = Variable(public.value); + } if (rowid.present) { map['rowid'] = Variable(rowid.value); } @@ -1709,6 +1739,7 @@ class PlaylistsCompanion extends UpdateCompanion { ..write('coverArt: $coverArt, ') ..write('created: $created, ') ..write('changed: $changed, ') + ..write('public: $public, ') ..write('rowid: $rowid') ..write(')')) .toString(); @@ -3432,6 +3463,7 @@ typedef $PlaylistsCreateCompanionBuilder = Value coverArt, required DateTime created, required DateTime changed, + Value public, Value rowid, }); typedef $PlaylistsUpdateCompanionBuilder = @@ -3443,6 +3475,7 @@ typedef $PlaylistsUpdateCompanionBuilder = Value coverArt, Value created, Value changed, + Value public, Value rowid, }); @@ -3489,6 +3522,11 @@ class $PlaylistsFilterComposer column: $table.changed, builder: (column) => ColumnFilters(column), ); + + ColumnFilters get public => $composableBuilder( + column: $table.public, + builder: (column) => ColumnFilters(column), + ); } class $PlaylistsOrderingComposer @@ -3534,6 +3572,11 @@ class $PlaylistsOrderingComposer column: $table.changed, builder: (column) => ColumnOrderings(column), ); + + ColumnOrderings get public => $composableBuilder( + column: $table.public, + builder: (column) => ColumnOrderings(column), + ); } class $PlaylistsAnnotationComposer @@ -3565,6 +3608,9 @@ class $PlaylistsAnnotationComposer GeneratedColumn get changed => $composableBuilder(column: $table.changed, builder: (column) => column); + + GeneratedColumn get public => + $composableBuilder(column: $table.public, builder: (column) => column); } class $PlaylistsTableManager @@ -3605,6 +3651,7 @@ class $PlaylistsTableManager Value coverArt = const Value.absent(), Value created = const Value.absent(), Value changed = const Value.absent(), + Value public = const Value.absent(), Value rowid = const Value.absent(), }) => PlaylistsCompanion( sourceId: sourceId, @@ -3614,6 +3661,7 @@ class $PlaylistsTableManager coverArt: coverArt, created: created, changed: changed, + public: public, rowid: rowid, ), createCompanionCallback: @@ -3625,6 +3673,7 @@ class $PlaylistsTableManager Value coverArt = const Value.absent(), required DateTime created, required DateTime changed, + Value public = const Value.absent(), Value rowid = const Value.absent(), }) => PlaylistsCompanion.insert( sourceId: sourceId, @@ -3634,6 +3683,7 @@ class $PlaylistsTableManager coverArt: coverArt, created: created, changed: changed, + public: public, rowid: rowid, ), withReferenceMapper: (p0) => p0 diff --git a/lib/database/query.dart b/lib/database/query.dart index fec969e..f4a2847 100644 --- a/lib/database/query.dart +++ b/lib/database/query.dart @@ -32,6 +32,11 @@ enum SongsColumn { albumArtist, } +enum PlaylistsColumn { + name, + created, +} + @freezed abstract class SortingTerm with _$SortingTerm { const factory SortingTerm.albums({ @@ -39,16 +44,53 @@ abstract class SortingTerm with _$SortingTerm { required AlbumsColumn by, }) = AlbumsSortingTerm; + static AlbumsSortingTerm albumsAsc(AlbumsColumn by) { + return AlbumsSortingTerm(dir: SortDirection.asc, by: by); + } + + static AlbumsSortingTerm albumsDesc(AlbumsColumn by) { + return AlbumsSortingTerm(dir: SortDirection.desc, by: by); + } + const factory SortingTerm.artists({ required SortDirection dir, required ArtistsColumn by, }) = ArtistsSortingTerm; + static ArtistsSortingTerm artistsAsc(ArtistsColumn by) { + return ArtistsSortingTerm(dir: SortDirection.asc, by: by); + } + + static ArtistsSortingTerm artistsDesc(ArtistsColumn by) { + return ArtistsSortingTerm(dir: SortDirection.desc, by: by); + } + const factory SortingTerm.songs({ required SortDirection dir, required SongsColumn by, }) = SongsSortingTerm; + static SongsSortingTerm songsAsc(SongsColumn by) { + return SongsSortingTerm(dir: SortDirection.asc, by: by); + } + + static SongsSortingTerm songsDesc(SongsColumn by) { + return SongsSortingTerm(dir: SortDirection.desc, by: by); + } + + const factory SortingTerm.playlists({ + required SortDirection dir, + required PlaylistsColumn by, + }) = PlaylistsSortingTerm; + + static PlaylistsSortingTerm playlistsAsc(PlaylistsColumn by) { + return PlaylistsSortingTerm(dir: SortDirection.asc, by: by); + } + + static PlaylistsSortingTerm playlistsDesc(PlaylistsColumn by) { + return PlaylistsSortingTerm(dir: SortDirection.desc, by: by); + } + factory SortingTerm.fromJson(Map json) => _$SortingTermFromJson(json); } @@ -122,3 +164,27 @@ abstract class SongsFilter with _$SongsFilter { factory SongsFilter.fromJson(Map json) => _$SongsFilterFromJson(json); } + +@freezed +abstract class PlaylistsQuery with _$PlaylistsQuery { + const factory PlaylistsQuery({ + required int sourceId, + @Default(IListConst([])) IList filter, + required IList sort, + int? limit, + int? offset, + }) = _PlaylistsQuery; + + factory PlaylistsQuery.fromJson(Map json) => + _$PlaylistsQueryFromJson(json); +} + +@freezed +abstract class PlaylistsFilter with _$PlaylistsFilter { + const factory PlaylistsFilter.nameSearch(String name) = + PlaylistsFilterNameSearch; + const factory PlaylistsFilter.public(bool public) = PlaylistsFilterPublic; + + factory PlaylistsFilter.fromJson(Map json) => + _$PlaylistsFilterFromJson(json); +} diff --git a/lib/database/query.freezed.dart b/lib/database/query.freezed.dart index 722aa70..3e658af 100644 --- a/lib/database/query.freezed.dart +++ b/lib/database/query.freezed.dart @@ -27,6 +27,10 @@ SortingTerm _$SortingTermFromJson( return SongsSortingTerm.fromJson( json ); + case 'playlists': + return PlaylistsSortingTerm.fromJson( + json + ); default: throw CheckedFromJsonException( @@ -116,13 +120,14 @@ extension SortingTermPatterns on SortingTerm { /// } /// ``` -@optionalTypeArgs TResult maybeMap({TResult Function( AlbumsSortingTerm value)? albums,TResult Function( ArtistsSortingTerm value)? artists,TResult Function( SongsSortingTerm value)? songs,required TResult orElse(),}){ +@optionalTypeArgs TResult maybeMap({TResult Function( AlbumsSortingTerm value)? albums,TResult Function( ArtistsSortingTerm value)? artists,TResult Function( SongsSortingTerm value)? songs,TResult Function( PlaylistsSortingTerm value)? playlists,required TResult orElse(),}){ final _that = this; switch (_that) { case AlbumsSortingTerm() when albums != null: return albums(_that);case ArtistsSortingTerm() when artists != null: return artists(_that);case SongsSortingTerm() when songs != null: -return songs(_that);case _: +return songs(_that);case PlaylistsSortingTerm() when playlists != null: +return playlists(_that);case _: return orElse(); } @@ -140,13 +145,14 @@ return songs(_that);case _: /// } /// ``` -@optionalTypeArgs TResult map({required TResult Function( AlbumsSortingTerm value) albums,required TResult Function( ArtistsSortingTerm value) artists,required TResult Function( SongsSortingTerm value) songs,}){ +@optionalTypeArgs TResult map({required TResult Function( AlbumsSortingTerm value) albums,required TResult Function( ArtistsSortingTerm value) artists,required TResult Function( SongsSortingTerm value) songs,required TResult Function( PlaylistsSortingTerm value) playlists,}){ final _that = this; switch (_that) { case AlbumsSortingTerm(): return albums(_that);case ArtistsSortingTerm(): return artists(_that);case SongsSortingTerm(): -return songs(_that);case _: +return songs(_that);case PlaylistsSortingTerm(): +return playlists(_that);case _: throw StateError('Unexpected subclass'); } @@ -163,13 +169,14 @@ return songs(_that);case _: /// } /// ``` -@optionalTypeArgs TResult? mapOrNull({TResult? Function( AlbumsSortingTerm value)? albums,TResult? Function( ArtistsSortingTerm value)? artists,TResult? Function( SongsSortingTerm value)? songs,}){ +@optionalTypeArgs TResult? mapOrNull({TResult? Function( AlbumsSortingTerm value)? albums,TResult? Function( ArtistsSortingTerm value)? artists,TResult? Function( SongsSortingTerm value)? songs,TResult? Function( PlaylistsSortingTerm value)? playlists,}){ final _that = this; switch (_that) { case AlbumsSortingTerm() when albums != null: return albums(_that);case ArtistsSortingTerm() when artists != null: return artists(_that);case SongsSortingTerm() when songs != null: -return songs(_that);case _: +return songs(_that);case PlaylistsSortingTerm() when playlists != null: +return playlists(_that);case _: return null; } @@ -186,12 +193,13 @@ return songs(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen({TResult Function( SortDirection dir, AlbumsColumn by)? albums,TResult Function( SortDirection dir, ArtistsColumn by)? artists,TResult Function( SortDirection dir, SongsColumn by)? songs,required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen({TResult Function( SortDirection dir, AlbumsColumn by)? albums,TResult Function( SortDirection dir, ArtistsColumn by)? artists,TResult Function( SortDirection dir, SongsColumn by)? songs,TResult Function( SortDirection dir, PlaylistsColumn by)? playlists,required TResult orElse(),}) {final _that = this; switch (_that) { case AlbumsSortingTerm() when albums != null: return albums(_that.dir,_that.by);case ArtistsSortingTerm() when artists != null: return artists(_that.dir,_that.by);case SongsSortingTerm() when songs != null: -return songs(_that.dir,_that.by);case _: +return songs(_that.dir,_that.by);case PlaylistsSortingTerm() when playlists != null: +return playlists(_that.dir,_that.by);case _: return orElse(); } @@ -209,12 +217,13 @@ return songs(_that.dir,_that.by);case _: /// } /// ``` -@optionalTypeArgs TResult when({required TResult Function( SortDirection dir, AlbumsColumn by) albums,required TResult Function( SortDirection dir, ArtistsColumn by) artists,required TResult Function( SortDirection dir, SongsColumn by) songs,}) {final _that = this; +@optionalTypeArgs TResult when({required TResult Function( SortDirection dir, AlbumsColumn by) albums,required TResult Function( SortDirection dir, ArtistsColumn by) artists,required TResult Function( SortDirection dir, SongsColumn by) songs,required TResult Function( SortDirection dir, PlaylistsColumn by) playlists,}) {final _that = this; switch (_that) { case AlbumsSortingTerm(): return albums(_that.dir,_that.by);case ArtistsSortingTerm(): return artists(_that.dir,_that.by);case SongsSortingTerm(): -return songs(_that.dir,_that.by);case _: +return songs(_that.dir,_that.by);case PlaylistsSortingTerm(): +return playlists(_that.dir,_that.by);case _: throw StateError('Unexpected subclass'); } @@ -231,12 +240,13 @@ return songs(_that.dir,_that.by);case _: /// } /// ``` -@optionalTypeArgs TResult? whenOrNull({TResult? Function( SortDirection dir, AlbumsColumn by)? albums,TResult? Function( SortDirection dir, ArtistsColumn by)? artists,TResult? Function( SortDirection dir, SongsColumn by)? songs,}) {final _that = this; +@optionalTypeArgs TResult? whenOrNull({TResult? Function( SortDirection dir, AlbumsColumn by)? albums,TResult? Function( SortDirection dir, ArtistsColumn by)? artists,TResult? Function( SortDirection dir, SongsColumn by)? songs,TResult? Function( SortDirection dir, PlaylistsColumn by)? playlists,}) {final _that = this; switch (_that) { case AlbumsSortingTerm() when albums != null: return albums(_that.dir,_that.by);case ArtistsSortingTerm() when artists != null: return artists(_that.dir,_that.by);case SongsSortingTerm() when songs != null: -return songs(_that.dir,_that.by);case _: +return songs(_that.dir,_that.by);case PlaylistsSortingTerm() when playlists != null: +return playlists(_that.dir,_that.by);case _: return null; } @@ -467,6 +477,81 @@ as SongsColumn, } +} + +/// @nodoc +@JsonSerializable() + +class PlaylistsSortingTerm implements SortingTerm { + const PlaylistsSortingTerm({required this.dir, required this.by, final String? $type}): $type = $type ?? 'playlists'; + factory PlaylistsSortingTerm.fromJson(Map json) => _$PlaylistsSortingTermFromJson(json); + +@override final SortDirection dir; +@override final PlaylistsColumn by; + +@JsonKey(name: 'runtimeType') +final String $type; + + +/// Create a copy of SortingTerm +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$PlaylistsSortingTermCopyWith get copyWith => _$PlaylistsSortingTermCopyWithImpl(this, _$identity); + +@override +Map toJson() { + return _$PlaylistsSortingTermToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is PlaylistsSortingTerm&&(identical(other.dir, dir) || other.dir == dir)&&(identical(other.by, by) || other.by == by)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,dir,by); + +@override +String toString() { + return 'SortingTerm.playlists(dir: $dir, by: $by)'; +} + + +} + +/// @nodoc +abstract mixin class $PlaylistsSortingTermCopyWith<$Res> implements $SortingTermCopyWith<$Res> { + factory $PlaylistsSortingTermCopyWith(PlaylistsSortingTerm value, $Res Function(PlaylistsSortingTerm) _then) = _$PlaylistsSortingTermCopyWithImpl; +@override @useResult +$Res call({ + SortDirection dir, PlaylistsColumn by +}); + + + + +} +/// @nodoc +class _$PlaylistsSortingTermCopyWithImpl<$Res> + implements $PlaylistsSortingTermCopyWith<$Res> { + _$PlaylistsSortingTermCopyWithImpl(this._self, this._then); + + final PlaylistsSortingTerm _self; + final $Res Function(PlaylistsSortingTerm) _then; + +/// Create a copy of SortingTerm +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? dir = null,Object? by = null,}) { + return _then(PlaylistsSortingTerm( +dir: null == dir ? _self.dir : dir // ignore: cast_nullable_to_non_nullable +as SortDirection,by: null == by ? _self.by : by // ignore: cast_nullable_to_non_nullable +as PlaylistsColumn, + )); +} + + } @@ -2306,6 +2391,619 @@ as String, } +} + + +/// @nodoc +mixin _$PlaylistsQuery { + + int get sourceId; IList get filter; IList get sort; int? get limit; int? get offset; +/// Create a copy of PlaylistsQuery +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$PlaylistsQueryCopyWith get copyWith => _$PlaylistsQueryCopyWithImpl(this as PlaylistsQuery, _$identity); + + /// Serializes this PlaylistsQuery to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is PlaylistsQuery&&(identical(other.sourceId, sourceId) || other.sourceId == sourceId)&&const DeepCollectionEquality().equals(other.filter, filter)&&const DeepCollectionEquality().equals(other.sort, sort)&&(identical(other.limit, limit) || other.limit == limit)&&(identical(other.offset, offset) || other.offset == offset)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,sourceId,const DeepCollectionEquality().hash(filter),const DeepCollectionEquality().hash(sort),limit,offset); + +@override +String toString() { + return 'PlaylistsQuery(sourceId: $sourceId, filter: $filter, sort: $sort, limit: $limit, offset: $offset)'; +} + + +} + +/// @nodoc +abstract mixin class $PlaylistsQueryCopyWith<$Res> { + factory $PlaylistsQueryCopyWith(PlaylistsQuery value, $Res Function(PlaylistsQuery) _then) = _$PlaylistsQueryCopyWithImpl; +@useResult +$Res call({ + int sourceId, IList filter, IList sort, int? limit, int? offset +}); + + + + +} +/// @nodoc +class _$PlaylistsQueryCopyWithImpl<$Res> + implements $PlaylistsQueryCopyWith<$Res> { + _$PlaylistsQueryCopyWithImpl(this._self, this._then); + + final PlaylistsQuery _self; + final $Res Function(PlaylistsQuery) _then; + +/// Create a copy of PlaylistsQuery +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? sourceId = null,Object? filter = null,Object? sort = null,Object? limit = freezed,Object? offset = freezed,}) { + return _then(_self.copyWith( +sourceId: null == sourceId ? _self.sourceId : sourceId // ignore: cast_nullable_to_non_nullable +as int,filter: null == filter ? _self.filter : filter // ignore: cast_nullable_to_non_nullable +as IList,sort: null == sort ? _self.sort : sort // ignore: cast_nullable_to_non_nullable +as IList,limit: freezed == limit ? _self.limit : limit // ignore: cast_nullable_to_non_nullable +as int?,offset: freezed == offset ? _self.offset : offset // ignore: cast_nullable_to_non_nullable +as int?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [PlaylistsQuery]. +extension PlaylistsQueryPatterns on PlaylistsQuery { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _PlaylistsQuery value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _PlaylistsQuery() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _PlaylistsQuery value) $default,){ +final _that = this; +switch (_that) { +case _PlaylistsQuery(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _PlaylistsQuery value)? $default,){ +final _that = this; +switch (_that) { +case _PlaylistsQuery() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( int sourceId, IList filter, IList sort, int? limit, int? offset)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _PlaylistsQuery() when $default != null: +return $default(_that.sourceId,_that.filter,_that.sort,_that.limit,_that.offset);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( int sourceId, IList filter, IList sort, int? limit, int? offset) $default,) {final _that = this; +switch (_that) { +case _PlaylistsQuery(): +return $default(_that.sourceId,_that.filter,_that.sort,_that.limit,_that.offset);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( int sourceId, IList filter, IList sort, int? limit, int? offset)? $default,) {final _that = this; +switch (_that) { +case _PlaylistsQuery() when $default != null: +return $default(_that.sourceId,_that.filter,_that.sort,_that.limit,_that.offset);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _PlaylistsQuery implements PlaylistsQuery { + const _PlaylistsQuery({required this.sourceId, this.filter = const IListConst([]), required this.sort, this.limit, this.offset}); + factory _PlaylistsQuery.fromJson(Map json) => _$PlaylistsQueryFromJson(json); + +@override final int sourceId; +@override@JsonKey() final IList filter; +@override final IList sort; +@override final int? limit; +@override final int? offset; + +/// Create a copy of PlaylistsQuery +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$PlaylistsQueryCopyWith<_PlaylistsQuery> get copyWith => __$PlaylistsQueryCopyWithImpl<_PlaylistsQuery>(this, _$identity); + +@override +Map toJson() { + return _$PlaylistsQueryToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _PlaylistsQuery&&(identical(other.sourceId, sourceId) || other.sourceId == sourceId)&&const DeepCollectionEquality().equals(other.filter, filter)&&const DeepCollectionEquality().equals(other.sort, sort)&&(identical(other.limit, limit) || other.limit == limit)&&(identical(other.offset, offset) || other.offset == offset)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,sourceId,const DeepCollectionEquality().hash(filter),const DeepCollectionEquality().hash(sort),limit,offset); + +@override +String toString() { + return 'PlaylistsQuery(sourceId: $sourceId, filter: $filter, sort: $sort, limit: $limit, offset: $offset)'; +} + + +} + +/// @nodoc +abstract mixin class _$PlaylistsQueryCopyWith<$Res> implements $PlaylistsQueryCopyWith<$Res> { + factory _$PlaylistsQueryCopyWith(_PlaylistsQuery value, $Res Function(_PlaylistsQuery) _then) = __$PlaylistsQueryCopyWithImpl; +@override @useResult +$Res call({ + int sourceId, IList filter, IList sort, int? limit, int? offset +}); + + + + +} +/// @nodoc +class __$PlaylistsQueryCopyWithImpl<$Res> + implements _$PlaylistsQueryCopyWith<$Res> { + __$PlaylistsQueryCopyWithImpl(this._self, this._then); + + final _PlaylistsQuery _self; + final $Res Function(_PlaylistsQuery) _then; + +/// Create a copy of PlaylistsQuery +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? sourceId = null,Object? filter = null,Object? sort = null,Object? limit = freezed,Object? offset = freezed,}) { + return _then(_PlaylistsQuery( +sourceId: null == sourceId ? _self.sourceId : sourceId // ignore: cast_nullable_to_non_nullable +as int,filter: null == filter ? _self.filter : filter // ignore: cast_nullable_to_non_nullable +as IList,sort: null == sort ? _self.sort : sort // ignore: cast_nullable_to_non_nullable +as IList,limit: freezed == limit ? _self.limit : limit // ignore: cast_nullable_to_non_nullable +as int?,offset: freezed == offset ? _self.offset : offset // ignore: cast_nullable_to_non_nullable +as int?, + )); +} + + +} + +PlaylistsFilter _$PlaylistsFilterFromJson( + Map json +) { + switch (json['runtimeType']) { + case 'nameSearch': + return PlaylistsFilterNameSearch.fromJson( + json + ); + case 'public': + return PlaylistsFilterPublic.fromJson( + json + ); + + default: + throw CheckedFromJsonException( + json, + 'runtimeType', + 'PlaylistsFilter', + 'Invalid union type "${json['runtimeType']}"!' +); + } + +} + +/// @nodoc +mixin _$PlaylistsFilter { + + + + /// Serializes this PlaylistsFilter to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is PlaylistsFilter); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'PlaylistsFilter()'; +} + + +} + +/// @nodoc +class $PlaylistsFilterCopyWith<$Res> { +$PlaylistsFilterCopyWith(PlaylistsFilter _, $Res Function(PlaylistsFilter) __); +} + + +/// Adds pattern-matching-related methods to [PlaylistsFilter]. +extension PlaylistsFilterPatterns on PlaylistsFilter { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap({TResult Function( PlaylistsFilterNameSearch value)? nameSearch,TResult Function( PlaylistsFilterPublic value)? public,required TResult orElse(),}){ +final _that = this; +switch (_that) { +case PlaylistsFilterNameSearch() when nameSearch != null: +return nameSearch(_that);case PlaylistsFilterPublic() when public != null: +return public(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map({required TResult Function( PlaylistsFilterNameSearch value) nameSearch,required TResult Function( PlaylistsFilterPublic value) public,}){ +final _that = this; +switch (_that) { +case PlaylistsFilterNameSearch(): +return nameSearch(_that);case PlaylistsFilterPublic(): +return public(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull({TResult? Function( PlaylistsFilterNameSearch value)? nameSearch,TResult? Function( PlaylistsFilterPublic value)? public,}){ +final _that = this; +switch (_that) { +case PlaylistsFilterNameSearch() when nameSearch != null: +return nameSearch(_that);case PlaylistsFilterPublic() when public != null: +return public(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen({TResult Function( String name)? nameSearch,TResult Function( bool public)? public,required TResult orElse(),}) {final _that = this; +switch (_that) { +case PlaylistsFilterNameSearch() when nameSearch != null: +return nameSearch(_that.name);case PlaylistsFilterPublic() when public != null: +return public(_that.public);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when({required TResult Function( String name) nameSearch,required TResult Function( bool public) public,}) {final _that = this; +switch (_that) { +case PlaylistsFilterNameSearch(): +return nameSearch(_that.name);case PlaylistsFilterPublic(): +return public(_that.public);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull({TResult? Function( String name)? nameSearch,TResult? Function( bool public)? public,}) {final _that = this; +switch (_that) { +case PlaylistsFilterNameSearch() when nameSearch != null: +return nameSearch(_that.name);case PlaylistsFilterPublic() when public != null: +return public(_that.public);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class PlaylistsFilterNameSearch implements PlaylistsFilter { + const PlaylistsFilterNameSearch(this.name, {final String? $type}): $type = $type ?? 'nameSearch'; + factory PlaylistsFilterNameSearch.fromJson(Map json) => _$PlaylistsFilterNameSearchFromJson(json); + + final String name; + +@JsonKey(name: 'runtimeType') +final String $type; + + +/// Create a copy of PlaylistsFilter +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$PlaylistsFilterNameSearchCopyWith get copyWith => _$PlaylistsFilterNameSearchCopyWithImpl(this, _$identity); + +@override +Map toJson() { + return _$PlaylistsFilterNameSearchToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is PlaylistsFilterNameSearch&&(identical(other.name, name) || other.name == name)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,name); + +@override +String toString() { + return 'PlaylistsFilter.nameSearch(name: $name)'; +} + + +} + +/// @nodoc +abstract mixin class $PlaylistsFilterNameSearchCopyWith<$Res> implements $PlaylistsFilterCopyWith<$Res> { + factory $PlaylistsFilterNameSearchCopyWith(PlaylistsFilterNameSearch value, $Res Function(PlaylistsFilterNameSearch) _then) = _$PlaylistsFilterNameSearchCopyWithImpl; +@useResult +$Res call({ + String name +}); + + + + +} +/// @nodoc +class _$PlaylistsFilterNameSearchCopyWithImpl<$Res> + implements $PlaylistsFilterNameSearchCopyWith<$Res> { + _$PlaylistsFilterNameSearchCopyWithImpl(this._self, this._then); + + final PlaylistsFilterNameSearch _self; + final $Res Function(PlaylistsFilterNameSearch) _then; + +/// Create a copy of PlaylistsFilter +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? name = null,}) { + return _then(PlaylistsFilterNameSearch( +null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +/// @nodoc +@JsonSerializable() + +class PlaylistsFilterPublic implements PlaylistsFilter { + const PlaylistsFilterPublic(this.public, {final String? $type}): $type = $type ?? 'public'; + factory PlaylistsFilterPublic.fromJson(Map json) => _$PlaylistsFilterPublicFromJson(json); + + final bool public; + +@JsonKey(name: 'runtimeType') +final String $type; + + +/// Create a copy of PlaylistsFilter +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$PlaylistsFilterPublicCopyWith get copyWith => _$PlaylistsFilterPublicCopyWithImpl(this, _$identity); + +@override +Map toJson() { + return _$PlaylistsFilterPublicToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is PlaylistsFilterPublic&&(identical(other.public, public) || other.public == public)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,public); + +@override +String toString() { + return 'PlaylistsFilter.public(public: $public)'; +} + + +} + +/// @nodoc +abstract mixin class $PlaylistsFilterPublicCopyWith<$Res> implements $PlaylistsFilterCopyWith<$Res> { + factory $PlaylistsFilterPublicCopyWith(PlaylistsFilterPublic value, $Res Function(PlaylistsFilterPublic) _then) = _$PlaylistsFilterPublicCopyWithImpl; +@useResult +$Res call({ + bool public +}); + + + + +} +/// @nodoc +class _$PlaylistsFilterPublicCopyWithImpl<$Res> + implements $PlaylistsFilterPublicCopyWith<$Res> { + _$PlaylistsFilterPublicCopyWithImpl(this._self, this._then); + + final PlaylistsFilterPublic _self; + final $Res Function(PlaylistsFilterPublic) _then; + +/// Create a copy of PlaylistsFilter +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? public = null,}) { + return _then(PlaylistsFilterPublic( +null == public ? _self.public : public // ignore: cast_nullable_to_non_nullable +as bool, + )); +} + + } // dart format on diff --git a/lib/database/query.g.dart b/lib/database/query.g.dart index 4900a81..2418355 100644 --- a/lib/database/query.g.dart +++ b/lib/database/query.g.dart @@ -71,6 +71,30 @@ const _$SongsColumnEnumMap = { SongsColumn.starred: 'starred', SongsColumn.disc: 'disc', SongsColumn.track: 'track', + SongsColumn.album: 'album', + SongsColumn.artist: 'artist', + SongsColumn.albumArtist: 'albumArtist', +}; + +PlaylistsSortingTerm _$PlaylistsSortingTermFromJson( + Map json, +) => PlaylistsSortingTerm( + dir: $enumDecode(_$SortDirectionEnumMap, json['dir']), + by: $enumDecode(_$PlaylistsColumnEnumMap, json['by']), + $type: json['runtimeType'] as String?, +); + +Map _$PlaylistsSortingTermToJson( + PlaylistsSortingTerm instance, +) => { + 'dir': _$SortDirectionEnumMap[instance.dir]!, + 'by': _$PlaylistsColumnEnumMap[instance.by]!, + 'runtimeType': instance.$type, +}; + +const _$PlaylistsColumnEnumMap = { + PlaylistsColumn.name: 'name', + PlaylistsColumn.created: 'created', }; _AlbumsQuery _$AlbumsQueryFromJson(Map json) => _AlbumsQuery( @@ -224,3 +248,55 @@ Map _$SongsFilterPlaylistIdToJson( 'playlistId': instance.playlistId, 'runtimeType': instance.$type, }; + +_PlaylistsQuery _$PlaylistsQueryFromJson(Map json) => + _PlaylistsQuery( + sourceId: (json['sourceId'] as num).toInt(), + filter: json['filter'] == null + ? const IListConst([]) + : IList.fromJson( + json['filter'], + (value) => + PlaylistsFilter.fromJson(value as Map), + ), + sort: IList.fromJson( + json['sort'], + (value) => PlaylistsSortingTerm.fromJson(value as Map), + ), + limit: (json['limit'] as num?)?.toInt(), + offset: (json['offset'] as num?)?.toInt(), + ); + +Map _$PlaylistsQueryToJson(_PlaylistsQuery instance) => + { + 'sourceId': instance.sourceId, + 'filter': instance.filter.toJson((value) => value), + 'sort': instance.sort.toJson((value) => value), + 'limit': instance.limit, + 'offset': instance.offset, + }; + +PlaylistsFilterNameSearch _$PlaylistsFilterNameSearchFromJson( + Map json, +) => PlaylistsFilterNameSearch( + json['name'] as String, + $type: json['runtimeType'] as String?, +); + +Map _$PlaylistsFilterNameSearchToJson( + PlaylistsFilterNameSearch instance, +) => {'name': instance.name, 'runtimeType': instance.$type}; + +PlaylistsFilterPublic _$PlaylistsFilterPublicFromJson( + Map json, +) => PlaylistsFilterPublic( + json['public'] as bool, + $type: json['runtimeType'] as String?, +); + +Map _$PlaylistsFilterPublicToJson( + PlaylistsFilterPublic instance, +) => { + 'public': instance.public, + 'runtimeType': instance.$type, +}; diff --git a/lib/database/tables.drift b/lib/database/tables.drift index 8fbd828..9a76641 100644 --- a/lib/database/tables.drift +++ b/lib/database/tables.drift @@ -136,6 +136,7 @@ CREATE TABLE playlists( cover_art TEXT, created DATETIME NOT NULL, changed DATETIME NOT NULL, + public BOOLEAN, PRIMARY KEY (source_id, id), FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE ) WITH Playlist; diff --git a/lib/sources/subsonic/mapping.dart b/lib/sources/subsonic/mapping.dart index 7ba00ed..996fcdd 100644 --- a/lib/sources/subsonic/mapping.dart +++ b/lib/sources/subsonic/mapping.dart @@ -34,6 +34,7 @@ Playlist mapPlaylist(XmlElement e) => Playlist( coverArt: e.getAttribute('coverArt'), created: DateTime.parse(e.getAttribute('created')!), changed: DateTime.parse(e.getAttribute('changed')!), + public: bool.tryParse(e.getAttribute('public') ?? ''), owner: e.getAttribute('owner'), );