From 0c042ac89fc0822fcbe09c48702857faa5494ae1 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 7 Dec 2025 23:34:03 +0900 Subject: feat(client): add sync status indicator component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add SyncStatusIndicator component to display current sync state in the UI header. The component shows online/offline status, syncing progress, pending changes count, and sync errors. - Create SyncProvider context to wrap SyncManager for React components - Add SyncStatusIndicator component with visual status indicators - Integrate indicator into HomePage header - Add comprehensive tests for SyncStatusIndicator and SyncProvider - Update existing tests to include SyncProvider wrapper 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/client/sync/conflict.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src/client/sync/conflict.ts') diff --git a/src/client/sync/conflict.ts b/src/client/sync/conflict.ts index 365ef3c..4e0e3ef 100644 --- a/src/client/sync/conflict.ts +++ b/src/client/sync/conflict.ts @@ -1,8 +1,5 @@ import type { LocalCard, LocalDeck } from "../db/index"; -import { - localCardRepository, - localDeckRepository, -} from "../db/repositories"; +import { localCardRepository, localDeckRepository } from "../db/repositories"; import type { ServerCard, ServerDeck, SyncPullResult } from "./pull"; import type { SyncPushResult } from "./push"; @@ -39,10 +36,7 @@ export interface ConflictResolverOptions { * Compare timestamps for LWW resolution * Returns true if server data is newer or equal */ -function isServerNewer( - serverUpdatedAt: Date, - localUpdatedAt: Date, -): boolean { +function isServerNewer(serverUpdatedAt: Date, localUpdatedAt: Date): boolean { return serverUpdatedAt.getTime() >= localUpdatedAt.getTime(); } @@ -222,7 +216,10 @@ export class ConflictResolver { const serverDeck = pullResult.decks.find((d) => d.id === deckId); if (localDeck && serverDeck) { - const resolution = await this.resolveDeckConflict(localDeck, serverDeck); + const resolution = await this.resolveDeckConflict( + localDeck, + serverDeck, + ); result.decks.push(resolution); } else if (serverDeck) { // Local doesn't exist, apply server data @@ -239,7 +236,10 @@ export class ConflictResolver { const serverCard = pullResult.cards.find((c) => c.id === cardId); if (localCard && serverCard) { - const resolution = await this.resolveCardConflict(localCard, serverCard); + const resolution = await this.resolveCardConflict( + localCard, + serverCard, + ); result.cards.push(resolution); } else if (serverCard) { // Local doesn't exist, apply server data @@ -266,4 +266,6 @@ export function createConflictResolver( /** * Default conflict resolver using LWW (server wins) strategy */ -export const conflictResolver = new ConflictResolver({ strategy: "server_wins" }); +export const conflictResolver = new ConflictResolver({ + strategy: "server_wins", +}); -- cgit v1.2.3-70-g09d2