feat: add pull sync on login with conflict resolution
- 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 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { VersDetailsPanel } from './verse-details-panel'
|
|||||||
import { ReadingSettings } from './reading-settings'
|
import { ReadingSettings } from './reading-settings'
|
||||||
import { HighlightSyncManager } from '@/lib/highlight-sync-manager'
|
import { HighlightSyncManager } from '@/lib/highlight-sync-manager'
|
||||||
import { addHighlight, updateHighlight, getHighlightsByVerse, deleteHighlight, getAllHighlights } from '@/lib/highlight-manager'
|
import { addHighlight, updateHighlight, getHighlightsByVerse, deleteHighlight, getAllHighlights } from '@/lib/highlight-manager'
|
||||||
|
import { pullAndMergeHighlights } from '@/lib/highlight-pull-sync'
|
||||||
|
|
||||||
interface BookInfo {
|
interface BookInfo {
|
||||||
id: string // UUID
|
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
|
// Load all highlights on mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadAllHighlights()
|
loadAllHighlights()
|
||||||
|
|||||||
42
lib/highlight-pull-sync.ts
Normal file
42
lib/highlight-pull-sync.ts
Normal file
@@ -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<BibleHighlight[]> {
|
||||||
|
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 []
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user