[slightly less scuffed bugfix]: Update table rating/favorite when updated anywhere … (#707)

* [scuffed bugfix]: Update table rating/favorite when updated anywhere else

Modify player store to have temporary state for favorite/rating update
Add effect handler for `virtual-table` to update rating/favorite for players

Note that this does not handle song grid view.
Using a similar handler for gird view did not work, as it appeared to result in inconsistent state.

Finally, this is probably not the optimal solution.
Performance appears fine for ~20k items, but no guarantees.

* restore should update song

* update song rating/favorite/played everywhere except playlist

* special rule for playlists

* use iterator instead
This commit is contained in:
Kendall Garner 2024-09-02 22:31:20 -07:00 committed by GitHub
parent 9d44f0fc08
commit 56c229a5e0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 223 additions and 143 deletions

View file

@ -0,0 +1,71 @@
import { create } from 'zustand';
import { devtools, subscribeWithSelector } from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer';
export type FavoriteEvent = {
event: 'favorite';
favorite: boolean;
};
export type PlayEvent = {
event: 'play';
timestamp: string;
};
export type RatingEvent = {
event: 'rating';
rating: number | null;
};
export type UserEvent = FavoriteEvent | PlayEvent | RatingEvent;
export interface EventState {
event: UserEvent | null;
ids: string[];
}
export interface EventSlice extends EventState {
actions: {
favorite: (ids: string[], favorite: boolean) => void;
play: (ids: string[]) => void;
rate: (ids: string[], rating: number | null) => void;
};
}
export const useEventStore = create<EventSlice>()(
subscribeWithSelector(
devtools(
immer((set) => ({
actions: {
favorite(ids, favorite) {
set((state) => {
state.event = { event: 'favorite', favorite };
state.ids = ids;
});
},
play(ids) {
set((state) => {
state.event = { event: 'play', timestamp: new Date().toISOString() };
state.ids = ids;
});
},
rate(ids, rating) {
set((state) => {
state.event = { event: 'rating', rating };
state.ids = ids;
});
},
},
event: null,
ids: [],
})),
{ name: 'event_store' },
),
),
);
export const useFavoriteEvent = () => useEventStore((state) => state.actions.favorite);
export const usePlayEvent = () => useEventStore((state) => state.actions.play);
export const useRatingEvent = () => useEventStore((state) => state.actions.rate);