refactor(image-to-string): use asset placeholders instead of dicebear URIs

This commit is contained in:
Kingkor Roy Tirtho 2022-09-08 23:55:48 +06:00
parent 531fae64f9
commit daa62c73f7
23 changed files with 115 additions and 48 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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