From 7545ff64159b3e5561abfe887014d8cee872597b Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 21 Mar 2024 00:18:43 +0600 Subject: [PATCH] refactor: use extension method for image to url string --- lib/components/album/album_card.dart | 4 +-- lib/components/artist/artist_card.dart | 4 +-- .../playlist_generate/simple_track_tile.dart | 4 +-- .../library/user_downloads/download_item.dart | 4 +-- lib/components/player/player.dart | 4 +-- lib/components/playlist/playlist_card.dart | 4 +-- .../playlist/playlist_create_dialog.dart | 4 +-- lib/components/root/bottom_player.dart | 4 +-- lib/components/root/sidebar.dart | 4 +-- .../dialogs/playlist_add_track_dialog.dart | 4 +-- .../shared/track_tile/track_options.dart | 5 ++-- .../shared/track_tile/track_tile.dart | 4 +-- lib/extensions/image.dart | 28 +++++++++++++++++++ .../configurators/use_get_storage_perms.dart | 4 +-- lib/pages/album/album.dart | 4 +-- lib/pages/artist/section/footer.dart | 4 +-- lib/pages/artist/section/header.dart | 4 +-- .../playlist_generate/playlist_generate.dart | 10 +++---- lib/pages/lyrics/lyrics.dart | 4 +-- lib/pages/playlist/playlist.dart | 4 +-- lib/pages/track/track.dart | 7 ++--- lib/provider/download_manager_provider.dart | 7 +++-- .../proxy_playlist_provider.dart | 4 +-- .../audio_services/audio_services.dart | 10 ++++--- .../audio_services/linux_audio_service.dart | 4 +-- .../audio_services/windows_audio_service.dart | 21 ++++++++------ lib/utils/type_conversion_utils.dart | 25 ----------------- 27 files changed, 99 insertions(+), 90 deletions(-) create mode 100644 lib/extensions/image.dart diff --git a/lib/components/album/album_card.dart b/lib/components/album/album_card.dart index 3838b7a4..97db9d72 100644 --- a/lib/components/album/album_card.dart +++ b/lib/components/album/album_card.dart @@ -4,6 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/shared/playbutton_card.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; @@ -49,8 +50,7 @@ class AlbumCard extends HookConsumerWidget { } return PlaybuttonCard( - imageUrl: TypeConversionUtils.image_X_UrlString( - album.images, + imageUrl: album.images.asUrlString( placeholder: ImagePlaceholder.collection, ), margin: const EdgeInsets.symmetric(horizontal: 10), diff --git a/lib/components/artist/artist_card.dart b/lib/components/artist/artist_card.dart index ac3e9bec..322ad501 100644 --- a/lib/components/artist/artist_card.dart +++ b/lib/components/artist/artist_card.dart @@ -6,6 +6,7 @@ import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/hooks/utils/use_breakpoint_value.dart'; import 'package:spotube/hooks/utils/use_brightness_value.dart'; import 'package:spotube/provider/blacklist_provider.dart'; @@ -20,8 +21,7 @@ class ArtistCard extends HookConsumerWidget { Widget build(BuildContext context, ref) { final theme = Theme.of(context); final backgroundImage = UniversalImage.imageProvider( - TypeConversionUtils.image_X_UrlString( - artist.images, + artist.images.asUrlString( placeholder: ImagePlaceholder.artist, ), ); diff --git a/lib/components/library/playlist_generate/simple_track_tile.dart b/lib/components/library/playlist_generate/simple_track_tile.dart index e592969e..08d5060f 100644 --- a/lib/components/library/playlist_generate/simple_track_tile.dart +++ b/lib/components/library/playlist_generate/simple_track_tile.dart @@ -4,6 +4,7 @@ import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; class SimpleTrackTile extends HookWidget { @@ -21,8 +22,7 @@ class SimpleTrackTile extends HookWidget { leading: ClipRRect( borderRadius: BorderRadius.circular(8), child: UniversalImage( - path: TypeConversionUtils.image_X_UrlString( - track.album?.images, + path: (track.album?.images).asUrlString( placeholder: ImagePlaceholder.artist, ), height: 40, diff --git a/lib/components/library/user_downloads/download_item.dart b/lib/components/library/user_downloads/download_item.dart index 1cb5e559..16bf1afe 100644 --- a/lib/components/library/user_downloads/download_item.dart +++ b/lib/components/library/user_downloads/download_item.dart @@ -5,6 +5,7 @@ import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/services/download_manager/download_status.dart'; import 'package:spotube/services/sourced_track/sourced_track.dart'; @@ -51,8 +52,7 @@ class DownloadItem extends HookConsumerWidget { child: UniversalImage( height: 40, width: 40, - path: TypeConversionUtils.image_X_UrlString( - track.album?.images, + path: (track.album?.images).asUrlString( placeholder: ImagePlaceholder.albumArt, ), ), diff --git a/lib/components/player/player.dart b/lib/components/player/player.dart index 5d5a39af..6fcbbd1c 100644 --- a/lib/components/player/player.dart +++ b/lib/components/player/player.dart @@ -18,6 +18,7 @@ import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/components/shared/panels/sliding_up_panel.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/hooks/utils/use_custom_status_bar_color.dart'; import 'package:spotube/hooks/utils/use_palette_color.dart'; import 'package:spotube/models/local_track.dart'; @@ -59,8 +60,7 @@ class PlayerView extends HookConsumerWidget { }, [mediaQuery.lgAndUp]); String albumArt = useMemoized( - () => TypeConversionUtils.image_X_UrlString( - currentTrack?.album?.images, + () => (currentTrack?.album?.images).asUrlString( placeholder: ImagePlaceholder.albumArt, ), [currentTrack?.album?.images], diff --git a/lib/components/playlist/playlist_card.dart b/lib/components/playlist/playlist_card.dart index ffbfbae9..83e25a85 100644 --- a/lib/components/playlist/playlist_card.dart +++ b/lib/components/playlist/playlist_card.dart @@ -3,6 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/shared/playbutton_card.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; @@ -43,8 +44,7 @@ class PlaylistCard extends HookConsumerWidget { margin: const EdgeInsets.symmetric(horizontal: 10), title: playlist.name!, description: playlist.description, - imageUrl: TypeConversionUtils.image_X_UrlString( - playlist.images, + imageUrl: playlist.images.asUrlString( placeholder: ImagePlaceholder.collection, ), isPlaying: isPlaylistPlaying, diff --git a/lib/components/playlist/playlist_create_dialog.dart b/lib/components/playlist/playlist_create_dialog.dart index 669dce51..cae51444 100644 --- a/lib/components/playlist/playlist_create_dialog.dart +++ b/lib/components/playlist/playlist_create_dialog.dart @@ -14,6 +14,7 @@ import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/provider/spotify_provider.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; @@ -163,8 +164,7 @@ class PlaylistCreateDialog extends HookConsumerWidget { children: [ UniversalImage( path: field.value?.path ?? - TypeConversionUtils.image_X_UrlString( - updatingPlaylist?.images, + (updatingPlaylist?.images).asUrlString( placeholder: ImagePlaceholder.collection, ), height: 200, diff --git a/lib/components/root/bottom_player.dart b/lib/components/root/bottom_player.dart index 3f70490a..e6cf17dc 100644 --- a/lib/components/root/bottom_player.dart +++ b/lib/components/root/bottom_player.dart @@ -14,6 +14,7 @@ import 'package:spotube/components/player/player_controls.dart'; import 'package:spotube/components/player/volume_slider.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/hooks/utils/use_brightness_value.dart'; import 'package:spotube/models/logger.dart'; import 'package:flutter/material.dart'; @@ -39,8 +40,7 @@ class BottomPlayer extends HookConsumerWidget { String albumArt = useMemoized( () => playlist.activeTrack?.album?.images?.isNotEmpty == true - ? TypeConversionUtils.image_X_UrlString( - playlist.activeTrack?.album?.images, + ? (playlist.activeTrack?.album?.images).asUrlString( index: (playlist.activeTrack?.album?.images?.length ?? 1) - 1, placeholder: ImagePlaceholder.albumArt, ) diff --git a/lib/components/root/sidebar.dart b/lib/components/root/sidebar.dart index 21259a94..9049ecf1 100644 --- a/lib/components/root/sidebar.dart +++ b/lib/components/root/sidebar.dart @@ -11,6 +11,7 @@ import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/hooks/utils/use_brightness_value.dart'; import 'package:spotube/hooks/controllers/use_sidebarx_controller.dart'; import 'package:spotube/provider/download_manager_provider.dart'; @@ -244,8 +245,7 @@ class SidebarFooter extends HookConsumerWidget { final me = ref.watch(meProvider); final data = me.asData?.value; - final avatarImg = TypeConversionUtils.image_X_UrlString( - data?.images, + final avatarImg = (data?.images).asUrlString( index: (data?.images?.length ?? 1) - 1, placeholder: ImagePlaceholder.artist, ); diff --git a/lib/components/shared/dialogs/playlist_add_track_dialog.dart b/lib/components/shared/dialogs/playlist_add_track_dialog.dart index 1f1807da..28044b41 100644 --- a/lib/components/shared/dialogs/playlist_add_track_dialog.dart +++ b/lib/components/shared/dialogs/playlist_add_track_dialog.dart @@ -7,6 +7,7 @@ import 'package:spotify/spotify.dart'; import 'package:spotube/components/playlist/playlist_create_dialog.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; @@ -105,8 +106,7 @@ class PlaylistAddTrackDialog extends HookConsumerWidget { return CheckboxListTile( secondary: CircleAvatar( backgroundImage: UniversalImage.imageProvider( - TypeConversionUtils.image_X_UrlString( - playlist.images, + playlist.images.asUrlString( placeholder: ImagePlaceholder.collection, ), ), diff --git a/lib/components/shared/track_tile/track_options.dart b/lib/components/shared/track_tile/track_options.dart index 8522738d..590a5889 100644 --- a/lib/components/shared/track_tile/track_options.dart +++ b/lib/components/shared/track_tile/track_options.dart @@ -17,6 +17,7 @@ import 'package:spotube/components/shared/heart_button.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/models/local_track.dart'; import 'package:spotube/provider/authentication_provider.dart'; import 'package:spotube/provider/blacklist_provider.dart'; @@ -294,8 +295,8 @@ class TrackOptions extends HookConsumerWidget { child: ClipRRect( borderRadius: BorderRadius.circular(10), child: UniversalImage( - path: TypeConversionUtils.image_X_UrlString(track.album!.images, - placeholder: ImagePlaceholder.albumArt), + path: track.album!.images + .asUrlString(placeholder: ImagePlaceholder.albumArt), fit: BoxFit.cover, ), ), diff --git a/lib/components/shared/track_tile/track_tile.dart b/lib/components/shared/track_tile/track_tile.dart index ecadc1c6..afdc19a4 100644 --- a/lib/components/shared/track_tile/track_tile.dart +++ b/lib/components/shared/track_tile/track_tile.dart @@ -13,6 +13,7 @@ import 'package:spotube/components/shared/links/link_text.dart'; import 'package:spotube/components/shared/track_tile/track_options.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/duration.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/models/local_track.dart'; import 'package:spotube/provider/blacklist_provider.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; @@ -135,8 +136,7 @@ class TrackTile extends HookConsumerWidget { child: AspectRatio( aspectRatio: 1, child: UniversalImage( - path: TypeConversionUtils.image_X_UrlString( - track.album?.images, + path: (track.album?.images).asUrlString( placeholder: ImagePlaceholder.albumArt, ), fit: BoxFit.cover, diff --git a/lib/extensions/image.dart b/lib/extensions/image.dart new file mode 100644 index 00000000..f84bd37a --- /dev/null +++ b/lib/extensions/image.dart @@ -0,0 +1,28 @@ +import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/assets.gen.dart'; +import 'package:spotube/utils/primitive_utils.dart'; +import 'package:spotube/utils/type_conversion_utils.dart'; +import 'package:collection/collection.dart'; + +extension SpotifyImageExtensions on List? { + String asUrlString({ + int index = 1, + required ImagePlaceholder placeholder, + }) { + final String placeholderUrl = { + ImagePlaceholder.albumArt: Assets.albumPlaceholder.path, + ImagePlaceholder.artist: Assets.userPlaceholder.path, + ImagePlaceholder.collection: Assets.placeholder.path, + ImagePlaceholder.online: + "https://avatars.dicebear.com/api/bottts/${PrimitiveUtils.uuid.v4()}.png", + }[placeholder]!; + + final sortedImage = this?.sorted((a, b) => a.width!.compareTo(b.width!)); + + return sortedImage != null && sortedImage.isNotEmpty + ? sortedImage[ + index > sortedImage.length - 1 ? sortedImage.length - 1 : index] + .url! + : placeholderUrl; + } +} diff --git a/lib/hooks/configurators/use_get_storage_perms.dart b/lib/hooks/configurators/use_get_storage_perms.dart index 3fcb369b..86b495c4 100644 --- a/lib/hooks/configurators/use_get_storage_perms.dart +++ b/lib/hooks/configurators/use_get_storage_perms.dart @@ -25,11 +25,11 @@ void useGetStoragePermissions(WidgetRef ref) { if (hasNoStoragePerm) { await Permission.storage.request(); - if (isMounted()) ref.refresh(localTracksProvider); + if (isMounted()) ref.invalidate(localTracksProvider); } if (hasNoAudioPerm) { await Permission.audio.request(); - if (isMounted()) ref.refresh(localTracksProvider); + if (isMounted()) ref.invalidate(localTracksProvider); } }, null, diff --git a/lib/pages/album/album.dart b/lib/pages/album/album.dart index fac0a6a6..0f36756f 100644 --- a/lib/pages/album/album.dart +++ b/lib/pages/album/album.dart @@ -4,6 +4,7 @@ import 'package:spotify/spotify.dart'; import 'package:spotube/components/shared/tracks_view/track_view.dart'; import 'package:spotube/components/shared/tracks_view/track_view_props.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; @@ -23,8 +24,7 @@ class AlbumPage extends HookConsumerWidget { return InheritedTrackView( collectionId: album.id!, - image: TypeConversionUtils.image_X_UrlString( - album.images, + image: album.images.asUrlString( placeholder: ImagePlaceholder.albumArt, ), title: album.name!, diff --git a/lib/pages/artist/section/footer.dart b/lib/pages/artist/section/footer.dart index ac166252..c53f2c54 100644 --- a/lib/pages/artist/section/footer.dart +++ b/lib/pages/artist/section/footer.dart @@ -5,6 +5,7 @@ import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; import 'package:url_launcher/url_launcher_string.dart'; @@ -18,8 +19,7 @@ class ArtistPageFooter extends ConsumerWidget { final ThemeData(:textTheme) = Theme.of(context); final mediaQuery = MediaQuery.of(context); - final artistImage = TypeConversionUtils.image_X_UrlString( - artist.images, + final artistImage = artist.images.asUrlString( placeholder: ImagePlaceholder.artist, ); final summary = ref.watch(artistWikipediaSummaryProvider(artist)); diff --git a/lib/pages/artist/section/header.dart b/lib/pages/artist/section/header.dart index 7756da15..dcf3114e 100644 --- a/lib/pages/artist/section/header.dart +++ b/lib/pages/artist/section/header.dart @@ -8,6 +8,7 @@ import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/hooks/utils/use_breakpoint_value.dart'; import 'package:spotube/provider/authentication_provider.dart'; import 'package:spotube/provider/blacklist_provider.dart'; @@ -44,8 +45,7 @@ class ArtistPageHeader extends HookConsumerWidget { BlacklistedElement.artist(artistId, artist.name!), ); - final image = TypeConversionUtils.image_X_UrlString( - artist.images, + final image = artist.images.asUrlString( placeholder: ImagePlaceholder.artist, ); diff --git a/lib/pages/library/playlist_generate/playlist_generate.dart b/lib/pages/library/playlist_generate/playlist_generate.dart index 642ceb6c..81fbbfe3 100644 --- a/lib/pages/library/playlist_generate/playlist_generate.dart +++ b/lib/pages/library/playlist_generate/playlist_generate.dart @@ -15,6 +15,7 @@ import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/models/spotify/recommendation_seeds.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/provider/spotify_provider.dart'; @@ -84,8 +85,7 @@ class PlaylistGeneratorPage extends HookConsumerWidget { autocompleteOptionBuilder: (option, onSelected) => ListTile( leading: CircleAvatar( backgroundImage: UniversalImage.imageProvider( - TypeConversionUtils.image_X_UrlString( - option.images, + option.images.asUrlString( placeholder: ImagePlaceholder.artist, ), ), @@ -117,8 +117,7 @@ class PlaylistGeneratorPage extends HookConsumerWidget { selectedSeedBuilder: (artist) => Chip( avatar: CircleAvatar( backgroundImage: UniversalImage.imageProvider( - TypeConversionUtils.image_X_UrlString( - artist.images, + artist.images.asUrlString( placeholder: ImagePlaceholder.artist, ), ), @@ -163,8 +162,7 @@ class PlaylistGeneratorPage extends HookConsumerWidget { autocompleteOptionBuilder: (option, onSelected) => ListTile( leading: CircleAvatar( backgroundImage: UniversalImage.imageProvider( - TypeConversionUtils.image_X_UrlString( - option.album?.images, + (option.album?.images).asUrlString( placeholder: ImagePlaceholder.artist, ), ), diff --git a/lib/pages/lyrics/lyrics.dart b/lib/pages/lyrics/lyrics.dart index 9c777660..0482cfe9 100644 --- a/lib/pages/lyrics/lyrics.dart +++ b/lib/pages/lyrics/lyrics.dart @@ -11,6 +11,7 @@ import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/components/shared/themed_button_tab_bar.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/hooks/utils/use_custom_status_bar_color.dart'; import 'package:spotube/hooks/utils/use_palette_color.dart'; import 'package:spotube/pages/lyrics/plain_lyrics.dart'; @@ -28,8 +29,7 @@ class LyricsPage extends HookConsumerWidget { Widget build(BuildContext context, ref) { final playlist = ref.watch(ProxyPlaylistNotifier.provider); String albumArt = useMemoized( - () => TypeConversionUtils.image_X_UrlString( - playlist.activeTrack?.album?.images, + () => (playlist.activeTrack?.album?.images).asUrlString( index: (playlist.activeTrack?.album?.images?.length ?? 1) - 1, placeholder: ImagePlaceholder.albumArt, ), diff --git a/lib/pages/playlist/playlist.dart b/lib/pages/playlist/playlist.dart index 7962c66a..3a0f9ec6 100644 --- a/lib/pages/playlist/playlist.dart +++ b/lib/pages/playlist/playlist.dart @@ -6,6 +6,7 @@ import 'package:spotube/components/shared/tracks_view/sections/body/use_is_user_ import 'package:spotube/components/shared/tracks_view/track_view.dart'; import 'package:spotube/components/shared/tracks_view/track_view_props.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; @@ -30,8 +31,7 @@ class PlaylistPage extends HookConsumerWidget { return InheritedTrackView( collectionId: playlist.id!, - image: TypeConversionUtils.image_X_UrlString( - playlist.images, + image: playlist.images.asUrlString( placeholder: ImagePlaceholder.collection, ), pagination: PaginationProps( diff --git a/lib/pages/track/track.dart b/lib/pages/track/track.dart index ca5dbf95..aef9a083 100644 --- a/lib/pages/track/track.dart +++ b/lib/pages/track/track.dart @@ -12,6 +12,7 @@ import 'package:spotube/components/shared/links/link_text.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/components/shared/track_tile/track_options.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; @@ -60,8 +61,7 @@ class TrackPage extends HookConsumerWidget { decoration: BoxDecoration( image: DecorationImage( image: UniversalImage.imageProvider( - TypeConversionUtils.image_X_UrlString( - track.album!.images, + track.album!.images.asUrlString( placeholder: ImagePlaceholder.albumArt, ), ), @@ -104,8 +104,7 @@ class TrackPage extends HookConsumerWidget { ClipRRect( borderRadius: BorderRadius.circular(10), child: UniversalImage( - path: TypeConversionUtils.image_X_UrlString( - track.album!.images, + path: track.album!.images.asUrlString( placeholder: ImagePlaceholder.albumArt, ), height: 200, diff --git a/lib/provider/download_manager_provider.dart b/lib/provider/download_manager_provider.dart index dc538938..abf4ed6c 100644 --- a/lib/provider/download_manager_provider.dart +++ b/lib/provider/download_manager_provider.dart @@ -9,6 +9,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:metadata_god/metadata_god.dart'; import 'package:path/path.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; import 'package:spotube/services/download_manager/download_manager.dart'; import 'package:spotube/services/sourced_track/enums.dart'; @@ -52,8 +53,10 @@ class DownloadManagerProvider extends ChangeNotifier { } final imageBytes = await downloadImage( - TypeConversionUtils.image_X_UrlString(track.album?.images, - placeholder: ImagePlaceholder.albumArt, index: 1), + (track.album?.images).asUrlString( + placeholder: ImagePlaceholder.albumArt, + index: 1, + ), ); final metadata = Metadata( diff --git a/lib/provider/proxy_playlist/proxy_playlist_provider.dart b/lib/provider/proxy_playlist/proxy_playlist_provider.dart index 0811fe35..aea873dd 100644 --- a/lib/provider/proxy_playlist/proxy_playlist_provider.dart +++ b/lib/provider/proxy_playlist/proxy_playlist_provider.dart @@ -10,6 +10,7 @@ import 'package:http/http.dart'; import 'package:palette_generator/palette_generator.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/models/local_track.dart'; import 'package:spotube/models/logger.dart'; @@ -522,8 +523,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier final palette = await PaletteGenerator.fromImageProvider( UniversalImage.imageProvider( - TypeConversionUtils.image_X_UrlString( - state.activeTrack?.album?.images, + (state.activeTrack?.album?.images).asUrlString( placeholder: ImagePlaceholder.albumArt, ), height: 50, diff --git a/lib/services/audio_services/audio_services.dart b/lib/services/audio_services/audio_services.dart index a6ecac3f..068b41ba 100644 --- a/lib/services/audio_services/audio_services.dart +++ b/lib/services/audio_services/audio_services.dart @@ -2,6 +2,7 @@ import 'package:audio_service/audio_service.dart'; import 'package:flutter_desktop_tools/flutter_desktop_tools.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/services/audio_services/mobile_audio_service.dart'; import 'package:spotube/services/audio_services/windows_audio_service.dart'; @@ -50,10 +51,11 @@ class AudioServices { duration: track is SourcedTrack ? track.sourceInfo.duration : Duration(milliseconds: track.durationMs ?? 0), - artUri: Uri.parse(TypeConversionUtils.image_X_UrlString( - track.album?.images ?? [], - placeholder: ImagePlaceholder.albumArt, - )), + artUri: Uri.parse( + (track.album?.images).asUrlString( + placeholder: ImagePlaceholder.albumArt, + ), + ), playable: true, )); } diff --git a/lib/services/audio_services/linux_audio_service.dart b/lib/services/audio_services/linux_audio_service.dart index 2dfef362..11399e67 100644 --- a/lib/services/audio_services/linux_audio_service.dart +++ b/lib/services/audio_services/linux_audio_service.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:dbus/dbus.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; @@ -309,8 +310,7 @@ class _MprisMediaPlayer2Player extends DBusObject { (await audioPlayer.duration)?.inMicroseconds ?? 0, ), "mpris:artUrl": DBusString( - TypeConversionUtils.image_X_UrlString( - playlist.activeTrack?.album?.images, + (playlist.activeTrack?.album?.images).asUrlString( placeholder: ImagePlaceholder.albumArt, ), ), diff --git a/lib/services/audio_services/windows_audio_service.dart b/lib/services/audio_services/windows_audio_service.dart index fde88145..2df0e9fe 100644 --- a/lib/services/audio_services/windows_audio_service.dart +++ b/lib/services/audio_services/windows_audio_service.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:smtc_windows/smtc_windows.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/extensions/image.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:spotube/services/audio_player/playback_state.dart'; @@ -80,16 +81,18 @@ class WindowsAudioService { if (!smtc.enabled) { await smtc.enableSmtc(); } - await smtc.updateMetadata(MusicMetadata( - title: track.name!, - albumArtist: track.artists?.firstOrNull?.name ?? "Unknown", - artist: TypeConversionUtils.artists_X_String(track.artists ?? []), - album: track.album?.name ?? "Unknown", - thumbnail: TypeConversionUtils.image_X_UrlString( - track.album?.images ?? [], - placeholder: ImagePlaceholder.albumArt, + await smtc.updateMetadata( + MusicMetadata( + title: track.name!, + albumArtist: track.artists?.firstOrNull?.name ?? "Unknown", + artist: + TypeConversionUtils.artists_X_String(track.artists ?? []), + album: track.album?.name ?? "Unknown", + thumbnail: (track.album?.images).asUrlString( + placeholder: ImagePlaceholder.albumArt, + ), ), - )); + ); } void dispose() { diff --git a/lib/utils/type_conversion_utils.dart b/lib/utils/type_conversion_utils.dart index d5eb68f6..639299a1 100644 --- a/lib/utils/type_conversion_utils.dart +++ b/lib/utils/type_conversion_utils.dart @@ -2,14 +2,11 @@ import 'dart:io'; -import 'package:collection/collection.dart'; import 'package:flutter/widgets.dart' hide Image; import 'package:metadata_god/metadata_god.dart'; import 'package:path/path.dart'; -import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/components/shared/links/anchor_button.dart'; import 'package:spotify/spotify.dart'; -import 'package:spotube/utils/primitive_utils.dart'; import 'package:spotube/utils/service_utils.dart'; enum ImagePlaceholder { @@ -20,28 +17,6 @@ enum ImagePlaceholder { } abstract class TypeConversionUtils { - static String image_X_UrlString( - List? images, { - int index = 1, - required ImagePlaceholder placeholder, - }) { - final String placeholderUrl = { - ImagePlaceholder.albumArt: Assets.albumPlaceholder.path, - ImagePlaceholder.artist: Assets.userPlaceholder.path, - ImagePlaceholder.collection: Assets.placeholder.path, - ImagePlaceholder.online: - "https://avatars.dicebear.com/api/bottts/${PrimitiveUtils.uuid.v4()}.png", - }[placeholder]!; - - final sortedImage = images?.sorted((a, b) => a.width!.compareTo(b.width!)); - - return sortedImage != null && sortedImage.isNotEmpty - ? sortedImage[ - index > sortedImage.length - 1 ? sortedImage.length - 1 : index] - .url! - : placeholderUrl; - } - static String artists_X_String(List artists) { return artists.map((e) => e.name?.replaceAll(",", " ")).join(", "); }