mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-05-31 11:08:26 +01:00
feat(sync): auto-refresh on Jellyfin LibraryChanged events
Handle the server's LibraryChanged WebSocket message to invalidate library-dependent React Query caches when items are added/updated/ removed, so newly added episodes/movies appear without a manual refresh. Debounced to coalesce a scan's burst of events. Add useRefreshLibraryOnFocus as a fallback that re-checks on screen focus (throttled, online-only, skips first focus), wired into home (mobile + TV) and the library pages.
This commit is contained in:
50
hooks/useRefreshLibraryOnFocus.ts
Normal file
50
hooks/useRefreshLibraryOnFocus.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { useFocusEffect } from "expo-router";
|
||||
import { useCallback, useRef } from "react";
|
||||
import { useNetworkAwareQueryClient } from "@/hooks/useNetworkAwareQueryClient";
|
||||
|
||||
// Query keys that depend on the set of library items. Kept in sync with the
|
||||
// LibraryChanged handler in WebSocketProvider.
|
||||
const LIBRARY_QUERY_KEYS = [
|
||||
["home"],
|
||||
["library-items"],
|
||||
["nextUp-all"],
|
||||
["nextUp"],
|
||||
["resumeItems"],
|
||||
];
|
||||
|
||||
/**
|
||||
* Fallback refresh for newly added/removed content.
|
||||
*
|
||||
* The primary path is the server's `LibraryChanged` WebSocket event (handled in
|
||||
* WebSocketProvider). This hook is a safety net for cases where the socket was
|
||||
* down or the change happened while the screen was unfocused: when the screen
|
||||
* regains focus, it invalidates the library-dependent queries so React Query
|
||||
* refetches the latest content.
|
||||
*
|
||||
* Skips the refresh on the very first focus (initial mount already fetches) and
|
||||
* throttles to avoid refetch storms when quickly switching tabs.
|
||||
*/
|
||||
export function useRefreshLibraryOnFocus(throttleMs = 30_000) {
|
||||
const queryClient = useNetworkAwareQueryClient();
|
||||
const hasFocusedOnce = useRef(false);
|
||||
const lastRefreshRef = useRef(0);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
if (!hasFocusedOnce.current) {
|
||||
hasFocusedOnce.current = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
if (now - lastRefreshRef.current < throttleMs) {
|
||||
return;
|
||||
}
|
||||
lastRefreshRef.current = now;
|
||||
|
||||
for (const queryKey of LIBRARY_QUERY_KEYS) {
|
||||
queryClient.invalidateQueries({ queryKey });
|
||||
}
|
||||
}, [queryClient, throttleMs]),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user