feat(flutter/models): User, ArtistRef, AlbumRef, TrackRef, HomeData
Field names mirror web/src/lib/api/types.ts and the server JSON shape (internal/api/types.go's HomePayload). Hand-written DTOs per spec section 10 -- codegen revisits at ~30 models. Adopts server contract over plan-body mock: - cover_url (not cover_art_url) for artist/album refs - duration_sec (not duration_ms) for albums and tracks - stream_url, disc_number on TrackRef - sort_name/album_count on ArtistRef; sort_title/year/track_count on AlbumRef HomeData section keys match server: recently_added_albums, rediscover_albums, rediscover_artists, most_played_tracks, last_played_artists.
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import 'album.dart';
|
||||
import 'artist.dart';
|
||||
import 'track.dart';
|
||||
|
||||
// Mirrors internal/api/types.go HomePayload and web/src/lib/api/types.ts.
|
||||
// Section keys MUST stay in sync with the server's JSON tags:
|
||||
// recently_added_albums / rediscover_albums / rediscover_artists /
|
||||
// most_played_tracks / last_played_artists.
|
||||
//
|
||||
// Server contract guarantees all five slices are non-nil at JSON encode
|
||||
// time (empty sections render as []), but we still tolerate missing keys
|
||||
// so partial fixtures and offline-degraded responses can be parsed.
|
||||
class HomeData {
|
||||
const HomeData({
|
||||
required this.recentlyAddedAlbums,
|
||||
required this.rediscoverAlbums,
|
||||
required this.rediscoverArtists,
|
||||
required this.mostPlayedTracks,
|
||||
required this.lastPlayedArtists,
|
||||
});
|
||||
|
||||
final List<AlbumRef> recentlyAddedAlbums;
|
||||
final List<AlbumRef> rediscoverAlbums;
|
||||
final List<ArtistRef> rediscoverArtists;
|
||||
final List<TrackRef> mostPlayedTracks;
|
||||
final List<ArtistRef> lastPlayedArtists;
|
||||
|
||||
factory HomeData.fromJson(Map<String, dynamic> j) => HomeData(
|
||||
recentlyAddedAlbums: _list(j, 'recently_added_albums', AlbumRef.fromJson),
|
||||
rediscoverAlbums: _list(j, 'rediscover_albums', AlbumRef.fromJson),
|
||||
rediscoverArtists: _list(j, 'rediscover_artists', ArtistRef.fromJson),
|
||||
mostPlayedTracks: _list(j, 'most_played_tracks', TrackRef.fromJson),
|
||||
lastPlayedArtists: _list(j, 'last_played_artists', ArtistRef.fromJson),
|
||||
);
|
||||
|
||||
static List<T> _list<T>(
|
||||
Map<String, dynamic> j,
|
||||
String key,
|
||||
T Function(Map<String, dynamic>) parse,
|
||||
) {
|
||||
final raw = j[key] as List? ?? const [];
|
||||
return raw
|
||||
.map((e) => parse((e as Map).cast<String, dynamic>()))
|
||||
.toList(growable: false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user