import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:spotify/spotify.dart'; part 'home_feed.freezed.dart'; part 'home_feed.g.dart'; @freezed class SpotifySectionPlaylist with _$SpotifySectionPlaylist { const SpotifySectionPlaylist._(); const factory SpotifySectionPlaylist({ required String description, required String format, required List images, required String name, required String owner, required String uri, }) = _SpotifySectionPlaylist; factory SpotifySectionPlaylist.fromJson(Map json) => _$SpotifySectionPlaylistFromJson(json); String get id => uri.split(":").last; Playlist get asPlaylist { return Playlist() ..id = id ..name = name ..description = description ..collaborative = false ..images = images.map((e) => e.asImage).toList() ..owner = (User()..displayName = "Spotify") ..uri = uri ..type = "playlist"; } } @freezed class SpotifySectionArtist with _$SpotifySectionArtist { const SpotifySectionArtist._(); const factory SpotifySectionArtist({ required String name, required String uri, required List images, }) = _SpotifySectionArtist; factory SpotifySectionArtist.fromJson(Map json) => _$SpotifySectionArtistFromJson(json); String get id => uri.split(":").last; Artist get asArtist { return Artist() ..id = id ..name = name ..images = images.map((e) => e.asImage).toList() ..type = "artist" ..uri = uri; } } @freezed class SpotifySectionAlbum with _$SpotifySectionAlbum { const SpotifySectionAlbum._(); const factory SpotifySectionAlbum({ required List artists, required List images, required String name, required String uri, }) = _SpotifySectionAlbum; factory SpotifySectionAlbum.fromJson(Map json) => _$SpotifySectionAlbumFromJson(json); String get id => uri.split(":").last; Album get asAlbum { return Album() ..id = id ..name = name ..artists = artists.map((a) => a.asArtist).toList() ..albumType = AlbumType.album ..images = images.map((e) => e.asImage).toList() ..uri = uri; } } @freezed class SpotifySectionAlbumArtist with _$SpotifySectionAlbumArtist { const SpotifySectionAlbumArtist._(); const factory SpotifySectionAlbumArtist({ required String name, required String uri, }) = _SpotifySectionAlbumArtist; factory SpotifySectionAlbumArtist.fromJson(Map json) => _$SpotifySectionAlbumArtistFromJson(json); String get id => uri.split(":").last; Artist get asArtist { return Artist() ..id = id ..name = name ..type = "artist" ..uri = uri; } } @freezed class SpotifySectionItemImage with _$SpotifySectionItemImage { const SpotifySectionItemImage._(); const factory SpotifySectionItemImage({ required num? height, required String url, required num? width, }) = _SpotifySectionItemImage; factory SpotifySectionItemImage.fromJson(Map json) => _$SpotifySectionItemImageFromJson(json); Image get asImage { return Image() ..height = height?.toInt() ..width = width?.toInt() ..url = url; } } @freezed class SpotifyHomeFeedSectionItem with _$SpotifyHomeFeedSectionItem { factory SpotifyHomeFeedSectionItem({ required String typename, SpotifySectionPlaylist? playlist, SpotifySectionArtist? artist, SpotifySectionAlbum? album, }) = _SpotifyHomeFeedSectionItem; factory SpotifyHomeFeedSectionItem.fromJson(Map json) => _$SpotifyHomeFeedSectionItemFromJson(json); } @freezed class SpotifyHomeFeedSection with _$SpotifyHomeFeedSection { factory SpotifyHomeFeedSection({ required String typename, String? title, required String uri, required List items, }) = _SpotifyHomeFeedSection; factory SpotifyHomeFeedSection.fromJson(Map json) => _$SpotifyHomeFeedSectionFromJson(json); } @freezed class SpotifyHomeFeed with _$SpotifyHomeFeed { factory SpotifyHomeFeed({ required String greeting, required List sections, }) = _SpotifyHomeFeed; factory SpotifyHomeFeed.fromJson(Map json) => _$SpotifyHomeFeedFromJson(json); } Map transformSectionItemTypeJsonMap( Map json) { final data = json["content"]["data"]; final objType = json["content"]["data"]["__typename"]; return { "typename": json["content"]["__typename"], if (objType == "Playlist") "playlist": { "name": data["name"], "description": data["description"], "format": data["format"], "images": (data["images"]["items"] as List) .expand((j) => j["sources"] as dynamic) .toList() .cast>(), "owner": data["ownerV2"]["data"]["name"], "uri": data["uri"] }, if (objType == "Artist") "artist": { "name": data["profile"]["name"], "uri": data["uri"], "images": data["visuals"]["avatarImage"]["sources"], }, if (objType == "Album") "album": { "name": data["name"], "uri": data["uri"], "images": data["coverArt"]["sources"], "artists": data["artists"]["items"] .map( (artist) => { "name": artist["profile"]["name"], "uri": artist["uri"], }, ) .toList() }, }; } Map transformSectionItemJsonMap(Map json) { return { "typename": json["data"]["__typename"], "title": json["data"]?["title"]?["text"], "uri": json["uri"], "items": (json["sectionItems"]["items"] as List) .map( (data) => transformSectionItemTypeJsonMap(data as Map) as dynamic, ) .where( (w) => w["playlist"] != null || w["artist"] != null || w["album"] != null, ) .toList() .cast>() }; } Map transformHomeFeedJsonMap(Map json) { return { "greeting": json["data"]["home"]["greeting"]["text"], "sections": (json["data"]["home"]["sectionContainer"]["sections"]["items"] as List) .map( (item) => transformSectionItemJsonMap(item as Map) as dynamic, ) .toList() .cast>() }; }