diff --git a/src/stores/bookmarks/BookmarkSyncer.tsx b/src/stores/bookmarks/BookmarkSyncer.tsx index cbbb1b87..de596072 100644 --- a/src/stores/bookmarks/BookmarkSyncer.tsx +++ b/src/stores/bookmarks/BookmarkSyncer.tsx @@ -59,6 +59,7 @@ export function BookmarkSyncer() { clearUpdateQueue(); }, [clearUpdateQueue]); + // Regular interval sync useEffect(() => { const interval = setInterval(() => { (async () => { @@ -79,5 +80,58 @@ export function BookmarkSyncer() { }; }, [removeUpdateItem, url]); + // Immediate sync when items are added or removed + useEffect(() => { + let syncTimeout: NodeJS.Timeout | null = null; + + const syncImmediately = async () => { + if (!url) return; + const state = useBookmarkStore.getState(); + const user = useAuthStore.getState(); + // Only sync if there are items in the queue + if (state.updateQueue.length > 0) { + await syncBookmarks( + state.updateQueue, + removeUpdateItem, + url, + user.account, + ); + } + }; + + const debouncedSync = () => { + if (syncTimeout) { + clearTimeout(syncTimeout); + } + syncTimeout = setTimeout(syncImmediately, 100); + }; + + // Override the addBookmark function to trigger immediate sync + const originalAddBookmark = useBookmarkStore.getState().addBookmark; + useBookmarkStore.setState({ + addBookmark: (...args) => { + originalAddBookmark(...args); + // Trigger debounced sync after adding bookmark + debouncedSync(); + }, + }); + + // Override removeBookmark to trigger immediate sync + const originalRemoveBookmark = useBookmarkStore.getState().removeBookmark; + useBookmarkStore.setState({ + removeBookmark: (...args) => { + originalRemoveBookmark(...args); + // Trigger debounced sync after removing bookmark + debouncedSync(); + }, + }); + + return () => { + if (syncTimeout) { + clearTimeout(syncTimeout); + } + }; + }, [removeUpdateItem, url]); + return null; } diff --git a/src/stores/progress/ProgressSyncer.tsx b/src/stores/progress/ProgressSyncer.tsx index 5c71409f..eda35c19 100644 --- a/src/stores/progress/ProgressSyncer.tsx +++ b/src/stores/progress/ProgressSyncer.tsx @@ -59,6 +59,7 @@ export function ProgressSyncer() { clearUpdateQueue(); }, [clearUpdateQueue]); + // Regular interval sync useEffect(() => { const interval = setInterval(() => { (async () => { @@ -79,5 +80,58 @@ export function ProgressSyncer() { }; }, [removeUpdateItem, url]); + // Immediate sync when items are added or removed + useEffect(() => { + let syncTimeout: NodeJS.Timeout | null = null; + + const syncImmediately = async () => { + if (!url) return; + const state = useProgressStore.getState(); + const user = useAuthStore.getState(); + // Only sync if there are items in the queue + if (state.updateQueue.length > 0) { + await syncProgress( + state.updateQueue, + removeUpdateItem, + url, + user.account, + ); + } + }; + + const debouncedSync = () => { + if (syncTimeout) { + clearTimeout(syncTimeout); + } + syncTimeout = setTimeout(syncImmediately, 100); + }; + + // Override the updateItem function to trigger immediate sync + const originalUpdateItem = useProgressStore.getState().updateItem; + useProgressStore.setState({ + updateItem: (...args) => { + originalUpdateItem(...args); + // Trigger debounced sync after updating item + debouncedSync(); + }, + }); + + // Override removeItem to trigger immediate sync + const originalRemoveItem = useProgressStore.getState().removeItem; + useProgressStore.setState({ + removeItem: (...args) => { + originalRemoveItem(...args); + // Trigger debounced sync after removing item + debouncedSync(); + }, + }); + + return () => { + if (syncTimeout) { + clearTimeout(syncTimeout); + } + }; + }, [removeUpdateItem, url]); + return null; } diff --git a/src/stores/watchHistory/WatchHistorySyncer.tsx b/src/stores/watchHistory/WatchHistorySyncer.tsx index 12c4926b..926b633c 100644 --- a/src/stores/watchHistory/WatchHistorySyncer.tsx +++ b/src/stores/watchHistory/WatchHistorySyncer.tsx @@ -66,18 +66,16 @@ export function WatchHistorySyncer() { clearUpdateQueue(); }, [clearUpdateQueue]); - // Immediate sync when items are added to queue + // Immediate sync when items are added or removed useEffect(() => { - let lastQueueLength = 0; + let syncTimeout: NodeJS.Timeout | null = null; - const checkAndSync = async () => { - const currentQueueLength = - useWatchHistoryStore.getState().updateQueue.length; - // Only sync immediately if queue grew (items were added) - if (currentQueueLength > lastQueueLength && currentQueueLength > 0) { - if (!url) return; - const state = useWatchHistoryStore.getState(); - const user = useAuthStore.getState(); + const syncImmediately = async () => { + if (!url) return; + const state = useWatchHistoryStore.getState(); + const user = useAuthStore.getState(); + // Only sync if there are items in the queue + if (state.updateQueue.length > 0) { await syncWatchHistory( state.updateQueue, removeUpdateItem, @@ -85,7 +83,13 @@ export function WatchHistorySyncer() { user.account, ); } - lastQueueLength = currentQueueLength; + }; + + const debouncedSync = () => { + if (syncTimeout) { + clearTimeout(syncTimeout); + } + syncTimeout = setTimeout(syncImmediately, 100); }; // Override the addItem function to trigger immediate sync @@ -93,20 +97,26 @@ export function WatchHistorySyncer() { useWatchHistoryStore.setState({ addItem: (...args) => { originalAddItem(...args); - // Trigger sync after adding item - setTimeout(checkAndSync, 100); + // Trigger debounced sync after adding item + debouncedSync(); }, }); - // Also override removeItem + // Override removeItem to trigger immediate sync const originalRemoveItem = useWatchHistoryStore.getState().removeItem; useWatchHistoryStore.setState({ removeItem: (...args) => { originalRemoveItem(...args); - // Trigger sync after removing item - setTimeout(checkAndSync, 100); + // Trigger debounced sync after removing item + debouncedSync(); }, }); + + return () => { + if (syncTimeout) { + clearTimeout(syncTimeout); + } + }; }, [removeUpdateItem, url]); // Regular interval sync