mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
feat: heart button animation
This commit is contained in:
parent
af278d8fea
commit
8432dc6286
@ -4,7 +4,6 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
import 'package:spotube/collections/spotube_icons.dart';
|
|
||||||
import 'package:spotube/hooks/use_palette_color.dart';
|
import 'package:spotube/hooks/use_palette_color.dart';
|
||||||
import 'package:spotube/provider/authentication_provider.dart';
|
import 'package:spotube/provider/authentication_provider.dart';
|
||||||
import 'package:spotube/services/mutations/mutations.dart';
|
import 'package:spotube/services/mutations/mutations.dart';
|
||||||
@ -13,7 +12,7 @@ import 'package:spotube/services/queries/queries.dart';
|
|||||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
class HeartButton extends ConsumerWidget {
|
class HeartButton extends HookConsumerWidget {
|
||||||
final bool isLiked;
|
final bool isLiked;
|
||||||
final void Function()? onPressed;
|
final void Function()? onPressed;
|
||||||
final IconData? icon;
|
final IconData? icon;
|
||||||
@ -36,9 +35,24 @@ class HeartButton extends ConsumerWidget {
|
|||||||
|
|
||||||
return IconButton(
|
return IconButton(
|
||||||
tooltip: tooltip,
|
tooltip: tooltip,
|
||||||
icon: Icon(
|
icon: AnimatedSwitcher(
|
||||||
icon ?? (!isLiked ? SpotubeIcons.heart : SpotubeIcons.heartFilled),
|
switchInCurve: Curves.fastOutSlowIn,
|
||||||
color: isLiked ? Colors.pink : color,
|
switchOutCurve: Curves.fastOutSlowIn,
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
transitionBuilder: (child, animation) {
|
||||||
|
return ScaleTransition(
|
||||||
|
scale: animation,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Icon(
|
||||||
|
icon ??
|
||||||
|
(isLiked
|
||||||
|
? Icons.favorite_rounded
|
||||||
|
: Icons.favorite_outline_rounded),
|
||||||
|
key: ValueKey(isLiked),
|
||||||
|
color: color ?? (isLiked ? color ?? Colors.red : null),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
);
|
);
|
||||||
@ -53,29 +67,36 @@ Tuple3<bool, Mutation<bool, dynamic, bool>, Query<User, dynamic>>
|
|||||||
useQueries.playlist.tracksOfQuery(ref, "user-liked-tracks");
|
useQueries.playlist.tracksOfQuery(ref, "user-liked-tracks");
|
||||||
|
|
||||||
final isLiked =
|
final isLiked =
|
||||||
savedTracks.data?.map((track) => track.id).contains(track.id) ?? false;
|
savedTracks.data?.any((element) => element.id == track.id) ?? false;
|
||||||
|
|
||||||
final mounted = useIsMounted();
|
final mounted = useIsMounted();
|
||||||
|
|
||||||
final toggleTrackLike = useMutations.track.toggleFavorite(
|
final toggleTrackLike = useMutations.track.toggleFavorite(
|
||||||
ref,
|
ref,
|
||||||
track.id!,
|
track.id!,
|
||||||
onMutate: (variables) {
|
onMutate: (isLiked) {
|
||||||
return variables;
|
savedTracks.setData(
|
||||||
|
[
|
||||||
|
if (isLiked == true)
|
||||||
|
...?savedTracks.data?.where((element) => element.id != track.id)
|
||||||
|
else
|
||||||
|
...?savedTracks.data?..add(track)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
return isLiked;
|
||||||
|
},
|
||||||
|
onData: (data, recoveryData) async {
|
||||||
|
await savedTracks.refresh();
|
||||||
},
|
},
|
||||||
onError: (payload, isLiked) {
|
onError: (payload, isLiked) {
|
||||||
if (!mounted()) return;
|
if (!mounted()) return;
|
||||||
|
|
||||||
savedTracks.setData(
|
savedTracks.setData([
|
||||||
isLiked == true
|
if (isLiked != true)
|
||||||
? [...(savedTracks.data ?? []), track]
|
...?savedTracks.data?.where((element) => element.id != track.id)
|
||||||
: savedTracks.data
|
else
|
||||||
?.where(
|
...?savedTracks.data?..add(track),
|
||||||
(element) => element.id != track.id,
|
]);
|
||||||
)
|
|
||||||
.toList() ??
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -377,7 +377,9 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
color: Colors.pink,
|
color: Colors.pink,
|
||||||
)
|
)
|
||||||
: const Icon(SpotubeIcons.heart),
|
: const Icon(SpotubeIcons.heart),
|
||||||
title: const Text("Save as favorite"),
|
title: Text(
|
||||||
|
"${toggler.item1 ? "Remove from" : "Save as "} favorite",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (auth != null)
|
if (auth != null)
|
||||||
|
Loading…
Reference in New Issue
Block a user