mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
refactor(image-to-string): use asset placeholders instead of dicebear URIs
This commit is contained in:
parent
531fae64f9
commit
daa62c73f7
@ -21,7 +21,10 @@ class AlbumCard extends HookConsumerWidget {
|
||||
final int marginH =
|
||||
useBreakpointValue(sm: 10, md: 15, lg: 20, xl: 20, xxl: 20);
|
||||
return PlaybuttonCard(
|
||||
imageUrl: TypeConversionUtils.image_X_UrlString(album.images),
|
||||
imageUrl: TypeConversionUtils.image_X_UrlString(
|
||||
album.images,
|
||||
placeholder: ImagePlaceholder.collection,
|
||||
),
|
||||
margin: EdgeInsets.symmetric(horizontal: marginH.toDouble()),
|
||||
isPlaying: isPlaylistPlaying && playback.isPlaying,
|
||||
isLoading: playback.status == PlaybackStatus.loading &&
|
||||
|
@ -27,7 +27,10 @@ class AlbumView extends HookConsumerWidget {
|
||||
tracks: tracks,
|
||||
id: album.id!,
|
||||
name: album.name!,
|
||||
thumbnail: TypeConversionUtils.image_X_UrlString(album.images),
|
||||
thumbnail: TypeConversionUtils.image_X_UrlString(
|
||||
album.images,
|
||||
placeholder: ImagePlaceholder.collection,
|
||||
),
|
||||
),
|
||||
tracks.indexWhere((s) => s.id == currentTrack?.id),
|
||||
);
|
||||
@ -50,7 +53,10 @@ class AlbumView extends HookConsumerWidget {
|
||||
ref.watch(albumIsSavedForCurrentUserQuery(album.id!));
|
||||
|
||||
final albumArt = useMemoized(
|
||||
() => TypeConversionUtils.image_X_UrlString(album.images),
|
||||
() => TypeConversionUtils.image_X_UrlString(
|
||||
album.images,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
),
|
||||
[album.images]);
|
||||
|
||||
final breakpoint = useBreakpoints();
|
||||
|
@ -4,6 +4,8 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/Shared/HoverBuilder.dart';
|
||||
import 'package:spotube/components/Shared/SpotubeMarqueeText.dart';
|
||||
import 'package:spotube/components/Shared/UniversalImage.dart';
|
||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||
|
||||
class ArtistCard extends StatelessWidget {
|
||||
final Artist artist;
|
||||
@ -11,11 +13,11 @@ class ArtistCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final backgroundImage = CachedNetworkImageProvider((artist
|
||||
.images?.isNotEmpty ??
|
||||
false)
|
||||
? artist.images!.first.url!
|
||||
: "https://avatars.dicebear.com/api/open-peeps/${artist.id}.png?b=%231ed760&r=50&flip=1&translateX=3&translateY=-6");
|
||||
final backgroundImage =
|
||||
UniversalImage.imageProvider(TypeConversionUtils.image_X_UrlString(
|
||||
artist.images,
|
||||
placeholder: ImagePlaceholder.artist,
|
||||
));
|
||||
return SizedBox(
|
||||
height: 240,
|
||||
width: 200,
|
||||
|
@ -1,4 +1,3 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
@ -10,6 +9,7 @@ import 'package:spotube/components/Artist/ArtistCard.dart';
|
||||
import 'package:spotube/components/LoaderShimmers/ShimmerArtistProfile.dart';
|
||||
import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
|
||||
import 'package:spotube/components/Shared/TrackTile.dart';
|
||||
import 'package:spotube/components/Shared/UniversalImage.dart';
|
||||
import 'package:spotube/hooks/useBreakpointValue.dart';
|
||||
import 'package:spotube/hooks/useBreakpoints.dart';
|
||||
import 'package:spotube/models/CurrentPlaylist.dart';
|
||||
@ -78,8 +78,11 @@ class ArtistProfile extends HookConsumerWidget {
|
||||
const SizedBox(width: 50),
|
||||
CircleAvatar(
|
||||
radius: avatarWidth,
|
||||
backgroundImage: CachedNetworkImageProvider(
|
||||
TypeConversionUtils.image_X_UrlString(data.images),
|
||||
backgroundImage: UniversalImage.imageProvider(
|
||||
TypeConversionUtils.image_X_UrlString(
|
||||
data.images,
|
||||
placeholder: ImagePlaceholder.artist,
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
@ -193,7 +196,9 @@ class ArtistProfile extends HookConsumerWidget {
|
||||
id: data.id!,
|
||||
name: "${data.name!} To Tracks",
|
||||
thumbnail: TypeConversionUtils.image_X_UrlString(
|
||||
data.images),
|
||||
data.images,
|
||||
placeholder: ImagePlaceholder.artist,
|
||||
),
|
||||
),
|
||||
tracks.indexWhere((s) => s.id == currentTrack?.id),
|
||||
);
|
||||
@ -234,9 +239,9 @@ class ArtistProfile extends HookConsumerWidget {
|
||||
String? thumbnailUrl =
|
||||
TypeConversionUtils.image_X_UrlString(
|
||||
track.value.album?.images,
|
||||
index:
|
||||
(track.value.album?.images?.length ?? 1) -
|
||||
1);
|
||||
index: (track.value.album?.images?.length ?? 1) - 1,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
);
|
||||
return TrackTile(
|
||||
playback,
|
||||
duration: duration,
|
||||
|
@ -5,6 +5,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:spotube/components/Shared/UniversalImage.dart';
|
||||
import 'package:spotube/hooks/useBreakpointValue.dart';
|
||||
import 'package:spotube/hooks/useBreakpoints.dart';
|
||||
import 'package:spotube/models/sideBarTiles.dart';
|
||||
@ -136,7 +137,9 @@ class Sidebar extends HookConsumerWidget {
|
||||
|
||||
final avatarImg = TypeConversionUtils.image_X_UrlString(
|
||||
data?.images,
|
||||
index: (data?.images?.length ?? 1) - 1);
|
||||
index: (data?.images?.length ?? 1) - 1,
|
||||
placeholder: ImagePlaceholder.artist,
|
||||
);
|
||||
if (extended.value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
@ -155,7 +158,8 @@ class Sidebar extends HookConsumerWidget {
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundImage:
|
||||
CachedNetworkImageProvider(avatarImg),
|
||||
UniversalImage.imageProvider(
|
||||
avatarImg),
|
||||
onBackgroundImageError:
|
||||
(exception, stackTrace) =>
|
||||
Image.asset(
|
||||
@ -193,7 +197,7 @@ class Sidebar extends HookConsumerWidget {
|
||||
onTap: () => goToSettings(context),
|
||||
child: CircleAvatar(
|
||||
backgroundImage:
|
||||
CachedNetworkImageProvider(avatarImg),
|
||||
UniversalImage.imageProvider(avatarImg),
|
||||
onBackgroundImageError: (exception, stackTrace) =>
|
||||
Image.asset(
|
||||
"assets/user-placeholder.png",
|
||||
|
@ -3,6 +3,7 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/Shared/UniversalImage.dart';
|
||||
import 'package:spotube/provider/Downloader.dart';
|
||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||
|
||||
@ -53,11 +54,12 @@ class UserDownloads extends HookConsumerWidget {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: CachedNetworkImage(
|
||||
child: UniversalImage(
|
||||
height: 40,
|
||||
width: 40,
|
||||
imageUrl: TypeConversionUtils.image_X_UrlString(
|
||||
path: TypeConversionUtils.image_X_UrlString(
|
||||
track.album?.images,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -108,7 +108,10 @@ class UserLocalTracks extends HookConsumerWidget {
|
||||
tracks: tracks,
|
||||
id: "local",
|
||||
name: "Local Tracks",
|
||||
thumbnail: TypeConversionUtils.image_X_UrlString(null),
|
||||
thumbnail: TypeConversionUtils.image_X_UrlString(
|
||||
null,
|
||||
placeholder: ImagePlaceholder.collection,
|
||||
),
|
||||
isLocal: true,
|
||||
),
|
||||
tracks.indexWhere((s) => s.id == currentTrack?.id),
|
||||
|
@ -112,6 +112,7 @@ class SyncedLyrics extends HookConsumerWidget {
|
||||
() => TypeConversionUtils.image_X_UrlString(
|
||||
playback.track?.album?.images,
|
||||
index: (playback.track?.album?.images?.length ?? 1) - 1,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
),
|
||||
[playback.track?.album?.images],
|
||||
);
|
||||
|
@ -25,6 +25,7 @@ class Player extends HookConsumerWidget {
|
||||
? TypeConversionUtils.image_X_UrlString(
|
||||
playback.track?.album?.images,
|
||||
index: (playback.track?.album?.images?.length ?? 1) - 1,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
)
|
||||
: "assets/album-placeholder.png",
|
||||
[playback.track?.album?.images],
|
||||
|
@ -113,6 +113,7 @@ class PlayerQueue extends HookConsumerWidget {
|
||||
duration: duration,
|
||||
thumbnailUrl: TypeConversionUtils.image_X_UrlString(
|
||||
track.value.album?.images,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
),
|
||||
isActive: playback.track?.id == track.value.id,
|
||||
onTrackPlayButtonPressed: (currentTrack) async {
|
||||
|
@ -42,6 +42,7 @@ class PlayerView extends HookConsumerWidget {
|
||||
() => TypeConversionUtils.image_X_UrlString(
|
||||
currentTrack?.album?.images,
|
||||
index: (currentTrack?.album?.images?.length ?? 1) - 1,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
),
|
||||
[currentTrack?.album?.images],
|
||||
);
|
||||
|
@ -23,7 +23,10 @@ class PlaylistCard extends HookConsumerWidget {
|
||||
return PlaybuttonCard(
|
||||
margin: EdgeInsets.symmetric(horizontal: marginH.toDouble()),
|
||||
title: playlist.name!,
|
||||
imageUrl: TypeConversionUtils.image_X_UrlString(playlist.images),
|
||||
imageUrl: TypeConversionUtils.image_X_UrlString(
|
||||
playlist.images,
|
||||
placeholder: ImagePlaceholder.collection,
|
||||
),
|
||||
isPlaying: isPlaylistPlaying && playback.isPlaying,
|
||||
isLoading: playback.status == PlaybackStatus.loading && isPlaylistPlaying,
|
||||
onTap: () {
|
||||
@ -56,7 +59,10 @@ class PlaylistCard extends HookConsumerWidget {
|
||||
tracks: tracks,
|
||||
id: playlist.id!,
|
||||
name: playlist.name!,
|
||||
thumbnail: TypeConversionUtils.image_X_UrlString(playlist.images),
|
||||
thumbnail: TypeConversionUtils.image_X_UrlString(
|
||||
playlist.images,
|
||||
placeholder: ImagePlaceholder.collection,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -33,7 +33,10 @@ class PlaylistView extends HookConsumerWidget {
|
||||
tracks: tracks,
|
||||
id: playlist.id!,
|
||||
name: playlist.name!,
|
||||
thumbnail: TypeConversionUtils.image_X_UrlString(playlist.images),
|
||||
thumbnail: TypeConversionUtils.image_X_UrlString(
|
||||
playlist.images,
|
||||
placeholder: ImagePlaceholder.collection,
|
||||
),
|
||||
),
|
||||
tracks.indexWhere((s) => s.id == currentTrack?.id),
|
||||
);
|
||||
@ -58,7 +61,10 @@ class PlaylistView extends HookConsumerWidget {
|
||||
final tracksSnapshot = ref.watch(playlistTracksQuery(playlist.id!));
|
||||
|
||||
final titleImage = useMemoized(
|
||||
() => TypeConversionUtils.image_X_UrlString(playlist.images),
|
||||
() => TypeConversionUtils.image_X_UrlString(
|
||||
playlist.images,
|
||||
placeholder: ImagePlaceholder.collection,
|
||||
),
|
||||
[playlist.images]);
|
||||
|
||||
final color = usePaletteGenerator(
|
||||
|
@ -110,7 +110,9 @@ class Search extends HookConsumerWidget {
|
||||
duration: duration,
|
||||
thumbnailUrl:
|
||||
TypeConversionUtils.image_X_UrlString(
|
||||
track.value.album?.images),
|
||||
track.value.album?.images,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
),
|
||||
isActive: playback.track?.id == track.value.id,
|
||||
onTrackPlayButtonPressed: (currentTrack) async {
|
||||
var isPlaylistPlaying =
|
||||
@ -126,6 +128,8 @@ class Search extends HookConsumerWidget {
|
||||
thumbnail: TypeConversionUtils
|
||||
.image_X_UrlString(
|
||||
currentTrack.album?.images,
|
||||
placeholder:
|
||||
ImagePlaceholder.albumArt,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:spotube/components/Shared/UniversalImage.dart';
|
||||
|
||||
class DownloadConfirmationDialog extends StatelessWidget {
|
||||
const DownloadConfirmationDialog({Key? key}) : super(key: key);
|
||||
@ -9,11 +9,11 @@ class DownloadConfirmationDialog extends StatelessWidget {
|
||||
return AlertDialog(
|
||||
contentPadding: const EdgeInsets.all(15),
|
||||
title: Row(
|
||||
children: [
|
||||
const Text("Are you sure?"),
|
||||
const SizedBox(width: 10),
|
||||
CachedNetworkImage(
|
||||
imageUrl:
|
||||
children: const [
|
||||
Text("Are you sure?"),
|
||||
SizedBox(width: 10),
|
||||
UniversalImage(
|
||||
path:
|
||||
"https://c.tenor.com/kHcmsxlKHEAAAAAM/rock-one-eyebrow-raised-rock-staring.gif",
|
||||
height: 40,
|
||||
width: 40,
|
||||
|
@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:spotube/components/Shared/HoverBuilder.dart';
|
||||
import 'package:spotube/components/Shared/SpotubeMarqueeText.dart';
|
||||
import 'package:spotube/components/Shared/UniversalImage.dart';
|
||||
|
||||
class PlaybuttonCard extends StatelessWidget {
|
||||
final void Function()? onTap;
|
||||
@ -55,8 +56,8 @@ class PlaybuttonCard extends StatelessWidget {
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: imageUrl,
|
||||
child: UniversalImage(
|
||||
path: imageUrl,
|
||||
placeholder: (context, url) =>
|
||||
Image.asset("assets/placeholder.png"),
|
||||
),
|
||||
|
@ -5,6 +5,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:spotube/components/LoaderShimmers/ShimmerTrackTile.dart';
|
||||
import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
|
||||
import 'package:spotube/components/Shared/TracksTableView.dart';
|
||||
import 'package:spotube/components/Shared/UniversalImage.dart';
|
||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||
import 'package:spotube/hooks/useCustomStatusBarColor.dart';
|
||||
import 'package:spotube/hooks/usePaletteColor.dart';
|
||||
@ -175,9 +176,7 @@ class TrackCollectionView extends HookConsumerWidget {
|
||||
const BoxConstraints(maxHeight: 200),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: titleImage,
|
||||
),
|
||||
child: UniversalImage(path: titleImage),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
|
@ -149,6 +149,7 @@ class TracksTableView extends HookConsumerWidget {
|
||||
String? thumbnailUrl = TypeConversionUtils.image_X_UrlString(
|
||||
track.value.album?.images,
|
||||
index: (track.value.album?.images?.length ?? 1) - 1,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
);
|
||||
String duration =
|
||||
"${track.value.duration?.inMinutes.remainder(60)}:${PrimitiveUtils.zeroPadNumStr(track.value.duration?.inSeconds.remainder(60) ?? 0)}";
|
||||
|
@ -98,12 +98,9 @@ class Downloader with ChangeNotifier {
|
||||
);
|
||||
final imageUri = TypeConversionUtils.image_X_UrlString(
|
||||
track.album?.images ?? [],
|
||||
placeholder: ImagePlaceholder.online,
|
||||
);
|
||||
final response = await get(
|
||||
Uri.parse(
|
||||
imageUri,
|
||||
),
|
||||
);
|
||||
final response = await get(Uri.parse(imageUri));
|
||||
|
||||
await MetadataGod.writeMetadata(
|
||||
file,
|
||||
|
@ -210,6 +210,7 @@ class Playback extends PersistedChangeNotifier {
|
||||
artUri: Uri.parse(
|
||||
TypeConversionUtils.image_X_UrlString(
|
||||
track.album?.images,
|
||||
placeholder: ImagePlaceholder.online,
|
||||
),
|
||||
),
|
||||
duration: track.ytTrack.duration,
|
||||
|
@ -133,7 +133,10 @@ final currentUserQuery = FutureProvider<User>(
|
||||
Image()
|
||||
..height = 50
|
||||
..width = 50
|
||||
..url = TypeConversionUtils.image_X_UrlString(me.images),
|
||||
..url = TypeConversionUtils.image_X_UrlString(
|
||||
me.images,
|
||||
placeholder: ImagePlaceholder.artist,
|
||||
),
|
||||
];
|
||||
}
|
||||
return me;
|
||||
|
@ -298,7 +298,9 @@ class _MprisMediaPlayer2Player extends DBusObject {
|
||||
"mpris:length": DBusInt32(playback.currentDuration.inMicroseconds),
|
||||
"mpris:artUrl": DBusString(
|
||||
TypeConversionUtils.image_X_UrlString(
|
||||
playback.track?.album?.images),
|
||||
playback.track?.album?.images,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
),
|
||||
),
|
||||
"xesam:album": DBusString(playback.track!.album!.name!),
|
||||
"xesam:artist": DBusArray.string(
|
||||
|
@ -11,11 +11,29 @@ import 'package:spotube/models/SpotubeTrack.dart';
|
||||
import 'package:spotube/utils/primitive_utils.dart';
|
||||
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
|
||||
|
||||
enum ImagePlaceholder {
|
||||
albumArt,
|
||||
artist,
|
||||
collection,
|
||||
online,
|
||||
}
|
||||
|
||||
abstract class TypeConversionUtils {
|
||||
static String image_X_UrlString(List<Image>? images, {int index = 0}) {
|
||||
static String image_X_UrlString(
|
||||
List<Image>? images, {
|
||||
int index = 0,
|
||||
required ImagePlaceholder placeholder,
|
||||
}) {
|
||||
final String placeholderUrl = {
|
||||
ImagePlaceholder.albumArt: "assets/album-placeholder.png",
|
||||
ImagePlaceholder.artist: "assets/user-placeholder.png",
|
||||
ImagePlaceholder.collection: "assets/placeholder.png",
|
||||
ImagePlaceholder.online:
|
||||
"https://avatars.dicebear.com/api/bottts/${PrimitiveUtils.uuid.v4()}.png",
|
||||
}[placeholder]!;
|
||||
return images != null && images.isNotEmpty
|
||||
? images[0].url!
|
||||
: "https://avatars.dicebear.com/api/bottts/${PrimitiveUtils.uuid.v4()}.png";
|
||||
: placeholderUrl;
|
||||
}
|
||||
|
||||
static String artists_X_String<T extends ArtistSimple>(List<T> artists) {
|
||||
|
Loading…
Reference in New Issue
Block a user