From 3e3e90f7748f02edfaff56280cb8ad3b3b6c13ed Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 12 Nov 2025 07:51:35 +0000 Subject: [PATCH] feat: add pull sync on login with conflict resolution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Created highlight-pull-sync.ts with pullAndMergeHighlights function - Integrated pull sync into BibleReaderApp on mount - Fetches server highlights, merges with local using conflict resolution - Updates local storage and component state with merged data 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- components/bible/bible-reader-app.tsx | 16 ++++++++++ lib/highlight-pull-sync.ts | 42 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 lib/highlight-pull-sync.ts diff --git a/components/bible/bible-reader-app.tsx b/components/bible/bible-reader-app.tsx index 355d0fe..396cd5b 100644 --- a/components/bible/bible-reader-app.tsx +++ b/components/bible/bible-reader-app.tsx @@ -10,6 +10,7 @@ import { VersDetailsPanel } from './verse-details-panel' import { ReadingSettings } from './reading-settings' import { HighlightSyncManager } from '@/lib/highlight-sync-manager' import { addHighlight, updateHighlight, getHighlightsByVerse, deleteHighlight, getAllHighlights } from '@/lib/highlight-manager' +import { pullAndMergeHighlights } from '@/lib/highlight-pull-sync' interface BookInfo { id: string // UUID @@ -61,6 +62,21 @@ export function BibleReaderApp() { } }, []) + // Pull highlights from server when component mounts (user logged in) + useEffect(() => { + const pullHighlights = async () => { + try { + const merged = await pullAndMergeHighlights() + const map = new Map(merged.map(h => [h.verseId, h])) + setHighlights(map) + } catch (error) { + console.error('Failed to pull highlights:', error) + } + } + + pullHighlights() + }, []) + // Load all highlights on mount useEffect(() => { loadAllHighlights() diff --git a/lib/highlight-pull-sync.ts b/lib/highlight-pull-sync.ts new file mode 100644 index 0000000..2a0e3a4 --- /dev/null +++ b/lib/highlight-pull-sync.ts @@ -0,0 +1,42 @@ +import { BibleHighlight } from '@/types' +import { getAllHighlights, addHighlight, updateHighlight } from './highlight-manager' +import { mergeHighlights } from './sync-conflict-resolver' + +export async function pullAndMergeHighlights(): Promise { + try { + // Fetch all highlights from server + const response = await fetch('/api/highlights/all') + + if (!response.ok) { + console.error('Failed to pull highlights:', response.status) + return [] + } + + const { highlights: serverHighlights } = await response.json() + + // Get local highlights + const clientHighlights = await getAllHighlights() + + // Merge with conflict resolution + const merged = mergeHighlights(clientHighlights, serverHighlights) + + // Update local storage with merged version + for (const highlight of merged) { + const existing = clientHighlights.find(h => h.id === highlight.id) + if (existing) { + // Update if different + if (JSON.stringify(existing) !== JSON.stringify(highlight)) { + await updateHighlight(highlight) + } + } else { + // Add new highlights from server + await addHighlight(highlight) + } + } + + return merged + } catch (error) { + console.error('Error pulling highlights:', error) + return [] + } +}