diff --git a/README.md b/README.md index 4c5c1f1c..153832ea 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,6 @@ If you are curious, you can [read the reason of choosing this license](https://d 1. [Invidious](https://invidious.io/) - Invidious is an open source alternative front-end to YouTube. 1. [yt-dlp](https://github.com/yt-dlp/yt-dlp) - A feature-rich command-line audio/video downloader. 1. [NewPipeExtractor](https://github.com/TeamNewPipe/NewPipeExtractor) - NewPipe's core library for extracting data from streaming sites. -1. [SongLink](https://song.link) - SongLink is a free smart link service that helps you share music with your audience. It's a one-stop-shop for creating smart links for music, podcasts, and other audio content 1. [LRCLib](https://lrclib.net/) - A public synced lyric API. 1. [Linux](https://www.linux.org) - Linux is a family of open-source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991, by Linus Torvalds. Linux is typically packaged in a Linux distribution 1. [AUR](https://aur.archlinux.org) - AUR stands for Arch User Repository. It is a community-driven repository for Arch-based Linux distributions users diff --git a/assets/images/logos/songlink-transparent.png b/assets/images/logos/songlink-transparent.png deleted file mode 100644 index fc4ae541..00000000 Binary files a/assets/images/logos/songlink-transparent.png and /dev/null differ diff --git a/lib/collections/assets.gen.dart b/lib/collections/assets.gen.dart index 7fa75e1d..7ab0ad03 100644 --- a/lib/collections/assets.gen.dart +++ b/lib/collections/assets.gen.dart @@ -66,6 +66,19 @@ class $AssetsImagesGen { ]; } +class $AssetsPluginsGen { + const $AssetsPluginsGen(); + + /// Directory path: assets/plugins/spotube-plugin-musicbrainz-listenbrainz + $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen + get spotubePluginMusicbrainzListenbrainz => + const $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen(); + + /// Directory path: assets/plugins/spotube-plugin-youtube-audio + $AssetsPluginsSpotubePluginYoutubeAudioGen get spotubePluginYoutubeAudio => + const $AssetsPluginsSpotubePluginYoutubeAudioGen(); +} + class $AssetsImagesLogosGen { const $AssetsImagesLogosGen(); @@ -81,13 +94,30 @@ class $AssetsImagesLogosGen { AssetGenImage get jiosaavn => const AssetGenImage('assets/images/logos/jiosaavn.png'); - /// File path: assets/images/logos/songlink-transparent.png - AssetGenImage get songlinkTransparent => - const AssetGenImage('assets/images/logos/songlink-transparent.png'); + /// List of all assets + List get values => [dabMusic, invidious, jiosaavn]; +} + +class $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen { + const $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen(); + + /// File path: assets/plugins/spotube-plugin-musicbrainz-listenbrainz/plugin.smplug + String get plugin => + 'assets/plugins/spotube-plugin-musicbrainz-listenbrainz/plugin.smplug'; /// List of all assets - List get values => - [dabMusic, invidious, jiosaavn, songlinkTransparent]; + List get values => [plugin]; +} + +class $AssetsPluginsSpotubePluginYoutubeAudioGen { + const $AssetsPluginsSpotubePluginYoutubeAudioGen(); + + /// File path: assets/plugins/spotube-plugin-youtube-audio/plugin.smplug + String get plugin => + 'assets/plugins/spotube-plugin-youtube-audio/plugin.smplug'; + + /// List of all assets + List get values => [plugin]; } class Assets { @@ -96,6 +126,7 @@ class Assets { static const String license = 'LICENSE'; static const $AssetsBrandingGen branding = $AssetsBrandingGen(); static const $AssetsImagesGen images = $AssetsImagesGen(); + static const $AssetsPluginsGen plugins = $AssetsPluginsGen(); /// List of all assets static List get values => [license]; diff --git a/lib/components/track_tile/track_options.dart b/lib/components/track_tile/track_options.dart index 6124abf0..61b47968 100644 --- a/lib/components/track_tile/track_options.dart +++ b/lib/components/track_tile/track_options.dart @@ -4,7 +4,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; -import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/routes.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/ui/button_tile.dart'; @@ -36,7 +35,6 @@ class TrackOptions extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final mediaQuery = MediaQuery.of(context); - final ThemeData(:colorScheme) = Theme.of(context); final trackOptionActions = ref.watch(trackOptionActionsProvider(track)); final ( @@ -260,24 +258,6 @@ class TrackOptions extends HookConsumerWidget { leading: const Icon(SpotubeIcons.share), title: Text(context.l10n.share), ), - if (!isLocalTrack) - ButtonTile( - style: ButtonVariance.menu, - onPressed: () async { - await trackOptionActions.action( - rootNavigatorKey.currentContext!, - TrackOptionValue.songlink, - playlistId, - ); - onTapItem?.call(); - }, - leading: Assets.images.logos.songlinkTransparent.image( - width: 22, - height: 22, - color: colorScheme.foreground.withValues(alpha: 0.5), - ), - title: Text(context.l10n.song_link), - ), if (!isLocalTrack) ButtonTile( style: ButtonVariance.menu, diff --git a/lib/models/database/database.g.dart b/lib/models/database/database.g.dart index 4a9a7eba..8aa14899 100644 --- a/lib/models/database/database.g.dart +++ b/lib/models/database/database.g.dart @@ -4143,8 +4143,6 @@ abstract class _$AppDatabase extends GeneratedDatabase { late final $PluginsTableTable pluginsTable = $PluginsTableTable(this); late final Index uniqueBlacklist = Index('unique_blacklist', 'CREATE UNIQUE INDEX unique_blacklist ON blacklist_table (element_type, element_id)'); - late final Index uniqTrackMatch = Index('uniq_track_match', - 'CREATE UNIQUE INDEX uniq_track_match ON source_match_table (track_id, source_info, source_type)'); @override Iterable> get allTables => allSchemaEntities.whereType>(); @@ -4160,8 +4158,7 @@ abstract class _$AppDatabase extends GeneratedDatabase { historyTable, lyricsTable, pluginsTable, - uniqueBlacklist, - uniqTrackMatch + uniqueBlacklist ]; } diff --git a/lib/models/metadata/audio_source.dart b/lib/models/metadata/audio_source.dart index 898300e9..4fb790ea 100644 --- a/lib/models/metadata/audio_source.dart +++ b/lib/models/metadata/audio_source.dart @@ -10,6 +10,8 @@ enum SpotubeMediaCompressionType { @Freezed(unionKey: 'type') class SpotubeAudioSourceContainerPreset with _$SpotubeAudioSourceContainerPreset { + const SpotubeAudioSourceContainerPreset._(); + @FreezedUnionValue("lossy") factory SpotubeAudioSourceContainerPreset.lossy({ required SpotubeMediaCompressionType type, @@ -27,6 +29,14 @@ class SpotubeAudioSourceContainerPreset factory SpotubeAudioSourceContainerPreset.fromJson( Map json) => _$SpotubeAudioSourceContainerPresetFromJson(json); + + String getFileExtension() { + return switch (name) { + "mp4" => "m4a", + "webm" => "weba", + _ => name, + }; + } } @freezed diff --git a/lib/models/metadata/metadata.freezed.dart b/lib/models/metadata/metadata.freezed.dart index 301929a5..fee1cbc2 100644 --- a/lib/models/metadata/metadata.freezed.dart +++ b/lib/models/metadata/metadata.freezed.dart @@ -197,12 +197,13 @@ class __$$SpotubeAudioSourceContainerPresetLossyImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$SpotubeAudioSourceContainerPresetLossyImpl - implements SpotubeAudioSourceContainerPresetLossy { + extends SpotubeAudioSourceContainerPresetLossy { _$SpotubeAudioSourceContainerPresetLossyImpl( {required this.type, required this.name, required final List qualities}) - : _qualities = qualities; + : _qualities = qualities, + super._(); factory _$SpotubeAudioSourceContainerPresetLossyImpl.fromJson( Map json) => @@ -338,12 +339,13 @@ class _$SpotubeAudioSourceContainerPresetLossyImpl } abstract class SpotubeAudioSourceContainerPresetLossy - implements SpotubeAudioSourceContainerPreset { + extends SpotubeAudioSourceContainerPreset { factory SpotubeAudioSourceContainerPresetLossy( {required final SpotubeMediaCompressionType type, required final String name, required final List qualities}) = _$SpotubeAudioSourceContainerPresetLossyImpl; + SpotubeAudioSourceContainerPresetLossy._() : super._(); factory SpotubeAudioSourceContainerPresetLossy.fromJson( Map json) = @@ -419,12 +421,13 @@ class __$$SpotubeAudioSourceContainerPresetLosslessImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$SpotubeAudioSourceContainerPresetLosslessImpl - implements SpotubeAudioSourceContainerPresetLossless { + extends SpotubeAudioSourceContainerPresetLossless { _$SpotubeAudioSourceContainerPresetLosslessImpl( {required this.type, required this.name, required final List qualities}) - : _qualities = qualities; + : _qualities = qualities, + super._(); factory _$SpotubeAudioSourceContainerPresetLosslessImpl.fromJson( Map json) => @@ -561,12 +564,13 @@ class _$SpotubeAudioSourceContainerPresetLosslessImpl } abstract class SpotubeAudioSourceContainerPresetLossless - implements SpotubeAudioSourceContainerPreset { + extends SpotubeAudioSourceContainerPreset { factory SpotubeAudioSourceContainerPresetLossless( {required final SpotubeMediaCompressionType type, required final String name, required final List qualities}) = _$SpotubeAudioSourceContainerPresetLosslessImpl; + SpotubeAudioSourceContainerPresetLossless._() : super._(); factory SpotubeAudioSourceContainerPresetLossless.fromJson( Map json) = diff --git a/lib/pages/library/user_downloads.dart b/lib/pages/library/user_downloads.dart index 6566bed6..73dc692f 100644 --- a/lib/pages/library/user_downloads.dart +++ b/lib/pages/library/user_downloads.dart @@ -16,7 +16,7 @@ class UserDownloadsPage extends HookConsumerWidget { Widget build(BuildContext context, ref) { final downloadManager = ref.watch(downloadManagerProvider); - final history = downloadManager.$backHistory; + final history = downloadManager.$history; return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -48,7 +48,7 @@ class UserDownloadsPage extends HookConsumerWidget { child: ListView.builder( itemCount: history.length, itemBuilder: (context, index) { - return DownloadItem(track: history.elementAt(index)); + return DownloadItem(track: history.elementAt(index).query); }, ), ), diff --git a/lib/pages/library/user_local_tracks/local_folder.dart b/lib/pages/library/user_local_tracks/local_folder.dart index 27af0f57..58a7a023 100644 --- a/lib/pages/library/user_local_tracks/local_folder.dart +++ b/lib/pages/library/user_local_tracks/local_folder.dart @@ -346,36 +346,41 @@ class LocalLibraryPage extends HookConsumerWidget { controller: controller, child: Skeletonizer( enabled: trackSnapshot.isLoading, - child: ListView.builder( + child: CustomScrollView( controller: controller, physics: const AlwaysScrollableScrollPhysics(), - itemCount: trackSnapshot.isLoading - ? 5 - : filteredTracks.length, - itemBuilder: (context, index) { - if (trackSnapshot.isLoading) { - return TrackTile( - playlist: playlist, - track: FakeData.track, - index: index, - ); - } + slivers: [ + SliverList.builder( + itemCount: trackSnapshot.isLoading + ? 5 + : filteredTracks.length, + itemBuilder: (context, index) { + if (trackSnapshot.isLoading) { + return TrackTile( + playlist: playlist, + track: FakeData.track, + index: index, + ); + } - final track = filteredTracks[index]; - return TrackTile( - index: index, - playlist: playlist, - track: track, - userPlaylist: false, - onTap: () async { - await playLocalTracks( - ref, - sortedTracks, - currentTrack: track, + final track = filteredTracks[index]; + return TrackTile( + index: index, + playlist: playlist, + track: track, + userPlaylist: false, + onTap: () async { + await playLocalTracks( + ref, + sortedTracks, + currentTrack: track, + ); + }, ); }, - ); - }, + ), + const SliverGap(200), + ], ), ), ), @@ -398,7 +403,7 @@ class LocalLibraryPage extends HookConsumerWidget { error: (error, stackTrace) => Text(error.toString() + stackTrace.toString()), ); - }) + }), ], ), ), diff --git a/lib/provider/download_manager_provider.dart b/lib/provider/download_manager_provider.dart index bc1de813..d64da32e 100644 --- a/lib/provider/download_manager_provider.dart +++ b/lib/provider/download_manager_provider.dart @@ -19,7 +19,6 @@ import 'package:spotube/utils/service_utils.dart'; class DownloadManagerProvider extends ChangeNotifier { DownloadManagerProvider({required this.ref}) : $history = {}, - $backHistory = {}, dl = DownloadManager() { dl.statusStream.listen((event) async { try { @@ -28,14 +27,13 @@ class DownloadManagerProvider extends ChangeNotifier { final sourcedTrack = $history.firstWhereOrNull( (element) => element.getUrlOfQuality( - downloadContainer, downloadQualityIndex) == + downloadContainer, + downloadQualityIndex, + ) == request.url, ); + if (sourcedTrack == null) return; - final track = $backHistory.firstWhereOrNull( - (element) => element.id == sourcedTrack.query.id, - ); - if (track == null) return; final savePath = getTrackFileUrl(sourcedTrack); // related to onFileExists @@ -47,12 +45,12 @@ class DownloadManagerProvider extends ChangeNotifier { await oldFile.exists()) { await oldFile.rename(savePath); } + if (status != DownloadStatus.completed || //? WebA audiotagging is not supported yet //? Although in future by converting weba to opus & then tagging it //? is possible using vorbis comments - downloadContainer.name == "weba" || - downloadContainer.name == "webm") { + downloadContainer.getFileExtension() == "weba") { return; } @@ -63,13 +61,13 @@ class DownloadManagerProvider extends ChangeNotifier { } final imageBytes = await ServiceUtils.downloadImage( - (track.album.images).asUrlString( + (sourcedTrack.query.album.images).asUrlString( placeholder: ImagePlaceholder.albumArt, index: 1, ), ); - final metadata = track.toMetadata( + final metadata = sourcedTrack.query.toMetadata( fileLength: await file.length(), imageBytes: imageBytes, ); @@ -111,17 +109,16 @@ class DownloadManagerProvider extends ChangeNotifier { final Set $history; // these are the tracks which metadata hasn't been fetched yet - final Set $backHistory; final DownloadManager dl; String getTrackFileUrl(SourcedTrack track) { final name = - "${track.query.name} - ${track.query.artists.join(", ")}.${downloadContainer.name}"; + "${track.query.name} - ${track.query.artists.map((e) => e.name).join(", ")}.${downloadContainer.getFileExtension()}"; return join(downloadDirectory, PrimitiveUtils.toSafeFileName(name)); } bool isActive(SpotubeFullTrackObject track) { - if ($backHistory.contains(track)) return true; + if ($history.any((e) => e.query.id == track.id)) return true; final sourcedTrack = $history.firstWhereOrNull( (element) => element.query.id == track.id, @@ -146,9 +143,7 @@ class DownloadManagerProvider extends ChangeNotifier { /// For singular downloads Future addToQueue(SpotubeFullTrackObject track) async { - final sourcedTrack = await ref.read( - sourcedTrackProvider(track).future, - ); + final sourcedTrack = await ref.read(sourcedTrackProvider(track).future); final savePath = getTrackFileUrl(sourcedTrack); @@ -161,35 +156,17 @@ class DownloadManagerProvider extends ChangeNotifier { await oldFile.rename("$savePath.old"); } - if (sourcedTrack.qualityPreset == downloadContainer) { - final downloadTask = await dl.addDownload( - sourcedTrack.getUrlOfQuality(downloadContainer, downloadQualityIndex)!, - savePath, - ); - if (downloadTask != null) { - $history.add(sourcedTrack); - } - } else { - $backHistory.add(track); - final sourcedTrack = - await ref.read(sourcedTrackProvider(track).future).then((d) { - $backHistory.remove(track); - return d; - }); - final downloadTask = await dl.addDownload( - sourcedTrack.getUrlOfQuality(downloadContainer, downloadQualityIndex)!, - savePath, - ); - if (downloadTask != null) { - $history.add(sourcedTrack); - } + final downloadTask = await dl.addDownload( + sourcedTrack.getUrlOfQuality(downloadContainer, downloadQualityIndex)!, + savePath, + ); + if (downloadTask != null) { + $history.add(sourcedTrack); } - notifyListeners(); } Future batchAddToQueue(List tracks) async { - $backHistory.addAll(tracks); notifyListeners(); for (final track in tracks) { try { diff --git a/lib/provider/server/routes/playback.dart b/lib/provider/server/routes/playback.dart index 792d7797..f7085505 100644 --- a/lib/provider/server/routes/playback.dart +++ b/lib/provider/server/routes/playback.dart @@ -48,7 +48,7 @@ class ServerPlaybackRoutes { return join( await UserPreferencesNotifier.getMusicCacheDir(), ServiceUtils.sanitizeFilename( - '${track.query.name} - ${track.query.artists.map((d) => d.name).join(",")} (${track.info.id}).${track.qualityPreset!.name}', + '${track.query.name} - ${track.query.artists.map((d) => d.name).join(",")} (${track.info.id}).${track.qualityPreset!.getFileExtension()}', ), ); } @@ -263,8 +263,7 @@ class ServerPlaybackRoutes { } if (contentRange.total == fileLength && - track.qualityPreset!.name != "webm" || - track.qualityPreset!.name != "weba") { + track.qualityPreset!.getFileExtension() != "weba") { final playlistTrack = playlist.tracks.firstWhereOrNull( (element) => element.id == track.query.id, ); diff --git a/lib/provider/track_options/track_options_provider.dart b/lib/provider/track_options/track_options_provider.dart index 42f363d9..e6b05201 100644 --- a/lib/provider/track_options/track_options_provider.dart +++ b/lib/provider/track_options/track_options_provider.dart @@ -21,12 +21,10 @@ import 'package:spotube/provider/metadata_plugin/library/playlists.dart'; import 'package:spotube/provider/metadata_plugin/library/tracks.dart'; import 'package:spotube/provider/metadata_plugin/metadata_plugin_provider.dart'; import 'package:spotube/services/metadata/errors/exceptions.dart'; -import 'package:url_launcher/url_launcher_string.dart'; enum TrackOptionValue { album, share, - songlink, addToPlaylist, addToQueue, removeFromPlaylist, @@ -237,10 +235,6 @@ class TrackOptionsActions { case TrackOptionValue.share: actionShare(context); break; - case TrackOptionValue.songlink: - final url = "https://song.link/s/${track.id}"; - await launchUrlString(url); - break; case TrackOptionValue.details: if (track is! SpotubeFullTrackObject) break; showDialog( @@ -252,8 +246,8 @@ class TrackOptionsActions { ); break; case TrackOptionValue.download: - if (track is! SpotubeFullTrackObject) break; - await downloadManager.addToQueue(track as SpotubeFullTrackObject); + if (track is SpotubeLocalTrackObject) break; + downloadManager.addToQueue(track as SpotubeFullTrackObject); break; case TrackOptionValue.startRadio: actionStartRadio(context); diff --git a/lib/services/audio_player/audio_player.dart b/lib/services/audio_player/audio_player.dart index a30fafba..9ae4e973 100644 --- a/lib/services/audio_player/audio_player.dart +++ b/lib/services/audio_player/audio_player.dart @@ -37,7 +37,7 @@ class SpotubeMedia extends mk.Media { factory SpotubeMedia.media(Media media) { assert(media.extras != null, "[Media] must have extra metadata set"); - return SpotubeMedia(SpotubeFullTrackObject.fromJson(media.extras!)); + return SpotubeMedia(SpotubeTrackObject.fromJson(media.extras!)); } } diff --git a/lib/services/song_link/model.dart b/lib/services/song_link/model.dart deleted file mode 100644 index ae9d3833..00000000 --- a/lib/services/song_link/model.dart +++ /dev/null @@ -1,19 +0,0 @@ -part of './song_link.dart'; - -@freezed -class SongLink with _$SongLink { - const factory SongLink({ - required String displayName, - required String linkId, - required String platform, - required bool show, - required String? uniqueId, - required String? country, - required String? url, - required String? nativeAppUriMobile, - required String? nativeAppUriDesktop, - }) = _SongLink; - - factory SongLink.fromJson(Map json) => - _$SongLinkFromJson(json); -} diff --git a/lib/services/song_link/song_link.dart b/lib/services/song_link/song_link.dart deleted file mode 100644 index e3cffa52..00000000 --- a/lib/services/song_link/song_link.dart +++ /dev/null @@ -1,54 +0,0 @@ -library song_link; - -import 'dart:convert'; - -import 'package:spotube/services/logger/logger.dart'; -import 'package:dio/dio.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:html/parser.dart'; - -part 'model.dart'; - -part 'song_link.freezed.dart'; -part 'song_link.g.dart'; - -abstract class SongLinkService { - static final dio = Dio(); - static Future> links(String spotifyId) async { - try { - final res = await dio.get( - "https://song.link/s/$spotifyId", - options: Options( - headers: { - "Accept": - "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" - }, - responseType: ResponseType.plain, - ), - ); - - final document = parse(res.data); - - final script = document.getElementById("__NEXT_DATA__")?.text; - - if (script == null) { - return []; - } - - final pageProps = jsonDecode(script) as Map; - final songLinks = pageProps["props"]?["pageProps"]?["pageData"] - ?["sections"] - ?.firstWhere( - (section) => section?["sectionId"] == "section|auto|links|listen", - )?["links"] as List?; - - return songLinks?.map((link) => SongLink.fromJson(link)).toList() ?? - []; - } catch (e, stackTrace) { - AppLogger.reportError(e, stackTrace); - return []; - } - } -} diff --git a/lib/services/song_link/song_link.freezed.dart b/lib/services/song_link/song_link.freezed.dart deleted file mode 100644 index c704cde3..00000000 --- a/lib/services/song_link/song_link.freezed.dart +++ /dev/null @@ -1,333 +0,0 @@ -// 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 'song_link.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'); - -SongLink _$SongLinkFromJson(Map json) { - return _SongLink.fromJson(json); -} - -/// @nodoc -mixin _$SongLink { - String get displayName => throw _privateConstructorUsedError; - String get linkId => throw _privateConstructorUsedError; - String get platform => throw _privateConstructorUsedError; - bool get show => throw _privateConstructorUsedError; - String? get uniqueId => throw _privateConstructorUsedError; - String? get country => throw _privateConstructorUsedError; - String? get url => throw _privateConstructorUsedError; - String? get nativeAppUriMobile => throw _privateConstructorUsedError; - String? get nativeAppUriDesktop => throw _privateConstructorUsedError; - - /// Serializes this SongLink to a JSON map. - Map toJson() => throw _privateConstructorUsedError; - - /// 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; -} - -/// @nodoc -abstract class $SongLinkCopyWith<$Res> { - factory $SongLinkCopyWith(SongLink value, $Res Function(SongLink) then) = - _$SongLinkCopyWithImpl<$Res, SongLink>; - @useResult - $Res call( - {String displayName, - String linkId, - String platform, - bool show, - String? uniqueId, - String? country, - String? url, - String? nativeAppUriMobile, - String? nativeAppUriDesktop}); -} - -/// @nodoc -class _$SongLinkCopyWithImpl<$Res, $Val extends SongLink> - implements $SongLinkCopyWith<$Res> { - _$SongLinkCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // 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({ - Object? displayName = null, - Object? linkId = null, - Object? platform = null, - Object? show = null, - Object? uniqueId = freezed, - Object? country = freezed, - Object? url = freezed, - Object? nativeAppUriMobile = freezed, - Object? nativeAppUriDesktop = freezed, - }) { - return _then(_value.copyWith( - displayName: null == displayName - ? _value.displayName - : displayName // ignore: cast_nullable_to_non_nullable - as String, - linkId: null == linkId - ? _value.linkId - : linkId // ignore: cast_nullable_to_non_nullable - as String, - platform: null == platform - ? _value.platform - : platform // ignore: cast_nullable_to_non_nullable - as String, - show: null == show - ? _value.show - : show // ignore: cast_nullable_to_non_nullable - as bool, - uniqueId: freezed == uniqueId - ? _value.uniqueId - : uniqueId // ignore: cast_nullable_to_non_nullable - as String?, - country: freezed == country - ? _value.country - : country // ignore: cast_nullable_to_non_nullable - as String?, - url: freezed == url - ? _value.url - : url // ignore: cast_nullable_to_non_nullable - as String?, - nativeAppUriMobile: freezed == nativeAppUriMobile - ? _value.nativeAppUriMobile - : nativeAppUriMobile // ignore: cast_nullable_to_non_nullable - as String?, - nativeAppUriDesktop: freezed == nativeAppUriDesktop - ? _value.nativeAppUriDesktop - : nativeAppUriDesktop // ignore: cast_nullable_to_non_nullable - as String?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$SongLinkImplCopyWith<$Res> - implements $SongLinkCopyWith<$Res> { - factory _$$SongLinkImplCopyWith( - _$SongLinkImpl value, $Res Function(_$SongLinkImpl) then) = - __$$SongLinkImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {String displayName, - String linkId, - String platform, - bool show, - String? uniqueId, - String? country, - String? url, - String? nativeAppUriMobile, - String? nativeAppUriDesktop}); -} - -/// @nodoc -class __$$SongLinkImplCopyWithImpl<$Res> - extends _$SongLinkCopyWithImpl<$Res, _$SongLinkImpl> - implements _$$SongLinkImplCopyWith<$Res> { - __$$SongLinkImplCopyWithImpl( - _$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({ - Object? displayName = null, - Object? linkId = null, - Object? platform = null, - Object? show = null, - Object? uniqueId = freezed, - Object? country = freezed, - Object? url = freezed, - Object? nativeAppUriMobile = freezed, - Object? nativeAppUriDesktop = freezed, - }) { - return _then(_$SongLinkImpl( - displayName: null == displayName - ? _value.displayName - : displayName // ignore: cast_nullable_to_non_nullable - as String, - linkId: null == linkId - ? _value.linkId - : linkId // ignore: cast_nullable_to_non_nullable - as String, - platform: null == platform - ? _value.platform - : platform // ignore: cast_nullable_to_non_nullable - as String, - show: null == show - ? _value.show - : show // ignore: cast_nullable_to_non_nullable - as bool, - uniqueId: freezed == uniqueId - ? _value.uniqueId - : uniqueId // ignore: cast_nullable_to_non_nullable - as String?, - country: freezed == country - ? _value.country - : country // ignore: cast_nullable_to_non_nullable - as String?, - url: freezed == url - ? _value.url - : url // ignore: cast_nullable_to_non_nullable - as String?, - nativeAppUriMobile: freezed == nativeAppUriMobile - ? _value.nativeAppUriMobile - : nativeAppUriMobile // ignore: cast_nullable_to_non_nullable - as String?, - nativeAppUriDesktop: freezed == nativeAppUriDesktop - ? _value.nativeAppUriDesktop - : nativeAppUriDesktop // ignore: cast_nullable_to_non_nullable - as String?, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$SongLinkImpl implements _SongLink { - const _$SongLinkImpl( - {required this.displayName, - required this.linkId, - required this.platform, - required this.show, - required this.uniqueId, - required this.country, - required this.url, - required this.nativeAppUriMobile, - required this.nativeAppUriDesktop}); - - factory _$SongLinkImpl.fromJson(Map json) => - _$$SongLinkImplFromJson(json); - - @override - final String displayName; - @override - final String linkId; - @override - final String platform; - @override - final bool show; - @override - final String? uniqueId; - @override - final String? country; - @override - final String? url; - @override - final String? nativeAppUriMobile; - @override - final String? nativeAppUriDesktop; - - @override - String toString() { - return 'SongLink(displayName: $displayName, linkId: $linkId, platform: $platform, show: $show, uniqueId: $uniqueId, country: $country, url: $url, nativeAppUriMobile: $nativeAppUriMobile, nativeAppUriDesktop: $nativeAppUriDesktop)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$SongLinkImpl && - (identical(other.displayName, displayName) || - other.displayName == displayName) && - (identical(other.linkId, linkId) || other.linkId == linkId) && - (identical(other.platform, platform) || - other.platform == platform) && - (identical(other.show, show) || other.show == show) && - (identical(other.uniqueId, uniqueId) || - other.uniqueId == uniqueId) && - (identical(other.country, country) || other.country == country) && - (identical(other.url, url) || other.url == url) && - (identical(other.nativeAppUriMobile, nativeAppUriMobile) || - other.nativeAppUriMobile == nativeAppUriMobile) && - (identical(other.nativeAppUriDesktop, nativeAppUriDesktop) || - other.nativeAppUriDesktop == nativeAppUriDesktop)); - } - - @JsonKey(includeFromJson: false, includeToJson: false) - @override - int get hashCode => Object.hash(runtimeType, displayName, linkId, platform, - show, uniqueId, country, url, nativeAppUriMobile, nativeAppUriDesktop); - - /// 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 => - __$$SongLinkImplCopyWithImpl<_$SongLinkImpl>(this, _$identity); - - @override - Map toJson() { - return _$$SongLinkImplToJson( - this, - ); - } -} - -abstract class _SongLink implements SongLink { - const factory _SongLink( - {required final String displayName, - required final String linkId, - required final String platform, - required final bool show, - required final String? uniqueId, - required final String? country, - required final String? url, - required final String? nativeAppUriMobile, - required final String? nativeAppUriDesktop}) = _$SongLinkImpl; - - factory _SongLink.fromJson(Map json) = - _$SongLinkImpl.fromJson; - - @override - String get displayName; - @override - String get linkId; - @override - String get platform; - @override - bool get show; - @override - String? get uniqueId; - @override - String? get country; - @override - String? get url; - @override - 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(includeFromJson: false, includeToJson: false) - _$$SongLinkImplCopyWith<_$SongLinkImpl> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/services/song_link/song_link.g.dart b/lib/services/song_link/song_link.g.dart deleted file mode 100644 index 7658a74c..00000000 --- a/lib/services/song_link/song_link.g.dart +++ /dev/null @@ -1,32 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'song_link.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$SongLinkImpl _$$SongLinkImplFromJson(Map json) => _$SongLinkImpl( - displayName: json['displayName'] as String, - linkId: json['linkId'] as String, - platform: json['platform'] as String, - show: json['show'] as bool, - uniqueId: json['uniqueId'] as String?, - country: json['country'] as String?, - url: json['url'] as String?, - nativeAppUriMobile: json['nativeAppUriMobile'] as String?, - nativeAppUriDesktop: json['nativeAppUriDesktop'] as String?, - ); - -Map _$$SongLinkImplToJson(_$SongLinkImpl instance) => - { - 'displayName': instance.displayName, - 'linkId': instance.linkId, - 'platform': instance.platform, - 'show': instance.show, - 'uniqueId': instance.uniqueId, - 'country': instance.country, - 'url': instance.url, - 'nativeAppUriMobile': instance.nativeAppUriMobile, - 'nativeAppUriDesktop': instance.nativeAppUriDesktop, - };