import { useState, useCallback } from "react"; import { syncFileFromRepo } from "../../lib/api"; interface RepoSyncIndicatorProps { fileId: string; repoFilePath: string | null | undefined; repoSyncStatus: string | null | undefined; repoSyncedAt: string | null | undefined; onSyncComplete?: () => void; /** Callback to push file content to repo (creates a task) */ onPushToRepo?: () => void; /** Whether a push operation is in progress */ isPushing?: boolean; } /** * Shows repository file link status and provides sync functionality. * Displays the linked file path and allows updating from the repo via daemon, * or pushing local changes back to the repo. */ export function RepoSyncIndicator({ fileId, repoFilePath, repoSyncStatus, repoSyncedAt, onSyncComplete, onPushToRepo, isPushing = false, }: RepoSyncIndicatorProps) { const [isSyncing, setIsSyncing] = useState(false); const [error, setError] = useState(null); const handleSync = useCallback(async () => { setIsSyncing(true); setError(null); try { await syncFileFromRepo(fileId); // The actual update happens via WebSocket notification // Give a brief delay then notify parent setTimeout(() => { onSyncComplete?.(); }, 500); } catch (err) { setError(err instanceof Error ? err.message : "Sync failed"); } finally { setIsSyncing(false); } }, [fileId, onSyncComplete]); // Don't render if no repo file path is set if (!repoFilePath) { return null; } const isActuallySyncing = isSyncing || repoSyncStatus === "syncing"; const isSynced = repoSyncStatus === "synced"; const isModified = repoSyncStatus === "modified"; // Format the synced timestamp const syncedAtFormatted = repoSyncedAt ? new Date(repoSyncedAt).toLocaleString() : null; return (
{/* File path icon and link */}
{repoFilePath}
{/* Status indicator */} {isSynced && ( )} {isModified && ( )} {/* Pull from repo button */} {/* Push to repo button */} {onPushToRepo && ( )} {/* Error message */} {error && ( Failed )}
); }