refactor: use extension method for image to url string

This commit is contained in:
Kingkor Roy Tirtho 2024-03-21 00:18:43 +06:00
parent 6673e5a8a8
commit 7545ff6415
27 changed files with 99 additions and 90 deletions

View File

@ -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),

View File

@ -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,
),
);

View File

@ -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,

View File

@ -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,
),
),

View File

@ -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],

View File

@ -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,

View File

@ -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,

View File

@ -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,
)

View File

@ -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,
);

View File

@ -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,
),
),

View File

@ -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,
),
),

View File

@ -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,

28
lib/extensions/image.dart Normal file
View File

@ -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<Image>? {
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;
}
}

View File

@ -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,

View File

@ -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!,

View File

@ -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));

View File

@ -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,
);

View File

@ -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,
),
),

View File

@ -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,
),

View File

@ -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(

View File

@ -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,

View File

@ -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(

View File

@ -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<ProxyPlaylist>
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,

View File

@ -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 ?? <Image>[],
placeholder: ImagePlaceholder.albumArt,
)),
artUri: Uri.parse(
(track.album?.images).asUrlString(
placeholder: ImagePlaceholder.albumArt,
),
),
playable: true,
));
}

View File

@ -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,
),
),

View File

@ -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<Artist>(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<Artist>(track.artists ?? []),
album: track.album?.name ?? "Unknown",
thumbnail: (track.album?.images).asUrlString(
placeholder: ImagePlaceholder.albumArt,
),
),
));
);
}
void dispose() {

View File

@ -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<Image>? 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<T extends ArtistSimple>(List<T> artists) {
return artists.map((e) => e.name?.replaceAll(",", " ")).join(", ");
}