[READ-ONLY] Mirror of https://github.com/FoxxMD/multi-scrobbler. Scrobble plays from multiple sources to multiple clients docs.multi-scrobbler.app
deezer docker jellyfin koito lastfm listenbrainz maloja mopidy mpris music music-assistant plex scrobble self-hosted spotify subsonic tautulli youtube-music
0

Configure Feed

Select the types of activity you want to include in your feed.

fix(ui): Fix conditional hook rendering

FoxxMD (Jul 6, 2026, 8:08 PM UTC) 5daba47a 8d7760df

+15 -15
+4 -3
src/client/components/PlayData.tsx
··· 45 45 dates = 'all' 46 46 } = props ?? {}; 47 47 48 - if (play === undefined) { 49 - return <EmptyPlayData /> 50 - } 51 48 52 49 const [codeMode, setCodeMode] = useState(false); 53 50 54 51 let code: React.JSX.Element | null = null; 55 52 56 53 const comparable = showCompare && final !== undefined; 54 + 55 + if (play === undefined) { 56 + return <EmptyPlayData /> 57 + } 57 58 58 59 if (showCodeToggle) { 59 60 code = (
+11 -12
src/client/components/chakraPlayer/Player.tsx
··· 69 69 const [positionBuffer, setProgressBuffer] = useState<undefined | number>(undefined); 70 70 const [intervalId, setIntervalId] = useState<undefined | number>(undefined); 71 71 const [lastUpdated, setLastUpdated] = useState<undefined | number>(undefined); 72 - 73 - if(expiration !== undefined && dayjs().isAfter(dayjs(expiration))) { 74 - return null; 75 - } 76 - 77 72 const playArt = art.track ?? art.album ?? art.artist ?? undefined; 78 73 79 74 const isNowPlaying = nowPlaying || nowPlayingMode; ··· 141 136 } 142 137 return () => clearInterval(interval); 143 138 },[setProgressBuffer, data, setIntervalId, setLastUpdated, isNowPlaying]); 139 + 140 + if(expiration !== undefined && dayjs().isAfter(dayjs(expiration))) { 141 + return null; 142 + } 144 143 145 144 const indeterminate = isNowPlaying || (calculated === 'playing' && data.position === undefined); 146 145 const positionProgress = indeterminate || data.position === undefined || duration === undefined ? undefined : Math.trunc((data.position/duration) * 100); ··· 227 226 initData?: SourcePlayerJson 228 227 } 229 228 230 - export function usePlayerQuery(componentId: number, platformId: string, opts: UsePlayerQueryOpts = {}) { 229 + export const usePlayerQuery = (componentId: number, platformId: string, opts: UsePlayerQueryOpts = {}) => { 231 230 const { initData } = opts; 232 231 const queryClient = useQueryClient(); 233 232 useEffect(() => { 234 233 if (initData !== undefined && queryClient.getQueryData(tanQueries.players.single(componentId, platformId).queryKey) === undefined) { 235 234 queryClient.setQueryData(tanQueries.players.single(componentId, platformId).queryKey, initData); 236 235 } 237 - }, [initData]); 236 + }, [initData, componentId, platformId]); 238 237 239 238 const client = useSSEContext<MsSseEvent<MsSseEventPayload<SourcePlayerJson>>>(); 240 239 useSSEEvent(client, "playerUpdate", (payload) => { ··· 264 263 players = {} 265 264 } = data; 266 265 267 - let playerContainers: React.JSX.Element[] = []; 266 + const playerContainers: React.JSX.Element[] = []; 268 267 // const isSource = isComponentSourceApiJson(data); 269 268 // const now = dayjs(); 270 269 if (Object.keys(players).length > 0) { ··· 292 291 </Stack>; 293 292 } 294 293 295 - function usePlayersQuery(componentId: number, players?: ComponentCommonApiJson['players']) { 294 + const usePlayersQuery = (componentId: number, players?: ComponentCommonApiJson['players']) => { 296 295 const queryClient = useQueryClient(); 297 296 298 297 useEffect(() => { 299 298 if(queryClient.getQueryData(tanQueries.players.list(componentId).queryKey) === undefined) { 300 299 queryClient.setQueryData(tanQueries.players.list(componentId).queryKey, players ?? {}); 301 300 } 302 - }, [players]); 301 + }, [players, componentId]); 303 302 304 303 const client = useSSEContext<MsSseEvent>(); 305 304 useSSEAnyEvent(client, (payload) => { ··· 309 308 const playerPayload = payload.data as MsSseEventPayload<SourcePlayerJson>; 310 309 queryClient.setQueryData(tanQueries.players.list(componentId).queryKey, (old: Record<string, SourcePlayerJson>) => { 311 310 if(old[playerPayload.data.platformId] === undefined || 'expiration' in playerPayload.data) { 312 - let newData: Record<string, SourcePlayerJson> = {...old}; 311 + const newData: Record<string, SourcePlayerJson> = {...old}; 313 312 newData[playerPayload.data.platformId] = playerPayload.data; 314 313 return newData; 315 314 } ··· 320 319 const playerPayload = payload.data as MsSseEventPayload<{platformId: string}>; 321 320 queryClient.setQueryData(tanQueries.players.list(componentId).queryKey, (old: Record<string, SourcePlayerJson>) => { 322 321 if(old[playerPayload.data.platformId] !== undefined) { 323 - let newData: Record<string, SourcePlayerJson> = {...old}; 322 + const newData: Record<string, SourcePlayerJson> = {...old}; 324 323 delete newData[playerPayload.data.platformId]; 325 324 return newData; 326 325 }