mirror of
https://github.com/austinried/subtracks.git
synced 2026-02-10 15:02:42 +01:00
bring in database
switch to just using source models (no extra db fields) start re-implementing sync service
This commit is contained in:
@@ -1,32 +1,21 @@
|
||||
// ignore_for_file: annotate_overrides
|
||||
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'models.freezed.dart';
|
||||
part 'models.g.dart';
|
||||
|
||||
mixin Starred {
|
||||
DateTime? get starred;
|
||||
}
|
||||
|
||||
mixin CoverArt {
|
||||
String? get coverArt;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class SourceItem with _$SourceItem {
|
||||
@With<Starred>()
|
||||
const factory SourceItem.artist({
|
||||
abstract class Artist with _$Artist {
|
||||
const factory Artist({
|
||||
required String id,
|
||||
required String name,
|
||||
DateTime? starred,
|
||||
Uri? smallImage,
|
||||
Uri? largeImage,
|
||||
}) = SourceArtist;
|
||||
}) = _Artist;
|
||||
}
|
||||
|
||||
@With<Starred>()
|
||||
@With<CoverArt>()
|
||||
const factory SourceItem.album({
|
||||
@freezed
|
||||
abstract class Album with _$Album {
|
||||
const factory Album({
|
||||
required String id,
|
||||
String? artistId,
|
||||
required String name,
|
||||
@@ -38,10 +27,12 @@ abstract class SourceItem with _$SourceItem {
|
||||
String? genre,
|
||||
int? frequentRank,
|
||||
int? recentRank,
|
||||
}) = SourceAlbum;
|
||||
}) = _Album;
|
||||
}
|
||||
|
||||
@With<CoverArt>()
|
||||
const factory SourceItem.playlist({
|
||||
@freezed
|
||||
abstract class Playlist with _$Playlist {
|
||||
const factory Playlist({
|
||||
required String id,
|
||||
required String name,
|
||||
String? comment,
|
||||
@@ -50,11 +41,12 @@ abstract class SourceItem with _$SourceItem {
|
||||
String? coverArt,
|
||||
String? owner,
|
||||
bool? public,
|
||||
}) = SourcePlaylist;
|
||||
}) = _Playlist;
|
||||
}
|
||||
|
||||
@With<Starred>()
|
||||
@With<CoverArt>()
|
||||
const factory SourceItem.song({
|
||||
@freezed
|
||||
abstract class Song with _$Song {
|
||||
const factory Song({
|
||||
required String id,
|
||||
String? albumId,
|
||||
String? artistId,
|
||||
@@ -67,20 +59,14 @@ abstract class SourceItem with _$SourceItem {
|
||||
DateTime? starred,
|
||||
String? genre,
|
||||
String? coverArt,
|
||||
}) = SourceSong;
|
||||
|
||||
factory SourceItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$SourceItemFromJson(json);
|
||||
}) = _Song;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class SourcePlaylistSong with _$SourcePlaylistSong {
|
||||
const factory SourcePlaylistSong({
|
||||
abstract class PlaylistSong with _$PlaylistSong {
|
||||
const factory PlaylistSong({
|
||||
required String playlistId,
|
||||
required String songId,
|
||||
required int position,
|
||||
}) = _SourcePlaylistSong;
|
||||
|
||||
factory SourcePlaylistSong.fromJson(Map<String, dynamic> json) =>
|
||||
_$SourcePlaylistSongFromJson(json);
|
||||
}) = _PlaylistSong;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,142 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'models.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
SourceArtist _$SourceArtistFromJson(Map<String, dynamic> json) => SourceArtist(
|
||||
id: json['id'] as String,
|
||||
name: json['name'] as String,
|
||||
starred: json['starred'] == null
|
||||
? null
|
||||
: DateTime.parse(json['starred'] as String),
|
||||
smallImage: json['smallImage'] == null
|
||||
? null
|
||||
: Uri.parse(json['smallImage'] as String),
|
||||
largeImage: json['largeImage'] == null
|
||||
? null
|
||||
: Uri.parse(json['largeImage'] as String),
|
||||
$type: json['runtimeType'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SourceArtistToJson(SourceArtist instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'starred': instance.starred?.toIso8601String(),
|
||||
'smallImage': instance.smallImage?.toString(),
|
||||
'largeImage': instance.largeImage?.toString(),
|
||||
'runtimeType': instance.$type,
|
||||
};
|
||||
|
||||
SourceAlbum _$SourceAlbumFromJson(Map<String, dynamic> json) => SourceAlbum(
|
||||
id: json['id'] as String,
|
||||
artistId: json['artistId'] as String?,
|
||||
name: json['name'] as String,
|
||||
albumArtist: json['albumArtist'] as String?,
|
||||
created: DateTime.parse(json['created'] as String),
|
||||
coverArt: json['coverArt'] as String?,
|
||||
year: (json['year'] as num?)?.toInt(),
|
||||
starred: json['starred'] == null
|
||||
? null
|
||||
: DateTime.parse(json['starred'] as String),
|
||||
genre: json['genre'] as String?,
|
||||
frequentRank: (json['frequentRank'] as num?)?.toInt(),
|
||||
recentRank: (json['recentRank'] as num?)?.toInt(),
|
||||
$type: json['runtimeType'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SourceAlbumToJson(SourceAlbum instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'artistId': instance.artistId,
|
||||
'name': instance.name,
|
||||
'albumArtist': instance.albumArtist,
|
||||
'created': instance.created.toIso8601String(),
|
||||
'coverArt': instance.coverArt,
|
||||
'year': instance.year,
|
||||
'starred': instance.starred?.toIso8601String(),
|
||||
'genre': instance.genre,
|
||||
'frequentRank': instance.frequentRank,
|
||||
'recentRank': instance.recentRank,
|
||||
'runtimeType': instance.$type,
|
||||
};
|
||||
|
||||
SourcePlaylist _$SourcePlaylistFromJson(Map<String, dynamic> json) =>
|
||||
SourcePlaylist(
|
||||
id: json['id'] as String,
|
||||
name: json['name'] as String,
|
||||
comment: json['comment'] as String?,
|
||||
created: DateTime.parse(json['created'] as String),
|
||||
changed: DateTime.parse(json['changed'] as String),
|
||||
coverArt: json['coverArt'] as String?,
|
||||
owner: json['owner'] as String?,
|
||||
public: json['public'] as bool?,
|
||||
$type: json['runtimeType'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SourcePlaylistToJson(SourcePlaylist instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'comment': instance.comment,
|
||||
'created': instance.created.toIso8601String(),
|
||||
'changed': instance.changed.toIso8601String(),
|
||||
'coverArt': instance.coverArt,
|
||||
'owner': instance.owner,
|
||||
'public': instance.public,
|
||||
'runtimeType': instance.$type,
|
||||
};
|
||||
|
||||
SourceSong _$SourceSongFromJson(Map<String, dynamic> json) => SourceSong(
|
||||
id: json['id'] as String,
|
||||
albumId: json['albumId'] as String?,
|
||||
artistId: json['artistId'] as String?,
|
||||
title: json['title'] as String,
|
||||
artist: json['artist'] as String?,
|
||||
album: json['album'] as String?,
|
||||
duration: json['duration'] == null
|
||||
? null
|
||||
: Duration(microseconds: (json['duration'] as num).toInt()),
|
||||
track: (json['track'] as num?)?.toInt(),
|
||||
disc: (json['disc'] as num?)?.toInt(),
|
||||
starred: json['starred'] == null
|
||||
? null
|
||||
: DateTime.parse(json['starred'] as String),
|
||||
genre: json['genre'] as String?,
|
||||
coverArt: json['coverArt'] as String?,
|
||||
$type: json['runtimeType'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SourceSongToJson(SourceSong instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'albumId': instance.albumId,
|
||||
'artistId': instance.artistId,
|
||||
'title': instance.title,
|
||||
'artist': instance.artist,
|
||||
'album': instance.album,
|
||||
'duration': instance.duration?.inMicroseconds,
|
||||
'track': instance.track,
|
||||
'disc': instance.disc,
|
||||
'starred': instance.starred?.toIso8601String(),
|
||||
'genre': instance.genre,
|
||||
'coverArt': instance.coverArt,
|
||||
'runtimeType': instance.$type,
|
||||
};
|
||||
|
||||
_SourcePlaylistSong _$SourcePlaylistSongFromJson(Map<String, dynamic> json) =>
|
||||
_SourcePlaylistSong(
|
||||
playlistId: json['playlistId'] as String,
|
||||
songId: json['songId'] as String,
|
||||
position: (json['position'] as num).toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SourcePlaylistSongToJson(_SourcePlaylistSong instance) =>
|
||||
<String, dynamic>{
|
||||
'playlistId': instance.playlistId,
|
||||
'songId': instance.songId,
|
||||
'position': instance.position,
|
||||
};
|
||||
@@ -3,11 +3,11 @@ import 'models.dart';
|
||||
abstract class MusicSource {
|
||||
Future<void> ping();
|
||||
|
||||
Stream<SourceAlbum> allAlbums();
|
||||
Stream<SourceArtist> allArtists();
|
||||
Stream<SourcePlaylist> allPlaylists();
|
||||
Stream<SourceSong> allSongs();
|
||||
Stream<SourcePlaylistSong> allPlaylistSongs();
|
||||
Stream<Album> allAlbums();
|
||||
Stream<Artist> allArtists();
|
||||
Stream<Playlist> allPlaylists();
|
||||
Stream<Song> allSongs();
|
||||
Stream<PlaylistSong> allPlaylistSongs();
|
||||
|
||||
Uri streamUri(String songId);
|
||||
Uri downloadUri(String songId);
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'package:xml/xml.dart';
|
||||
|
||||
import '../models.dart';
|
||||
|
||||
SourceArtist mapArtist(XmlElement e, XmlElement? info) => SourceArtist(
|
||||
Artist mapArtist(XmlElement e, XmlElement? info) => Artist(
|
||||
id: e.getAttribute('id')!,
|
||||
name: e.getAttribute('name')!,
|
||||
starred: DateTime.tryParse(e.getAttribute('starred').toString()),
|
||||
@@ -10,11 +10,11 @@ SourceArtist mapArtist(XmlElement e, XmlElement? info) => SourceArtist(
|
||||
largeImage: Uri.tryParse(info?.getElement('largeImageUrl')?.innerText ?? ''),
|
||||
);
|
||||
|
||||
SourceAlbum mapAlbum(
|
||||
Album mapAlbum(
|
||||
XmlElement e, {
|
||||
int? frequentRank,
|
||||
int? recentRank,
|
||||
}) => SourceAlbum(
|
||||
}) => Album(
|
||||
id: e.getAttribute('id')!,
|
||||
artistId: e.getAttribute('artistId'),
|
||||
name: e.getAttribute('name')!,
|
||||
@@ -28,7 +28,7 @@ SourceAlbum mapAlbum(
|
||||
recentRank: recentRank,
|
||||
);
|
||||
|
||||
SourcePlaylist mapPlaylist(XmlElement e) => SourcePlaylist(
|
||||
Playlist mapPlaylist(XmlElement e) => Playlist(
|
||||
id: e.getAttribute('id')!,
|
||||
name: e.getAttribute('name')!,
|
||||
comment: e.getAttribute('comment'),
|
||||
@@ -36,10 +36,9 @@ SourcePlaylist mapPlaylist(XmlElement e) => SourcePlaylist(
|
||||
created: DateTime.parse(e.getAttribute('created')!),
|
||||
changed: DateTime.parse(e.getAttribute('changed')!),
|
||||
owner: e.getAttribute('owner'),
|
||||
public: bool.tryParse(e.getAttribute('public').toString()),
|
||||
);
|
||||
|
||||
SourceSong mapSong(XmlElement e) => SourceSong(
|
||||
Song mapSong(XmlElement e) => Song(
|
||||
id: e.getAttribute('id')!,
|
||||
albumId: e.getAttribute('albumId'),
|
||||
artistId: e.getAttribute('artistId'),
|
||||
@@ -57,10 +56,10 @@ SourceSong mapSong(XmlElement e) => SourceSong(
|
||||
genre: e.getAttribute('genre'),
|
||||
);
|
||||
|
||||
SourcePlaylistSong mapPlaylistSong(
|
||||
PlaylistSong mapPlaylistSong(
|
||||
int index,
|
||||
XmlElement e,
|
||||
) => SourcePlaylistSong(
|
||||
) => PlaylistSong(
|
||||
playlistId: e.parentElement!.getAttribute('id')!,
|
||||
songId: e.getAttribute('id')!,
|
||||
position: index,
|
||||
|
||||
@@ -41,7 +41,7 @@ class SubsonicSource implements MusicSource {
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<SourceArtist> allArtists() async* {
|
||||
Stream<Artist> allArtists() async* {
|
||||
final getArtistsRes = await _pool.withResource(
|
||||
() => client.get('getArtists'),
|
||||
);
|
||||
@@ -58,7 +58,7 @@ class SubsonicSource implements MusicSource {
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<SourceAlbum> allAlbums() async* {
|
||||
Stream<Album> allAlbums() async* {
|
||||
final extras = await Future.wait([
|
||||
_albumList(
|
||||
'frequent',
|
||||
@@ -89,7 +89,7 @@ class SubsonicSource implements MusicSource {
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<SourcePlaylist> allPlaylists() async* {
|
||||
Stream<Playlist> allPlaylists() async* {
|
||||
final res = await _pool.withResource(() => client.get('getPlaylists'));
|
||||
|
||||
yield* Stream.fromIterable(
|
||||
@@ -98,7 +98,7 @@ class SubsonicSource implements MusicSource {
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<SourcePlaylistSong> allPlaylistSongs() async* {
|
||||
Stream<PlaylistSong> allPlaylistSongs() async* {
|
||||
final allPlaylists = await _pool.withResource(
|
||||
() => client.get('getPlaylists'),
|
||||
);
|
||||
@@ -116,7 +116,7 @@ class SubsonicSource implements MusicSource {
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<SourceSong> allSongs() async* {
|
||||
Stream<Song> allSongs() async* {
|
||||
if (await supportsFastSongSync) {
|
||||
await for (var songs in _songSearch()) {
|
||||
yield* Stream.fromIterable(songs.map(mapSong));
|
||||
|
||||
Reference in New Issue
Block a user