diff --git a/front/components/FavSongRow.tsx b/front/components/FavSongRow.tsx index 7c5a439..3893042 100644 --- a/front/components/FavSongRow.tsx +++ b/front/components/FavSongRow.tsx @@ -2,9 +2,9 @@ import { HStack, IconButton, Image, Text } from 'native-base'; import RowCustom from './RowCustom'; import TextButton from './TextButton'; import { MaterialIcons } from '@expo/vector-icons'; -import API from '../API'; import DurationComponent from './DurationComponent'; import Song from '../models/Song'; +import { useLikeSongMutation } from '../utils/likeSongMutation'; type FavSongRowProps = { song: Song; @@ -13,6 +13,8 @@ type FavSongRowProps = { }; const FavSongRow = ({ song, addedDate, onPress }: FavSongRowProps) => { + const { mutate } = useLikeSongMutation(); + return ( @@ -63,7 +65,7 @@ const FavSongRow = ({ song, addedDate, onPress }: FavSongRowProps) => { variant={'ghost'} borderRadius={'full'} onPress={() => { - API.removeLikedSong(song.id); + mutate({ songId: song.id, like: false }); }} _icon={{ as: MaterialIcons, diff --git a/front/components/SearchResult.tsx b/front/components/SearchResult.tsx index 9cfe8e0..d682e8b 100644 --- a/front/components/SearchResult.tsx +++ b/front/components/SearchResult.tsx @@ -24,6 +24,7 @@ import Song from '../models/Song'; import { useNavigation } from '../Navigation'; import SongRow from '../components/SongRow'; import FavSongRow from './FavSongRow'; +import { useLikeSongMutation } from '../utils/likeSongMutation'; const swaToSongCardProps = (song: Song) => ({ songId: song.id, @@ -89,6 +90,7 @@ const SongsSearchComponent = (props: SongsSearchComponentProps) => { if (state == false) await API.removeLikedSong(songId); else await API.addLikedSong(songId); }; + const { mutate } = useLikeSongMutation(); return ( @@ -102,8 +104,8 @@ const SongsSearchComponent = (props: SongsSearchComponentProps) => { isLiked={ !favoritesQuery.data?.find((query) => query?.songId == comp.id) } - handleLike={(state: boolean, songId: number) => - handleFavoriteButton(state, songId) + handleLike={async (state: boolean, songId: number) => + mutate({ songId: songId, like: state }) } onPress={() => { API.createSearchHistoryEntry(comp.name, 'song'); diff --git a/front/utils/likeSongMutation.ts b/front/utils/likeSongMutation.ts new file mode 100644 index 0000000..01f00d5 --- /dev/null +++ b/front/utils/likeSongMutation.ts @@ -0,0 +1,19 @@ +import { useMutation, useQueryClient } from "react-query" +import API from "../API"; + +/** + * Mutation to like/unlike a song + */ +export const useLikeSongMutation = () => { + const queryClient = useQueryClient(); + + return useMutation(({ songId, like }: {songId: number, like: boolean}) => { + const apiCall = like ? API.addLikedSong : API.removeLikedSong + + return apiCall(songId).then(() => { + queryClient.invalidateQueries('liked songs') + queryClient.invalidateQueries('songs') + queryClient.invalidateQueries([songId]) + }); + }); +} \ No newline at end of file diff --git a/front/views/ArtistDetailsView.tsx b/front/views/ArtistDetailsView.tsx index 72e83ff..7f4ba84 100644 --- a/front/views/ArtistDetailsView.tsx +++ b/front/views/ArtistDetailsView.tsx @@ -7,6 +7,7 @@ import SongRow from '../components/SongRow'; import { Key } from 'react'; import { RouteProps, useNavigation } from '../Navigation'; import { ImageBackground } from 'react-native'; +import { useLikeSongMutation } from '../utils/likeSongMutation'; type ArtistDetailsViewProps = { artistId: number; @@ -20,11 +21,7 @@ const ArtistDetailsView = ({ artistId }: RouteProps) => const navigation = useNavigation(); const favoritesQuery = useQuery(API.getLikedSongs()); - - const handleFavoriteButton = async (state: boolean, songId: number): Promise => { - if (state == false) await API.removeLikedSong(songId); - else await API.addLikedSong(songId); - }; + const { mutate } = useLikeSongMutation(); if (artistQuery.isError || songsQuery.isError) { navigation.navigate('Error'); @@ -53,8 +50,8 @@ const ArtistDetailsView = ({ artistId }: RouteProps) => isLiked={ !favoritesQuery.data?.find((query) => query?.songId == comp.id) } - handleLike={(state: boolean, songId: number) => - handleFavoriteButton(state, songId) + handleLike={async (state: boolean, songId: number) => + mutate({ songId: songId, like: state }) } onPress={() => { API.createSearchHistoryEntry(comp.name, 'song'); diff --git a/front/views/MusicView.tsx b/front/views/MusicView.tsx index 50bf7c8..7b40347 100644 --- a/front/views/MusicView.tsx +++ b/front/views/MusicView.tsx @@ -1,5 +1,9 @@ import React from 'react'; +<<<<<<< HEAD import { Center, useBreakpointValue, useTheme } from 'native-base'; +======= +import { Center, Text, Toast, useBreakpointValue, useTheme } from 'native-base'; +>>>>>>> 06cfa56 (Front: Use Mutations to update 'liked' state) import { useWindowDimensions } from 'react-native'; import { TabView, @@ -18,10 +22,12 @@ import MusicList from '../components/UI/MusicList'; import { useQuery } from '../Queries'; import API from '../API'; import { LoadingView } from '../components/Loading'; +import { useLikeSongMutation } from '../utils/likeSongMutation'; export const FavoritesMusic = () => { const navigation = useNavigation(); const likedSongs = useQuery(API.getLikedSongs(['artist', 'SongHistory'])); + const { mutate } = useLikeSongMutation(); const musics = likedSongs.data?.map((x) => ({ @@ -32,7 +38,8 @@ export const FavoritesMusic = () => { bestScore: x.song.bestScore, liked: true, onLike: () => { - console.log('onLike'); + Toast.show({ description: 'aaaaaaa' }) + mutate({ songId: x.id, like: false }) }, onPlay: () => navigation.navigate('Play', { songId: x.song.id }), })) ?? [];