diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 66a8b11..87d5fc6 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -15,6 +15,8 @@ PODS: - flutter_inappwebview_ios/Core (0.0.1): - Flutter - OrderedSet (~> 5.0) + - flutter_native_splash (0.0.1): + - Flutter - flutter_secure_storage (6.0.0): - Flutter - media_kit_libs_ios_audio (1.0.4): @@ -61,6 +63,7 @@ DEPENDENCIES: - Flutter (from `Flutter`) - flutter_broadcasts (from `.symlinks/plugins/flutter_broadcasts/ios`) - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) + - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - media_kit_libs_ios_audio (from `.symlinks/plugins/media_kit_libs_ios_audio/ios`) - media_kit_native_event_loop (from `.symlinks/plugins/media_kit_native_event_loop/ios`) @@ -89,6 +92,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/flutter_broadcasts/ios" flutter_inappwebview_ios: :path: ".symlinks/plugins/flutter_inappwebview_ios/ios" + flutter_native_splash: + :path: ".symlinks/plugins/flutter_native_splash/ios" flutter_secure_storage: :path: ".symlinks/plugins/flutter_secure_storage/ios" media_kit_libs_ios_audio: @@ -115,6 +120,7 @@ SPEC CHECKSUMS: Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_broadcasts: 3ece15b27d8ccbe2132c3df303e7c3401feab882 flutter_inappwebview_ios: 97215cf7d4677db55df76782dbd2930c5e1c1ea0 + flutter_native_splash: edf599c81f74d093a4daf8e17bd7a018854bc778 flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 media_kit_libs_ios_audio: 8f39d96a9c630685dfb844c289bd1d114c486fb3 media_kit_native_event_loop: 99111eded5acbdc9c2738021ea6550dd36ca8837 diff --git a/lib/screens/explore.dart b/lib/screens/explore.dart index 92a5f5f..631701b 100644 --- a/lib/screens/explore.dart +++ b/lib/screens/explore.dart @@ -1,12 +1,16 @@ import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; import 'package:get/get.dart'; +import 'package:intl/intl.dart'; +import 'package:rhythm_box/providers/auth.dart'; import 'package:rhythm_box/providers/recent_played.dart'; import 'package:rhythm_box/providers/spotify.dart'; import 'package:rhythm_box/providers/user_preferences.dart'; import 'package:rhythm_box/services/album.dart'; import 'package:rhythm_box/services/database/database.dart'; +import 'package:rhythm_box/services/spotify/spotify_endpoints.dart'; import 'package:rhythm_box/widgets/playlist/playlist_section.dart'; +import 'package:spotify/spotify.dart'; class ExploreScreen extends StatefulWidget { const ExploreScreen({super.key}); @@ -18,19 +22,23 @@ class ExploreScreen extends StatefulWidget { class _ExploreScreenState extends State { late final SpotifyProvider _spotify = Get.find(); late final RecentlyPlayedProvider _history = Get.find(); + late final AuthenticationProvider _auth = Get.find(); final Map _isLoading = { 'featured': true, 'recently': true, 'newReleases': true, + 'forYou': true, }; List? _featuredPlaylist; List? _recentlyPlaylist; List? _newReleasesPlaylist; + List? _forYouView; Future _pullPlaylist() async { final market = Get.find().state.value.market; + final locale = Get.find().state.value.locale; _featuredPlaylist = (await _spotify.api.playlists.featured.getPage(20)).items!.toList(); @@ -48,6 +56,16 @@ class _ExploreScreenState extends State { ?.map((album) => album.toAlbum()) .toList(); setState(() => _isLoading['newReleases'] = false); + + final customEndpoint = + CustomSpotifyEndpoints(_auth.auth.value?.accessToken.value ?? ''); + final forYouView = await customEndpoint.getView( + 'made-for-x-hub', + market: market, + locale: Intl.canonicalizedLocale(locale.toString()), + ); + _forYouView = forYouView['content']?['items']; + setState(() => _isLoading['forYou'] = false); } @override @@ -65,28 +83,52 @@ class _ExploreScreenState extends State { title: Text('explore'.tr), centerTitle: MediaQuery.of(context).size.width >= 720, ), - body: ListView( - children: [ + body: CustomScrollView( + slivers: [ if (_newReleasesPlaylist?.isNotEmpty ?? false) - PlaylistSection( - isLoading: _isLoading['newReleases']!, - title: 'New Releases', - list: _newReleasesPlaylist, + SliverToBoxAdapter( + child: PlaylistSection( + isLoading: _isLoading['newReleases']!, + title: 'New Releases', + list: _newReleasesPlaylist, + ), ), - if (_newReleasesPlaylist?.isNotEmpty ?? false) const Gap(16), + if (_newReleasesPlaylist?.isNotEmpty ?? false) const SliverGap(16), if (_recentlyPlaylist?.isNotEmpty ?? false) - PlaylistSection( - isLoading: _isLoading['recently']!, - title: 'Recent Played', - list: _recentlyPlaylist, + SliverToBoxAdapter( + child: PlaylistSection( + isLoading: _isLoading['recently']!, + title: 'Recent Played', + list: _recentlyPlaylist, + ), ), - if (_recentlyPlaylist?.isNotEmpty ?? false) const Gap(16), - PlaylistSection( - isLoading: _isLoading['featured']!, - title: 'Featured', - list: _featuredPlaylist, + if (_recentlyPlaylist?.isNotEmpty ?? false) const SliverGap(16), + SliverList.builder( + itemCount: _forYouView?.length ?? 0, + itemBuilder: (context, idx) { + final item = _forYouView![idx]; + final playlists = item['content']?['items'] + ?.where((itemL2) => itemL2['type'] == 'playlist') + .map((itemL2) => PlaylistSimple.fromJson(itemL2)) + .toList() + .cast() ?? + []; + if (playlists.isEmpty) return const SizedBox.shrink(); + return PlaylistSection( + isLoading: false, + title: item['name'] ?? '', + list: playlists, + ).paddingOnly(bottom: 16); + }, ), - const Gap(16), + SliverToBoxAdapter( + child: PlaylistSection( + isLoading: _isLoading['featured']!, + title: 'Featured', + list: _featuredPlaylist, + ), + ), + const SliverGap(16), ], ), ), diff --git a/lib/services/song_link/song_link.freezed.dart b/lib/services/song_link/song_link.freezed.dart old mode 100755 new mode 100644 index 0a1af8a..c704cde --- a/lib/services/song_link/song_link.freezed.dart +++ b/lib/services/song_link/song_link.freezed.dart @@ -30,8 +30,12 @@ mixin _$SongLink { String? get nativeAppUriMobile => throw _privateConstructorUsedError; String? get nativeAppUriDesktop => throw _privateConstructorUsedError; + /// Serializes this SongLink to a JSON map. Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + + /// Create a copy of SongLink + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) $SongLinkCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -63,6 +67,8 @@ class _$SongLinkCopyWithImpl<$Res, $Val extends SongLink> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of SongLink + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -145,6 +151,8 @@ class __$$SongLinkImplCopyWithImpl<$Res> _$SongLinkImpl _value, $Res Function(_$SongLinkImpl) _then) : super(_value, _then); + /// Create a copy of SongLink + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -261,12 +269,14 @@ class _$SongLinkImpl implements _SongLink { other.nativeAppUriDesktop == nativeAppUriDesktop)); } - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) @override int get hashCode => Object.hash(runtimeType, displayName, linkId, platform, show, uniqueId, country, url, nativeAppUriMobile, nativeAppUriDesktop); - @JsonKey(ignore: true) + /// Create a copy of SongLink + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$SongLinkImplCopyWith<_$SongLinkImpl> get copyWith => @@ -313,8 +323,11 @@ abstract class _SongLink implements SongLink { String? get nativeAppUriMobile; @override String? get nativeAppUriDesktop; + + /// Create a copy of SongLink + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$SongLinkImplCopyWith<_$SongLinkImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/lib/services/spotify/spotify_endpoints.dart b/lib/services/spotify/spotify_endpoints.dart new file mode 100644 index 0000000..c6b45a2 --- /dev/null +++ b/lib/services/spotify/spotify_endpoints.dart @@ -0,0 +1,214 @@ +import 'dart:convert'; + +import 'package:dio/dio.dart'; +import 'package:rhythm_box/services/spotify/spotify_feed.dart'; +import 'package:spotify/spotify.dart'; +import 'package:timezone/timezone.dart' as tz; + +class CustomSpotifyEndpoints { + static const _baseUrl = 'https://api.spotify.com/v1'; + final String accessToken; + final Dio _client; + + CustomSpotifyEndpoints(this.accessToken) + : _client = Dio( + BaseOptions( + baseUrl: _baseUrl, + responseType: ResponseType.json, + headers: { + 'content-type': 'application/json', + if (accessToken.isNotEmpty) + 'authorization': 'Bearer $accessToken', + 'accept': 'application/json', + }, + ), + ); + + // views API + + /// Get a single view of given genre + /// + /// Currently known genres are: + /// - new-releases-page + /// - made-for-x-hub (it requires authentication) + /// - my-mix-genres (it requires authentication) + /// - artist-seed-mixes (it requires authentication) + /// - my-mix-decades (it requires authentication) + /// - my-mix-moods (it requires authentication) + /// - podcasts-and-more (it requires authentication) + /// - uniquely-yours-in-hub (it requires authentication) + /// - made-for-x-dailymix (it requires authentication) + /// - made-for-x-discovery (it requires authentication) + Future> getView( + String view, { + int limit = 20, + int contentLimit = 10, + List types = const [ + 'album', + 'playlist', + 'artist', + 'show', + 'station', + 'episode', + 'merch', + 'artist_concerts', + 'uri_link' + ], + String imageStyle = 'gradient_overlay', + String includeExternal = 'audio', + String? locale, + Market? market, + Market? country, + }) async { + if (accessToken.isEmpty) { + throw Exception('[CustomSpotifyEndpoints.getView]: accessToken is empty'); + } + + final queryParams = { + 'limit': limit.toString(), + 'content_limit': contentLimit.toString(), + 'types': types.join(','), + 'image_style': imageStyle, + 'include_external': includeExternal, + 'timestamp': DateTime.now().toUtc().toIso8601String(), + if (locale != null) 'locale': locale, + if (market != null) 'market': market.name, + if (country != null) 'country': country.name, + }.entries.map((e) => '${e.key}=${e.value}').join('&'); + + final res = await _client.getUri( + Uri.parse('$_baseUrl/views/$view?$queryParams'), + ); + + if (res.statusCode == 200) { + return res.data; + } else { + throw Exception( + '[CustomSpotifyEndpoints.getView]: Failed to get view' + '\nStatus code: ${res.statusCode}' + '\nBody: ${res.data}', + ); + } + } + + Future> listGenreSeeds() async { + final res = await _client.getUri( + Uri.parse('$_baseUrl/recommendations/available-genre-seeds'), + ); + + if (res.statusCode == 200) { + final body = res.data; + return List.from(body['genres'] ?? []); + } else { + throw Exception( + '[CustomSpotifyEndpoints.listGenreSeeds]: Failed to get genre seeds' + '\nStatus code: ${res.statusCode}' + '\nBody: ${res.data}', + ); + } + } + + Future getHomeFeed({ + required String spTCookie, + required Market country, + }) async { + final headers = { + 'app-platform': 'WebPlayer', + 'authorization': 'Bearer $accessToken', + 'content-type': 'application/json;charset=UTF-8', + 'dnt': '1', + 'origin': 'https://open.spotify.com', + 'referer': 'https://open.spotify.com/' + }; + final response = await _client.getUri( + Uri( + scheme: 'https', + host: 'api-partner.spotify.com', + path: '/pathfinder/v1/query', + queryParameters: { + 'operationName': 'home', + 'variables': jsonEncode({ + 'timeZone': tz.local.name, + 'sp_t': spTCookie, + 'country': country.name, + 'facet': null, + 'sectionItemsLimit': 10 + }), + 'extensions': jsonEncode( + { + 'persistedQuery': { + 'version': 1, + + /// GraphQL persisted Query hash + /// This can change overtime. We've to lookout for it + /// Docs: https://www.apollographql.com/docs/graphos/operations/persisted-queries/ + 'sha256Hash': + 'eb3fba2d388cf4fc4d696b1757a58584e9538a3b515ea742e9cc9465807340be', + } + }, + ), + }, + ), + options: Options(headers: headers), + ); + + final data = SpotifyHomeFeed.fromJson( + transformHomeFeedJsonMap(response.data), + ); + + return data; + } + + Future getHomeFeedSection( + String sectionUri, { + required String spTCookie, + required Market country, + }) async { + final headers = { + 'app-platform': 'WebPlayer', + 'authorization': 'Bearer $accessToken', + 'content-type': 'application/json;charset=UTF-8', + 'dnt': '1', + 'origin': 'https://open.spotify.com', + 'referer': 'https://open.spotify.com/' + }; + final response = await _client.getUri( + Uri( + scheme: 'https', + host: 'api-partner.spotify.com', + path: '/pathfinder/v1/query', + queryParameters: { + 'operationName': 'homeSection', + 'variables': jsonEncode({ + 'timeZone': tz.local.name, + 'sp_t': spTCookie, + 'country': country.name, + 'uri': sectionUri + }), + 'extensions': jsonEncode( + { + 'persistedQuery': { + 'version': 1, + + /// GraphQL persisted Query hash + /// This can change overtime. We've to lookout for it + /// Docs: https://www.apollographql.com/docs/graphos/operations/persisted-queries/ + 'sha256Hash': + 'eb3fba2d388cf4fc4d696b1757a58584e9538a3b515ea742e9cc9465807340be', + } + }, + ), + }, + ), + options: Options(headers: headers), + ); + + final data = SpotifyHomeFeedSection.fromJson( + transformSectionItemJsonMap( + response.data['data']['homeSections']['sections'][0], + ), + ); + + return data; + } +} diff --git a/lib/services/spotify/spotify_feed.dart b/lib/services/spotify/spotify_feed.dart new file mode 100644 index 0000000..e2966b7 --- /dev/null +++ b/lib/services/spotify/spotify_feed.dart @@ -0,0 +1,247 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:spotify/spotify.dart'; + +part 'spotify_feed.freezed.dart'; +part 'spotify_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>() + }; +} diff --git a/lib/services/spotify/spotify_feed.freezed.dart b/lib/services/spotify/spotify_feed.freezed.dart new file mode 100644 index 0000000..4ee2759 --- /dev/null +++ b/lib/services/spotify/spotify_feed.freezed.dart @@ -0,0 +1,1776 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'spotify_feed.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +SpotifySectionPlaylist _$SpotifySectionPlaylistFromJson( + Map json) { + return _SpotifySectionPlaylist.fromJson(json); +} + +/// @nodoc +mixin _$SpotifySectionPlaylist { + String get description => throw _privateConstructorUsedError; + String get format => throw _privateConstructorUsedError; + List get images => + throw _privateConstructorUsedError; + String get name => throw _privateConstructorUsedError; + String get owner => throw _privateConstructorUsedError; + String get uri => throw _privateConstructorUsedError; + + /// Serializes this SpotifySectionPlaylist to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of SpotifySectionPlaylist + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $SpotifySectionPlaylistCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $SpotifySectionPlaylistCopyWith<$Res> { + factory $SpotifySectionPlaylistCopyWith(SpotifySectionPlaylist value, + $Res Function(SpotifySectionPlaylist) then) = + _$SpotifySectionPlaylistCopyWithImpl<$Res, SpotifySectionPlaylist>; + @useResult + $Res call( + {String description, + String format, + List images, + String name, + String owner, + String uri}); +} + +/// @nodoc +class _$SpotifySectionPlaylistCopyWithImpl<$Res, + $Val extends SpotifySectionPlaylist> + implements $SpotifySectionPlaylistCopyWith<$Res> { + _$SpotifySectionPlaylistCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of SpotifySectionPlaylist + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? description = null, + Object? format = null, + Object? images = null, + Object? name = null, + Object? owner = null, + Object? uri = null, + }) { + return _then(_value.copyWith( + description: null == description + ? _value.description + : description // ignore: cast_nullable_to_non_nullable + as String, + format: null == format + ? _value.format + : format // ignore: cast_nullable_to_non_nullable + as String, + images: null == images + ? _value.images + : images // ignore: cast_nullable_to_non_nullable + as List, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + owner: null == owner + ? _value.owner + : owner // ignore: cast_nullable_to_non_nullable + as String, + uri: null == uri + ? _value.uri + : uri // ignore: cast_nullable_to_non_nullable + as String, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$SpotifySectionPlaylistImplCopyWith<$Res> + implements $SpotifySectionPlaylistCopyWith<$Res> { + factory _$$SpotifySectionPlaylistImplCopyWith( + _$SpotifySectionPlaylistImpl value, + $Res Function(_$SpotifySectionPlaylistImpl) then) = + __$$SpotifySectionPlaylistImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String description, + String format, + List images, + String name, + String owner, + String uri}); +} + +/// @nodoc +class __$$SpotifySectionPlaylistImplCopyWithImpl<$Res> + extends _$SpotifySectionPlaylistCopyWithImpl<$Res, + _$SpotifySectionPlaylistImpl> + implements _$$SpotifySectionPlaylistImplCopyWith<$Res> { + __$$SpotifySectionPlaylistImplCopyWithImpl( + _$SpotifySectionPlaylistImpl _value, + $Res Function(_$SpotifySectionPlaylistImpl) _then) + : super(_value, _then); + + /// Create a copy of SpotifySectionPlaylist + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? description = null, + Object? format = null, + Object? images = null, + Object? name = null, + Object? owner = null, + Object? uri = null, + }) { + return _then(_$SpotifySectionPlaylistImpl( + description: null == description + ? _value.description + : description // ignore: cast_nullable_to_non_nullable + as String, + format: null == format + ? _value.format + : format // ignore: cast_nullable_to_non_nullable + as String, + images: null == images + ? _value._images + : images // ignore: cast_nullable_to_non_nullable + as List, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + owner: null == owner + ? _value.owner + : owner // ignore: cast_nullable_to_non_nullable + as String, + uri: null == uri + ? _value.uri + : uri // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$SpotifySectionPlaylistImpl extends _SpotifySectionPlaylist { + const _$SpotifySectionPlaylistImpl( + {required this.description, + required this.format, + required final List images, + required this.name, + required this.owner, + required this.uri}) + : _images = images, + super._(); + + factory _$SpotifySectionPlaylistImpl.fromJson(Map json) => + _$$SpotifySectionPlaylistImplFromJson(json); + + @override + final String description; + @override + final String format; + final List _images; + @override + List get images { + if (_images is EqualUnmodifiableListView) return _images; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_images); + } + + @override + final String name; + @override + final String owner; + @override + final String uri; + + @override + String toString() { + return 'SpotifySectionPlaylist(description: $description, format: $format, images: $images, name: $name, owner: $owner, uri: $uri)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SpotifySectionPlaylistImpl && + (identical(other.description, description) || + other.description == description) && + (identical(other.format, format) || other.format == format) && + const DeepCollectionEquality().equals(other._images, _images) && + (identical(other.name, name) || other.name == name) && + (identical(other.owner, owner) || other.owner == owner) && + (identical(other.uri, uri) || other.uri == uri)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, description, format, + const DeepCollectionEquality().hash(_images), name, owner, uri); + + /// Create a copy of SpotifySectionPlaylist + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SpotifySectionPlaylistImplCopyWith<_$SpotifySectionPlaylistImpl> + get copyWith => __$$SpotifySectionPlaylistImplCopyWithImpl< + _$SpotifySectionPlaylistImpl>(this, _$identity); + + @override + Map toJson() { + return _$$SpotifySectionPlaylistImplToJson( + this, + ); + } +} + +abstract class _SpotifySectionPlaylist extends SpotifySectionPlaylist { + const factory _SpotifySectionPlaylist( + {required final String description, + required final String format, + required final List images, + required final String name, + required final String owner, + required final String uri}) = _$SpotifySectionPlaylistImpl; + const _SpotifySectionPlaylist._() : super._(); + + factory _SpotifySectionPlaylist.fromJson(Map json) = + _$SpotifySectionPlaylistImpl.fromJson; + + @override + String get description; + @override + String get format; + @override + List get images; + @override + String get name; + @override + String get owner; + @override + String get uri; + + /// Create a copy of SpotifySectionPlaylist + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SpotifySectionPlaylistImplCopyWith<_$SpotifySectionPlaylistImpl> + get copyWith => throw _privateConstructorUsedError; +} + +SpotifySectionArtist _$SpotifySectionArtistFromJson(Map json) { + return _SpotifySectionArtist.fromJson(json); +} + +/// @nodoc +mixin _$SpotifySectionArtist { + String get name => throw _privateConstructorUsedError; + String get uri => throw _privateConstructorUsedError; + List get images => + throw _privateConstructorUsedError; + + /// Serializes this SpotifySectionArtist to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of SpotifySectionArtist + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $SpotifySectionArtistCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $SpotifySectionArtistCopyWith<$Res> { + factory $SpotifySectionArtistCopyWith(SpotifySectionArtist value, + $Res Function(SpotifySectionArtist) then) = + _$SpotifySectionArtistCopyWithImpl<$Res, SpotifySectionArtist>; + @useResult + $Res call({String name, String uri, List images}); +} + +/// @nodoc +class _$SpotifySectionArtistCopyWithImpl<$Res, + $Val extends SpotifySectionArtist> + implements $SpotifySectionArtistCopyWith<$Res> { + _$SpotifySectionArtistCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of SpotifySectionArtist + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? name = null, + Object? uri = null, + Object? images = null, + }) { + return _then(_value.copyWith( + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + uri: null == uri + ? _value.uri + : uri // ignore: cast_nullable_to_non_nullable + as String, + images: null == images + ? _value.images + : images // ignore: cast_nullable_to_non_nullable + as List, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$SpotifySectionArtistImplCopyWith<$Res> + implements $SpotifySectionArtistCopyWith<$Res> { + factory _$$SpotifySectionArtistImplCopyWith(_$SpotifySectionArtistImpl value, + $Res Function(_$SpotifySectionArtistImpl) then) = + __$$SpotifySectionArtistImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({String name, String uri, List images}); +} + +/// @nodoc +class __$$SpotifySectionArtistImplCopyWithImpl<$Res> + extends _$SpotifySectionArtistCopyWithImpl<$Res, _$SpotifySectionArtistImpl> + implements _$$SpotifySectionArtistImplCopyWith<$Res> { + __$$SpotifySectionArtistImplCopyWithImpl(_$SpotifySectionArtistImpl _value, + $Res Function(_$SpotifySectionArtistImpl) _then) + : super(_value, _then); + + /// Create a copy of SpotifySectionArtist + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? name = null, + Object? uri = null, + Object? images = null, + }) { + return _then(_$SpotifySectionArtistImpl( + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + uri: null == uri + ? _value.uri + : uri // ignore: cast_nullable_to_non_nullable + as String, + images: null == images + ? _value._images + : images // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$SpotifySectionArtistImpl extends _SpotifySectionArtist { + const _$SpotifySectionArtistImpl( + {required this.name, + required this.uri, + required final List images}) + : _images = images, + super._(); + + factory _$SpotifySectionArtistImpl.fromJson(Map json) => + _$$SpotifySectionArtistImplFromJson(json); + + @override + final String name; + @override + final String uri; + final List _images; + @override + List get images { + if (_images is EqualUnmodifiableListView) return _images; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_images); + } + + @override + String toString() { + return 'SpotifySectionArtist(name: $name, uri: $uri, images: $images)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SpotifySectionArtistImpl && + (identical(other.name, name) || other.name == name) && + (identical(other.uri, uri) || other.uri == uri) && + const DeepCollectionEquality().equals(other._images, _images)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, name, uri, const DeepCollectionEquality().hash(_images)); + + /// Create a copy of SpotifySectionArtist + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SpotifySectionArtistImplCopyWith<_$SpotifySectionArtistImpl> + get copyWith => + __$$SpotifySectionArtistImplCopyWithImpl<_$SpotifySectionArtistImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$SpotifySectionArtistImplToJson( + this, + ); + } +} + +abstract class _SpotifySectionArtist extends SpotifySectionArtist { + const factory _SpotifySectionArtist( + {required final String name, + required final String uri, + required final List images}) = + _$SpotifySectionArtistImpl; + const _SpotifySectionArtist._() : super._(); + + factory _SpotifySectionArtist.fromJson(Map json) = + _$SpotifySectionArtistImpl.fromJson; + + @override + String get name; + @override + String get uri; + @override + List get images; + + /// Create a copy of SpotifySectionArtist + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SpotifySectionArtistImplCopyWith<_$SpotifySectionArtistImpl> + get copyWith => throw _privateConstructorUsedError; +} + +SpotifySectionAlbum _$SpotifySectionAlbumFromJson(Map json) { + return _SpotifySectionAlbum.fromJson(json); +} + +/// @nodoc +mixin _$SpotifySectionAlbum { + List get artists => + throw _privateConstructorUsedError; + List get images => + throw _privateConstructorUsedError; + String get name => throw _privateConstructorUsedError; + String get uri => throw _privateConstructorUsedError; + + /// Serializes this SpotifySectionAlbum to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of SpotifySectionAlbum + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $SpotifySectionAlbumCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $SpotifySectionAlbumCopyWith<$Res> { + factory $SpotifySectionAlbumCopyWith( + SpotifySectionAlbum value, $Res Function(SpotifySectionAlbum) then) = + _$SpotifySectionAlbumCopyWithImpl<$Res, SpotifySectionAlbum>; + @useResult + $Res call( + {List artists, + List images, + String name, + String uri}); +} + +/// @nodoc +class _$SpotifySectionAlbumCopyWithImpl<$Res, $Val extends SpotifySectionAlbum> + implements $SpotifySectionAlbumCopyWith<$Res> { + _$SpotifySectionAlbumCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of SpotifySectionAlbum + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? artists = null, + Object? images = null, + Object? name = null, + Object? uri = null, + }) { + return _then(_value.copyWith( + artists: null == artists + ? _value.artists + : artists // ignore: cast_nullable_to_non_nullable + as List, + images: null == images + ? _value.images + : images // ignore: cast_nullable_to_non_nullable + as List, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + uri: null == uri + ? _value.uri + : uri // ignore: cast_nullable_to_non_nullable + as String, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$SpotifySectionAlbumImplCopyWith<$Res> + implements $SpotifySectionAlbumCopyWith<$Res> { + factory _$$SpotifySectionAlbumImplCopyWith(_$SpotifySectionAlbumImpl value, + $Res Function(_$SpotifySectionAlbumImpl) then) = + __$$SpotifySectionAlbumImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {List artists, + List images, + String name, + String uri}); +} + +/// @nodoc +class __$$SpotifySectionAlbumImplCopyWithImpl<$Res> + extends _$SpotifySectionAlbumCopyWithImpl<$Res, _$SpotifySectionAlbumImpl> + implements _$$SpotifySectionAlbumImplCopyWith<$Res> { + __$$SpotifySectionAlbumImplCopyWithImpl(_$SpotifySectionAlbumImpl _value, + $Res Function(_$SpotifySectionAlbumImpl) _then) + : super(_value, _then); + + /// Create a copy of SpotifySectionAlbum + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? artists = null, + Object? images = null, + Object? name = null, + Object? uri = null, + }) { + return _then(_$SpotifySectionAlbumImpl( + artists: null == artists + ? _value._artists + : artists // ignore: cast_nullable_to_non_nullable + as List, + images: null == images + ? _value._images + : images // ignore: cast_nullable_to_non_nullable + as List, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + uri: null == uri + ? _value.uri + : uri // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$SpotifySectionAlbumImpl extends _SpotifySectionAlbum { + const _$SpotifySectionAlbumImpl( + {required final List artists, + required final List images, + required this.name, + required this.uri}) + : _artists = artists, + _images = images, + super._(); + + factory _$SpotifySectionAlbumImpl.fromJson(Map json) => + _$$SpotifySectionAlbumImplFromJson(json); + + final List _artists; + @override + List get artists { + if (_artists is EqualUnmodifiableListView) return _artists; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_artists); + } + + final List _images; + @override + List get images { + if (_images is EqualUnmodifiableListView) return _images; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_images); + } + + @override + final String name; + @override + final String uri; + + @override + String toString() { + return 'SpotifySectionAlbum(artists: $artists, images: $images, name: $name, uri: $uri)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SpotifySectionAlbumImpl && + const DeepCollectionEquality().equals(other._artists, _artists) && + const DeepCollectionEquality().equals(other._images, _images) && + (identical(other.name, name) || other.name == name) && + (identical(other.uri, uri) || other.uri == uri)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(_artists), + const DeepCollectionEquality().hash(_images), + name, + uri); + + /// Create a copy of SpotifySectionAlbum + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SpotifySectionAlbumImplCopyWith<_$SpotifySectionAlbumImpl> get copyWith => + __$$SpotifySectionAlbumImplCopyWithImpl<_$SpotifySectionAlbumImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$SpotifySectionAlbumImplToJson( + this, + ); + } +} + +abstract class _SpotifySectionAlbum extends SpotifySectionAlbum { + const factory _SpotifySectionAlbum( + {required final List artists, + required final List images, + required final String name, + required final String uri}) = _$SpotifySectionAlbumImpl; + const _SpotifySectionAlbum._() : super._(); + + factory _SpotifySectionAlbum.fromJson(Map json) = + _$SpotifySectionAlbumImpl.fromJson; + + @override + List get artists; + @override + List get images; + @override + String get name; + @override + String get uri; + + /// Create a copy of SpotifySectionAlbum + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SpotifySectionAlbumImplCopyWith<_$SpotifySectionAlbumImpl> get copyWith => + throw _privateConstructorUsedError; +} + +SpotifySectionAlbumArtist _$SpotifySectionAlbumArtistFromJson( + Map json) { + return _SpotifySectionAlbumArtist.fromJson(json); +} + +/// @nodoc +mixin _$SpotifySectionAlbumArtist { + String get name => throw _privateConstructorUsedError; + String get uri => throw _privateConstructorUsedError; + + /// Serializes this SpotifySectionAlbumArtist to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of SpotifySectionAlbumArtist + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $SpotifySectionAlbumArtistCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $SpotifySectionAlbumArtistCopyWith<$Res> { + factory $SpotifySectionAlbumArtistCopyWith(SpotifySectionAlbumArtist value, + $Res Function(SpotifySectionAlbumArtist) then) = + _$SpotifySectionAlbumArtistCopyWithImpl<$Res, SpotifySectionAlbumArtist>; + @useResult + $Res call({String name, String uri}); +} + +/// @nodoc +class _$SpotifySectionAlbumArtistCopyWithImpl<$Res, + $Val extends SpotifySectionAlbumArtist> + implements $SpotifySectionAlbumArtistCopyWith<$Res> { + _$SpotifySectionAlbumArtistCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of SpotifySectionAlbumArtist + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? name = null, + Object? uri = null, + }) { + return _then(_value.copyWith( + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + uri: null == uri + ? _value.uri + : uri // ignore: cast_nullable_to_non_nullable + as String, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$SpotifySectionAlbumArtistImplCopyWith<$Res> + implements $SpotifySectionAlbumArtistCopyWith<$Res> { + factory _$$SpotifySectionAlbumArtistImplCopyWith( + _$SpotifySectionAlbumArtistImpl value, + $Res Function(_$SpotifySectionAlbumArtistImpl) then) = + __$$SpotifySectionAlbumArtistImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({String name, String uri}); +} + +/// @nodoc +class __$$SpotifySectionAlbumArtistImplCopyWithImpl<$Res> + extends _$SpotifySectionAlbumArtistCopyWithImpl<$Res, + _$SpotifySectionAlbumArtistImpl> + implements _$$SpotifySectionAlbumArtistImplCopyWith<$Res> { + __$$SpotifySectionAlbumArtistImplCopyWithImpl( + _$SpotifySectionAlbumArtistImpl _value, + $Res Function(_$SpotifySectionAlbumArtistImpl) _then) + : super(_value, _then); + + /// Create a copy of SpotifySectionAlbumArtist + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? name = null, + Object? uri = null, + }) { + return _then(_$SpotifySectionAlbumArtistImpl( + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + uri: null == uri + ? _value.uri + : uri // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$SpotifySectionAlbumArtistImpl extends _SpotifySectionAlbumArtist { + const _$SpotifySectionAlbumArtistImpl({required this.name, required this.uri}) + : super._(); + + factory _$SpotifySectionAlbumArtistImpl.fromJson(Map json) => + _$$SpotifySectionAlbumArtistImplFromJson(json); + + @override + final String name; + @override + final String uri; + + @override + String toString() { + return 'SpotifySectionAlbumArtist(name: $name, uri: $uri)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SpotifySectionAlbumArtistImpl && + (identical(other.name, name) || other.name == name) && + (identical(other.uri, uri) || other.uri == uri)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, name, uri); + + /// Create a copy of SpotifySectionAlbumArtist + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SpotifySectionAlbumArtistImplCopyWith<_$SpotifySectionAlbumArtistImpl> + get copyWith => __$$SpotifySectionAlbumArtistImplCopyWithImpl< + _$SpotifySectionAlbumArtistImpl>(this, _$identity); + + @override + Map toJson() { + return _$$SpotifySectionAlbumArtistImplToJson( + this, + ); + } +} + +abstract class _SpotifySectionAlbumArtist extends SpotifySectionAlbumArtist { + const factory _SpotifySectionAlbumArtist( + {required final String name, + required final String uri}) = _$SpotifySectionAlbumArtistImpl; + const _SpotifySectionAlbumArtist._() : super._(); + + factory _SpotifySectionAlbumArtist.fromJson(Map json) = + _$SpotifySectionAlbumArtistImpl.fromJson; + + @override + String get name; + @override + String get uri; + + /// Create a copy of SpotifySectionAlbumArtist + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SpotifySectionAlbumArtistImplCopyWith<_$SpotifySectionAlbumArtistImpl> + get copyWith => throw _privateConstructorUsedError; +} + +SpotifySectionItemImage _$SpotifySectionItemImageFromJson( + Map json) { + return _SpotifySectionItemImage.fromJson(json); +} + +/// @nodoc +mixin _$SpotifySectionItemImage { + num? get height => throw _privateConstructorUsedError; + String get url => throw _privateConstructorUsedError; + num? get width => throw _privateConstructorUsedError; + + /// Serializes this SpotifySectionItemImage to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of SpotifySectionItemImage + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $SpotifySectionItemImageCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $SpotifySectionItemImageCopyWith<$Res> { + factory $SpotifySectionItemImageCopyWith(SpotifySectionItemImage value, + $Res Function(SpotifySectionItemImage) then) = + _$SpotifySectionItemImageCopyWithImpl<$Res, SpotifySectionItemImage>; + @useResult + $Res call({num? height, String url, num? width}); +} + +/// @nodoc +class _$SpotifySectionItemImageCopyWithImpl<$Res, + $Val extends SpotifySectionItemImage> + implements $SpotifySectionItemImageCopyWith<$Res> { + _$SpotifySectionItemImageCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of SpotifySectionItemImage + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? height = freezed, + Object? url = null, + Object? width = freezed, + }) { + return _then(_value.copyWith( + height: freezed == height + ? _value.height + : height // ignore: cast_nullable_to_non_nullable + as num?, + url: null == url + ? _value.url + : url // ignore: cast_nullable_to_non_nullable + as String, + width: freezed == width + ? _value.width + : width // ignore: cast_nullable_to_non_nullable + as num?, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$SpotifySectionItemImageImplCopyWith<$Res> + implements $SpotifySectionItemImageCopyWith<$Res> { + factory _$$SpotifySectionItemImageImplCopyWith( + _$SpotifySectionItemImageImpl value, + $Res Function(_$SpotifySectionItemImageImpl) then) = + __$$SpotifySectionItemImageImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({num? height, String url, num? width}); +} + +/// @nodoc +class __$$SpotifySectionItemImageImplCopyWithImpl<$Res> + extends _$SpotifySectionItemImageCopyWithImpl<$Res, + _$SpotifySectionItemImageImpl> + implements _$$SpotifySectionItemImageImplCopyWith<$Res> { + __$$SpotifySectionItemImageImplCopyWithImpl( + _$SpotifySectionItemImageImpl _value, + $Res Function(_$SpotifySectionItemImageImpl) _then) + : super(_value, _then); + + /// Create a copy of SpotifySectionItemImage + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? height = freezed, + Object? url = null, + Object? width = freezed, + }) { + return _then(_$SpotifySectionItemImageImpl( + height: freezed == height + ? _value.height + : height // ignore: cast_nullable_to_non_nullable + as num?, + url: null == url + ? _value.url + : url // ignore: cast_nullable_to_non_nullable + as String, + width: freezed == width + ? _value.width + : width // ignore: cast_nullable_to_non_nullable + as num?, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$SpotifySectionItemImageImpl extends _SpotifySectionItemImage { + const _$SpotifySectionItemImageImpl( + {required this.height, required this.url, required this.width}) + : super._(); + + factory _$SpotifySectionItemImageImpl.fromJson(Map json) => + _$$SpotifySectionItemImageImplFromJson(json); + + @override + final num? height; + @override + final String url; + @override + final num? width; + + @override + String toString() { + return 'SpotifySectionItemImage(height: $height, url: $url, width: $width)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SpotifySectionItemImageImpl && + (identical(other.height, height) || other.height == height) && + (identical(other.url, url) || other.url == url) && + (identical(other.width, width) || other.width == width)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, height, url, width); + + /// Create a copy of SpotifySectionItemImage + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SpotifySectionItemImageImplCopyWith<_$SpotifySectionItemImageImpl> + get copyWith => __$$SpotifySectionItemImageImplCopyWithImpl< + _$SpotifySectionItemImageImpl>(this, _$identity); + + @override + Map toJson() { + return _$$SpotifySectionItemImageImplToJson( + this, + ); + } +} + +abstract class _SpotifySectionItemImage extends SpotifySectionItemImage { + const factory _SpotifySectionItemImage( + {required final num? height, + required final String url, + required final num? width}) = _$SpotifySectionItemImageImpl; + const _SpotifySectionItemImage._() : super._(); + + factory _SpotifySectionItemImage.fromJson(Map json) = + _$SpotifySectionItemImageImpl.fromJson; + + @override + num? get height; + @override + String get url; + @override + num? get width; + + /// Create a copy of SpotifySectionItemImage + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SpotifySectionItemImageImplCopyWith<_$SpotifySectionItemImageImpl> + get copyWith => throw _privateConstructorUsedError; +} + +SpotifyHomeFeedSectionItem _$SpotifyHomeFeedSectionItemFromJson( + Map json) { + return _SpotifyHomeFeedSectionItem.fromJson(json); +} + +/// @nodoc +mixin _$SpotifyHomeFeedSectionItem { + String get typename => throw _privateConstructorUsedError; + SpotifySectionPlaylist? get playlist => throw _privateConstructorUsedError; + SpotifySectionArtist? get artist => throw _privateConstructorUsedError; + SpotifySectionAlbum? get album => throw _privateConstructorUsedError; + + /// Serializes this SpotifyHomeFeedSectionItem to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of SpotifyHomeFeedSectionItem + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $SpotifyHomeFeedSectionItemCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $SpotifyHomeFeedSectionItemCopyWith<$Res> { + factory $SpotifyHomeFeedSectionItemCopyWith(SpotifyHomeFeedSectionItem value, + $Res Function(SpotifyHomeFeedSectionItem) then) = + _$SpotifyHomeFeedSectionItemCopyWithImpl<$Res, + SpotifyHomeFeedSectionItem>; + @useResult + $Res call( + {String typename, + SpotifySectionPlaylist? playlist, + SpotifySectionArtist? artist, + SpotifySectionAlbum? album}); + + $SpotifySectionPlaylistCopyWith<$Res>? get playlist; + $SpotifySectionArtistCopyWith<$Res>? get artist; + $SpotifySectionAlbumCopyWith<$Res>? get album; +} + +/// @nodoc +class _$SpotifyHomeFeedSectionItemCopyWithImpl<$Res, + $Val extends SpotifyHomeFeedSectionItem> + implements $SpotifyHomeFeedSectionItemCopyWith<$Res> { + _$SpotifyHomeFeedSectionItemCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of SpotifyHomeFeedSectionItem + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? typename = null, + Object? playlist = freezed, + Object? artist = freezed, + Object? album = freezed, + }) { + return _then(_value.copyWith( + typename: null == typename + ? _value.typename + : typename // ignore: cast_nullable_to_non_nullable + as String, + playlist: freezed == playlist + ? _value.playlist + : playlist // ignore: cast_nullable_to_non_nullable + as SpotifySectionPlaylist?, + artist: freezed == artist + ? _value.artist + : artist // ignore: cast_nullable_to_non_nullable + as SpotifySectionArtist?, + album: freezed == album + ? _value.album + : album // ignore: cast_nullable_to_non_nullable + as SpotifySectionAlbum?, + ) as $Val); + } + + /// Create a copy of SpotifyHomeFeedSectionItem + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $SpotifySectionPlaylistCopyWith<$Res>? get playlist { + if (_value.playlist == null) { + return null; + } + + return $SpotifySectionPlaylistCopyWith<$Res>(_value.playlist!, (value) { + return _then(_value.copyWith(playlist: value) as $Val); + }); + } + + /// Create a copy of SpotifyHomeFeedSectionItem + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $SpotifySectionArtistCopyWith<$Res>? get artist { + if (_value.artist == null) { + return null; + } + + return $SpotifySectionArtistCopyWith<$Res>(_value.artist!, (value) { + return _then(_value.copyWith(artist: value) as $Val); + }); + } + + /// Create a copy of SpotifyHomeFeedSectionItem + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $SpotifySectionAlbumCopyWith<$Res>? get album { + if (_value.album == null) { + return null; + } + + return $SpotifySectionAlbumCopyWith<$Res>(_value.album!, (value) { + return _then(_value.copyWith(album: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$SpotifyHomeFeedSectionItemImplCopyWith<$Res> + implements $SpotifyHomeFeedSectionItemCopyWith<$Res> { + factory _$$SpotifyHomeFeedSectionItemImplCopyWith( + _$SpotifyHomeFeedSectionItemImpl value, + $Res Function(_$SpotifyHomeFeedSectionItemImpl) then) = + __$$SpotifyHomeFeedSectionItemImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String typename, + SpotifySectionPlaylist? playlist, + SpotifySectionArtist? artist, + SpotifySectionAlbum? album}); + + @override + $SpotifySectionPlaylistCopyWith<$Res>? get playlist; + @override + $SpotifySectionArtistCopyWith<$Res>? get artist; + @override + $SpotifySectionAlbumCopyWith<$Res>? get album; +} + +/// @nodoc +class __$$SpotifyHomeFeedSectionItemImplCopyWithImpl<$Res> + extends _$SpotifyHomeFeedSectionItemCopyWithImpl<$Res, + _$SpotifyHomeFeedSectionItemImpl> + implements _$$SpotifyHomeFeedSectionItemImplCopyWith<$Res> { + __$$SpotifyHomeFeedSectionItemImplCopyWithImpl( + _$SpotifyHomeFeedSectionItemImpl _value, + $Res Function(_$SpotifyHomeFeedSectionItemImpl) _then) + : super(_value, _then); + + /// Create a copy of SpotifyHomeFeedSectionItem + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? typename = null, + Object? playlist = freezed, + Object? artist = freezed, + Object? album = freezed, + }) { + return _then(_$SpotifyHomeFeedSectionItemImpl( + typename: null == typename + ? _value.typename + : typename // ignore: cast_nullable_to_non_nullable + as String, + playlist: freezed == playlist + ? _value.playlist + : playlist // ignore: cast_nullable_to_non_nullable + as SpotifySectionPlaylist?, + artist: freezed == artist + ? _value.artist + : artist // ignore: cast_nullable_to_non_nullable + as SpotifySectionArtist?, + album: freezed == album + ? _value.album + : album // ignore: cast_nullable_to_non_nullable + as SpotifySectionAlbum?, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$SpotifyHomeFeedSectionItemImpl implements _SpotifyHomeFeedSectionItem { + _$SpotifyHomeFeedSectionItemImpl( + {required this.typename, this.playlist, this.artist, this.album}); + + factory _$SpotifyHomeFeedSectionItemImpl.fromJson( + Map json) => + _$$SpotifyHomeFeedSectionItemImplFromJson(json); + + @override + final String typename; + @override + final SpotifySectionPlaylist? playlist; + @override + final SpotifySectionArtist? artist; + @override + final SpotifySectionAlbum? album; + + @override + String toString() { + return 'SpotifyHomeFeedSectionItem(typename: $typename, playlist: $playlist, artist: $artist, album: $album)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SpotifyHomeFeedSectionItemImpl && + (identical(other.typename, typename) || + other.typename == typename) && + (identical(other.playlist, playlist) || + other.playlist == playlist) && + (identical(other.artist, artist) || other.artist == artist) && + (identical(other.album, album) || other.album == album)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => + Object.hash(runtimeType, typename, playlist, artist, album); + + /// Create a copy of SpotifyHomeFeedSectionItem + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SpotifyHomeFeedSectionItemImplCopyWith<_$SpotifyHomeFeedSectionItemImpl> + get copyWith => __$$SpotifyHomeFeedSectionItemImplCopyWithImpl< + _$SpotifyHomeFeedSectionItemImpl>(this, _$identity); + + @override + Map toJson() { + return _$$SpotifyHomeFeedSectionItemImplToJson( + this, + ); + } +} + +abstract class _SpotifyHomeFeedSectionItem + implements SpotifyHomeFeedSectionItem { + factory _SpotifyHomeFeedSectionItem( + {required final String typename, + final SpotifySectionPlaylist? playlist, + final SpotifySectionArtist? artist, + final SpotifySectionAlbum? album}) = _$SpotifyHomeFeedSectionItemImpl; + + factory _SpotifyHomeFeedSectionItem.fromJson(Map json) = + _$SpotifyHomeFeedSectionItemImpl.fromJson; + + @override + String get typename; + @override + SpotifySectionPlaylist? get playlist; + @override + SpotifySectionArtist? get artist; + @override + SpotifySectionAlbum? get album; + + /// Create a copy of SpotifyHomeFeedSectionItem + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SpotifyHomeFeedSectionItemImplCopyWith<_$SpotifyHomeFeedSectionItemImpl> + get copyWith => throw _privateConstructorUsedError; +} + +SpotifyHomeFeedSection _$SpotifyHomeFeedSectionFromJson( + Map json) { + return _SpotifyHomeFeedSection.fromJson(json); +} + +/// @nodoc +mixin _$SpotifyHomeFeedSection { + String get typename => throw _privateConstructorUsedError; + String? get title => throw _privateConstructorUsedError; + String get uri => throw _privateConstructorUsedError; + List get items => + throw _privateConstructorUsedError; + + /// Serializes this SpotifyHomeFeedSection to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of SpotifyHomeFeedSection + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $SpotifyHomeFeedSectionCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $SpotifyHomeFeedSectionCopyWith<$Res> { + factory $SpotifyHomeFeedSectionCopyWith(SpotifyHomeFeedSection value, + $Res Function(SpotifyHomeFeedSection) then) = + _$SpotifyHomeFeedSectionCopyWithImpl<$Res, SpotifyHomeFeedSection>; + @useResult + $Res call( + {String typename, + String? title, + String uri, + List items}); +} + +/// @nodoc +class _$SpotifyHomeFeedSectionCopyWithImpl<$Res, + $Val extends SpotifyHomeFeedSection> + implements $SpotifyHomeFeedSectionCopyWith<$Res> { + _$SpotifyHomeFeedSectionCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of SpotifyHomeFeedSection + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? typename = null, + Object? title = freezed, + Object? uri = null, + Object? items = null, + }) { + return _then(_value.copyWith( + typename: null == typename + ? _value.typename + : typename // ignore: cast_nullable_to_non_nullable + as String, + title: freezed == title + ? _value.title + : title // ignore: cast_nullable_to_non_nullable + as String?, + uri: null == uri + ? _value.uri + : uri // ignore: cast_nullable_to_non_nullable + as String, + items: null == items + ? _value.items + : items // ignore: cast_nullable_to_non_nullable + as List, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$SpotifyHomeFeedSectionImplCopyWith<$Res> + implements $SpotifyHomeFeedSectionCopyWith<$Res> { + factory _$$SpotifyHomeFeedSectionImplCopyWith( + _$SpotifyHomeFeedSectionImpl value, + $Res Function(_$SpotifyHomeFeedSectionImpl) then) = + __$$SpotifyHomeFeedSectionImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String typename, + String? title, + String uri, + List items}); +} + +/// @nodoc +class __$$SpotifyHomeFeedSectionImplCopyWithImpl<$Res> + extends _$SpotifyHomeFeedSectionCopyWithImpl<$Res, + _$SpotifyHomeFeedSectionImpl> + implements _$$SpotifyHomeFeedSectionImplCopyWith<$Res> { + __$$SpotifyHomeFeedSectionImplCopyWithImpl( + _$SpotifyHomeFeedSectionImpl _value, + $Res Function(_$SpotifyHomeFeedSectionImpl) _then) + : super(_value, _then); + + /// Create a copy of SpotifyHomeFeedSection + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? typename = null, + Object? title = freezed, + Object? uri = null, + Object? items = null, + }) { + return _then(_$SpotifyHomeFeedSectionImpl( + typename: null == typename + ? _value.typename + : typename // ignore: cast_nullable_to_non_nullable + as String, + title: freezed == title + ? _value.title + : title // ignore: cast_nullable_to_non_nullable + as String?, + uri: null == uri + ? _value.uri + : uri // ignore: cast_nullable_to_non_nullable + as String, + items: null == items + ? _value._items + : items // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$SpotifyHomeFeedSectionImpl implements _SpotifyHomeFeedSection { + _$SpotifyHomeFeedSectionImpl( + {required this.typename, + this.title, + required this.uri, + required final List items}) + : _items = items; + + factory _$SpotifyHomeFeedSectionImpl.fromJson(Map json) => + _$$SpotifyHomeFeedSectionImplFromJson(json); + + @override + final String typename; + @override + final String? title; + @override + final String uri; + final List _items; + @override + List get items { + if (_items is EqualUnmodifiableListView) return _items; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_items); + } + + @override + String toString() { + return 'SpotifyHomeFeedSection(typename: $typename, title: $title, uri: $uri, items: $items)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SpotifyHomeFeedSectionImpl && + (identical(other.typename, typename) || + other.typename == typename) && + (identical(other.title, title) || other.title == title) && + (identical(other.uri, uri) || other.uri == uri) && + const DeepCollectionEquality().equals(other._items, _items)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, typename, title, uri, + const DeepCollectionEquality().hash(_items)); + + /// Create a copy of SpotifyHomeFeedSection + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SpotifyHomeFeedSectionImplCopyWith<_$SpotifyHomeFeedSectionImpl> + get copyWith => __$$SpotifyHomeFeedSectionImplCopyWithImpl< + _$SpotifyHomeFeedSectionImpl>(this, _$identity); + + @override + Map toJson() { + return _$$SpotifyHomeFeedSectionImplToJson( + this, + ); + } +} + +abstract class _SpotifyHomeFeedSection implements SpotifyHomeFeedSection { + factory _SpotifyHomeFeedSection( + {required final String typename, + final String? title, + required final String uri, + required final List items}) = + _$SpotifyHomeFeedSectionImpl; + + factory _SpotifyHomeFeedSection.fromJson(Map json) = + _$SpotifyHomeFeedSectionImpl.fromJson; + + @override + String get typename; + @override + String? get title; + @override + String get uri; + @override + List get items; + + /// Create a copy of SpotifyHomeFeedSection + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SpotifyHomeFeedSectionImplCopyWith<_$SpotifyHomeFeedSectionImpl> + get copyWith => throw _privateConstructorUsedError; +} + +SpotifyHomeFeed _$SpotifyHomeFeedFromJson(Map json) { + return _SpotifyHomeFeed.fromJson(json); +} + +/// @nodoc +mixin _$SpotifyHomeFeed { + String get greeting => throw _privateConstructorUsedError; + List get sections => + throw _privateConstructorUsedError; + + /// Serializes this SpotifyHomeFeed to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of SpotifyHomeFeed + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $SpotifyHomeFeedCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $SpotifyHomeFeedCopyWith<$Res> { + factory $SpotifyHomeFeedCopyWith( + SpotifyHomeFeed value, $Res Function(SpotifyHomeFeed) then) = + _$SpotifyHomeFeedCopyWithImpl<$Res, SpotifyHomeFeed>; + @useResult + $Res call({String greeting, List sections}); +} + +/// @nodoc +class _$SpotifyHomeFeedCopyWithImpl<$Res, $Val extends SpotifyHomeFeed> + implements $SpotifyHomeFeedCopyWith<$Res> { + _$SpotifyHomeFeedCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of SpotifyHomeFeed + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? greeting = null, + Object? sections = null, + }) { + return _then(_value.copyWith( + greeting: null == greeting + ? _value.greeting + : greeting // ignore: cast_nullable_to_non_nullable + as String, + sections: null == sections + ? _value.sections + : sections // ignore: cast_nullable_to_non_nullable + as List, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$SpotifyHomeFeedImplCopyWith<$Res> + implements $SpotifyHomeFeedCopyWith<$Res> { + factory _$$SpotifyHomeFeedImplCopyWith(_$SpotifyHomeFeedImpl value, + $Res Function(_$SpotifyHomeFeedImpl) then) = + __$$SpotifyHomeFeedImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({String greeting, List sections}); +} + +/// @nodoc +class __$$SpotifyHomeFeedImplCopyWithImpl<$Res> + extends _$SpotifyHomeFeedCopyWithImpl<$Res, _$SpotifyHomeFeedImpl> + implements _$$SpotifyHomeFeedImplCopyWith<$Res> { + __$$SpotifyHomeFeedImplCopyWithImpl( + _$SpotifyHomeFeedImpl _value, $Res Function(_$SpotifyHomeFeedImpl) _then) + : super(_value, _then); + + /// Create a copy of SpotifyHomeFeed + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? greeting = null, + Object? sections = null, + }) { + return _then(_$SpotifyHomeFeedImpl( + greeting: null == greeting + ? _value.greeting + : greeting // ignore: cast_nullable_to_non_nullable + as String, + sections: null == sections + ? _value._sections + : sections // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$SpotifyHomeFeedImpl implements _SpotifyHomeFeed { + _$SpotifyHomeFeedImpl( + {required this.greeting, + required final List sections}) + : _sections = sections; + + factory _$SpotifyHomeFeedImpl.fromJson(Map json) => + _$$SpotifyHomeFeedImplFromJson(json); + + @override + final String greeting; + final List _sections; + @override + List get sections { + if (_sections is EqualUnmodifiableListView) return _sections; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_sections); + } + + @override + String toString() { + return 'SpotifyHomeFeed(greeting: $greeting, sections: $sections)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SpotifyHomeFeedImpl && + (identical(other.greeting, greeting) || + other.greeting == greeting) && + const DeepCollectionEquality().equals(other._sections, _sections)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, greeting, const DeepCollectionEquality().hash(_sections)); + + /// Create a copy of SpotifyHomeFeed + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SpotifyHomeFeedImplCopyWith<_$SpotifyHomeFeedImpl> get copyWith => + __$$SpotifyHomeFeedImplCopyWithImpl<_$SpotifyHomeFeedImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$SpotifyHomeFeedImplToJson( + this, + ); + } +} + +abstract class _SpotifyHomeFeed implements SpotifyHomeFeed { + factory _SpotifyHomeFeed( + {required final String greeting, + required final List sections}) = + _$SpotifyHomeFeedImpl; + + factory _SpotifyHomeFeed.fromJson(Map json) = + _$SpotifyHomeFeedImpl.fromJson; + + @override + String get greeting; + @override + List get sections; + + /// Create a copy of SpotifyHomeFeed + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SpotifyHomeFeedImplCopyWith<_$SpotifyHomeFeedImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/services/spotify/spotify_feed.g.dart b/lib/services/spotify/spotify_feed.g.dart new file mode 100644 index 0000000..2f7ea54 --- /dev/null +++ b/lib/services/spotify/spotify_feed.g.dart @@ -0,0 +1,169 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'spotify_feed.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$SpotifySectionPlaylistImpl _$$SpotifySectionPlaylistImplFromJson( + Map json) => + _$SpotifySectionPlaylistImpl( + description: json['description'] as String, + format: json['format'] as String, + images: (json['images'] as List) + .map((e) => + SpotifySectionItemImage.fromJson(e as Map)) + .toList(), + name: json['name'] as String, + owner: json['owner'] as String, + uri: json['uri'] as String, + ); + +Map _$$SpotifySectionPlaylistImplToJson( + _$SpotifySectionPlaylistImpl instance) => + { + 'description': instance.description, + 'format': instance.format, + 'images': instance.images, + 'name': instance.name, + 'owner': instance.owner, + 'uri': instance.uri, + }; + +_$SpotifySectionArtistImpl _$$SpotifySectionArtistImplFromJson( + Map json) => + _$SpotifySectionArtistImpl( + name: json['name'] as String, + uri: json['uri'] as String, + images: (json['images'] as List) + .map((e) => + SpotifySectionItemImage.fromJson(e as Map)) + .toList(), + ); + +Map _$$SpotifySectionArtistImplToJson( + _$SpotifySectionArtistImpl instance) => + { + 'name': instance.name, + 'uri': instance.uri, + 'images': instance.images, + }; + +_$SpotifySectionAlbumImpl _$$SpotifySectionAlbumImplFromJson( + Map json) => + _$SpotifySectionAlbumImpl( + artists: (json['artists'] as List) + .map((e) => + SpotifySectionAlbumArtist.fromJson(e as Map)) + .toList(), + images: (json['images'] as List) + .map((e) => + SpotifySectionItemImage.fromJson(e as Map)) + .toList(), + name: json['name'] as String, + uri: json['uri'] as String, + ); + +Map _$$SpotifySectionAlbumImplToJson( + _$SpotifySectionAlbumImpl instance) => + { + 'artists': instance.artists, + 'images': instance.images, + 'name': instance.name, + 'uri': instance.uri, + }; + +_$SpotifySectionAlbumArtistImpl _$$SpotifySectionAlbumArtistImplFromJson( + Map json) => + _$SpotifySectionAlbumArtistImpl( + name: json['name'] as String, + uri: json['uri'] as String, + ); + +Map _$$SpotifySectionAlbumArtistImplToJson( + _$SpotifySectionAlbumArtistImpl instance) => + { + 'name': instance.name, + 'uri': instance.uri, + }; + +_$SpotifySectionItemImageImpl _$$SpotifySectionItemImageImplFromJson( + Map json) => + _$SpotifySectionItemImageImpl( + height: json['height'] as num?, + url: json['url'] as String, + width: json['width'] as num?, + ); + +Map _$$SpotifySectionItemImageImplToJson( + _$SpotifySectionItemImageImpl instance) => + { + 'height': instance.height, + 'url': instance.url, + 'width': instance.width, + }; + +_$SpotifyHomeFeedSectionItemImpl _$$SpotifyHomeFeedSectionItemImplFromJson( + Map json) => + _$SpotifyHomeFeedSectionItemImpl( + typename: json['typename'] as String, + playlist: json['playlist'] == null + ? null + : SpotifySectionPlaylist.fromJson( + json['playlist'] as Map), + artist: json['artist'] == null + ? null + : SpotifySectionArtist.fromJson( + json['artist'] as Map), + album: json['album'] == null + ? null + : SpotifySectionAlbum.fromJson(json['album'] as Map), + ); + +Map _$$SpotifyHomeFeedSectionItemImplToJson( + _$SpotifyHomeFeedSectionItemImpl instance) => + { + 'typename': instance.typename, + 'playlist': instance.playlist, + 'artist': instance.artist, + 'album': instance.album, + }; + +_$SpotifyHomeFeedSectionImpl _$$SpotifyHomeFeedSectionImplFromJson( + Map json) => + _$SpotifyHomeFeedSectionImpl( + typename: json['typename'] as String, + title: json['title'] as String?, + uri: json['uri'] as String, + items: (json['items'] as List) + .map((e) => + SpotifyHomeFeedSectionItem.fromJson(e as Map)) + .toList(), + ); + +Map _$$SpotifyHomeFeedSectionImplToJson( + _$SpotifyHomeFeedSectionImpl instance) => + { + 'typename': instance.typename, + 'title': instance.title, + 'uri': instance.uri, + 'items': instance.items, + }; + +_$SpotifyHomeFeedImpl _$$SpotifyHomeFeedImplFromJson( + Map json) => + _$SpotifyHomeFeedImpl( + greeting: json['greeting'] as String, + sections: (json['sections'] as List) + .map( + (e) => SpotifyHomeFeedSection.fromJson(e as Map)) + .toList(), + ); + +Map _$$SpotifyHomeFeedImplToJson( + _$SpotifyHomeFeedImpl instance) => + { + 'greeting': instance.greeting, + 'sections': instance.sections, + }; diff --git a/lib/widgets/album/album_card.dart b/lib/widgets/album/album_card.dart index cd99534..a05c30b 100644 --- a/lib/widgets/album/album_card.dart +++ b/lib/widgets/album/album_card.dart @@ -44,7 +44,7 @@ class AlbumCard extends StatelessWidget { ], ).paddingSymmetric(horizontal: 8), onTap: () { - if (onTap != null) return; + if (onTap == null) return; onTap!(); }, ), diff --git a/lib/widgets/playlist/playlist_card.dart b/lib/widgets/playlist/playlist_card.dart index 59db49c..7702e01 100644 --- a/lib/widgets/playlist/playlist_card.dart +++ b/lib/widgets/playlist/playlist_card.dart @@ -43,7 +43,7 @@ class PlaylistCard extends StatelessWidget { ], ).paddingSymmetric(horizontal: 8), onTap: () { - if (onTap != null) return; + if (onTap == null) return; onTap!(); }, ), diff --git a/pubspec.lock b/pubspec.lock index acce576..ac22e32 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -614,6 +614,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + freezed: + dependency: "direct dev" + description: + name: freezed + sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e" + url: "https://pub.dev" + source: hosted + version: "2.5.7" freezed_annotation: dependency: "direct main" description: @@ -759,7 +767,7 @@ packages: source: hosted version: "4.9.0" json_serializable: - dependency: "direct main" + dependency: "direct dev" description: name: json_serializable sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b @@ -1382,6 +1390,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.2" + timezone: + dependency: "direct main" + description: + name: timezone + sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" + url: "https://pub.dev" + source: hosted + version: "0.9.4" timing: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a1ee047..457cef3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -78,7 +78,6 @@ dependencies: flutter_secure_storage: ^9.2.2 window_manager: ^0.4.2 lrc: ^1.0.2 - json_serializable: ^6.8.0 path: ^1.9.0 path_provider: ^2.1.4 sqlite3_flutter_libs: ^0.5.23 @@ -100,6 +99,7 @@ dependencies: ref: feat/cookies path: packages/desktop_webview_window flutter_inappwebview: ^6.0.0 + timezone: ^0.9.4 dev_dependencies: flutter_test: @@ -115,6 +115,8 @@ dev_dependencies: build_runner: ^2.4.12 flutter_launcher_icons: ^0.13.1 flutter_native_splash: ^2.4.1 + freezed: ^2.5.7 + json_serializable: ^6.8.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec