From 9a68001a4bd1e09a2fc3929b939d521c768e6ef2 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 8 Jun 2022 15:50:13 -0400 Subject: [PATCH] fix: trigger favorite update across active views of favorite tracks #132 --- src/components/common/FavoriteTrack.tsx | 30 +++++++++++++++++++++++-- src/contexts/globalState.tsx | 19 ++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/components/common/FavoriteTrack.tsx b/src/components/common/FavoriteTrack.tsx index a9cede7..fe1e17e 100644 --- a/src/components/common/FavoriteTrack.tsx +++ b/src/components/common/FavoriteTrack.tsx @@ -1,7 +1,11 @@ import { css } from "@emotion/css"; +import { useGlobalStateContext } from "contexts/globalState"; import React from "react"; import { FaStar, FaRegStar } from "react-icons/fa"; -import { addTrackToUserFavorites } from "../../services/Api"; +import { + addTrackToUserFavorites, + checkTrackIdsForFavorite, +} from "../../services/Api"; import IconButton from "./IconButton"; export const spinner = css` @@ -30,6 +34,11 @@ export const SpinningStar: React.FC<{ spinning: boolean; full: boolean }> = ({ export const FavoriteTrack: React.FC<{ track: TrackWithUserCounts }> = ({ track, }) => { + const { + state: { checkFavoriteStatusFlag }, + dispatch, + } = useGlobalStateContext(); + const [isFavorite, setIsFavorite] = React.useState(track.favorite); const [loadingFavorite, setLoadingFavorite] = React.useState(false); @@ -42,9 +51,26 @@ export const FavoriteTrack: React.FC<{ track: TrackWithUserCounts }> = ({ await addTrackToUserFavorites(track.id); setIsFavorite((val) => !val); setLoadingFavorite(false); + dispatch({ type: "incrementFavoriteStatusFlag" }); }, - [track.id] + [track.id, dispatch] ); + + const onFavoriteStatusFlagChange = React.useCallback(async () => { + const resolution = await checkTrackIdsForFavorite([track.id]); + if (resolution.length > 0 && resolution[0].track_id === track.id) { + setIsFavorite(true); + } else { + setIsFavorite(false); + } + }, [track]); + + React.useEffect(() => { + if (checkFavoriteStatusFlag) { + onFavoriteStatusFlagChange(); + } + }, [checkFavoriteStatusFlag, onFavoriteStatusFlagChange]); + return ( diff --git a/src/contexts/globalState.tsx b/src/contexts/globalState.tsx index 4c351fb..7989056 100644 --- a/src/contexts/globalState.tsx +++ b/src/contexts/globalState.tsx @@ -12,6 +12,7 @@ export interface GlobalState { draggingTrackId?: number; currentlyPlayingIndex?: number; userPlaylists?: { id: string; title: string }[]; + checkFavoriteStatusFlag?: number; } type SetLoggedInUser = { @@ -19,6 +20,10 @@ type SetLoggedInUser = { user?: LoggedInUser; }; +type IncrementFavoriteStatusFlag = { + type: "incrementFavoriteStatusFlag"; +}; + type ClearQueue = { type: "clearQueue"; }; @@ -112,7 +117,8 @@ type Actions = | IncrementCurrentlyPlayingIndex | DecrementCurrentlyPlayingIndex | SetUserCredits - | SetUserPlaylists; + | SetUserPlaylists + | IncrementFavoriteStatusFlag; export const stateReducer = produce((draft: GlobalState, action: Actions) => { switch (action.type) { @@ -217,12 +223,20 @@ export const stateReducer = produce((draft: GlobalState, action: Actions) => { case "setUserPlaylists": draft.userPlaylists = action.playlists; break; + case "incrementFavoriteStatusFlag": + draft.checkFavoriteStatusFlag = (draft.checkFavoriteStatusFlag ?? 0) + 1; + break; default: break; } localStorage.setItem( "state", - JSON.stringify({ ...draft, playing: undefined }) // We don't want playing to be persisted + JSON.stringify({ + ...draft, + // We don't want these to be persisted + checkFavoriteStatusFlag: undefined, + playing: undefined, + }) ); return draft; }); @@ -247,6 +261,7 @@ export const GlobalStateProvider: React.FC = ({ storedState.playerQueueIds = []; } } catch (e) {} + const [state, dispatch] = React.useReducer( stateReducer, storedState ?? { playerQueueIds: [] }