import { useCallback, useRef, useState, type ChangeEvent, type FormEvent } from 'react' import { invoke } from '@tauri-apps/api/core' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import type { GitAddRemoteResult } from '../types' import { isTauri, mockInvoke } from '../mock-tauri' type ConnectState = 'idle' | 'connecting' interface AddRemoteModalProps { open: boolean vaultPath: string onClose: () => void onRemoteConnected: (message: string) => void | Promise } function tauriCall(command: string, args: Record): Promise { return isTauri() ? invoke(command, args) : mockInvoke(command, args) } function shouldCloseAfterResult(result: GitAddRemoteResult): boolean { return result.status === 'connected' || result.status === 'already_configured' } async function submitRemoteConnection( vaultPath: string, remoteUrl: string, ): Promise { return tauriCall('git_add_remote', { request: { vaultPath, remoteUrl, }, }) } async function getConnectErrorMessage({ vaultPath, remoteUrl, onRemoteConnected, onClose, }: { vaultPath: string remoteUrl: string onRemoteConnected: (message: string) => void | Promise onClose: () => void }): Promise { try { const result = await submitRemoteConnection(vaultPath, remoteUrl) if (shouldCloseAfterResult(result)) { await onRemoteConnected(result.message) onClose() return null } return result.message } catch (error) { return `Could not connect that remote: ${String(error)}` } } export function AddRemoteModal({ open, vaultPath, onClose, onRemoteConnected, }: AddRemoteModalProps) { const [remoteUrl, setRemoteUrl] = useState('') const [connectState, setConnectState] = useState('idle') const [connectError, setConnectError] = useState(null) const inputRef = useRef(null) const resetState = useCallback(() => { setRemoteUrl('') setConnectState('idle') setConnectError(null) }, []) const handleClose = useCallback(() => { resetState() onClose() }, [onClose, resetState]) const handleOpenChange = useCallback((isOpen: boolean) => { if (!isOpen) { handleClose() } }, [handleClose]) const handleRemoteUrlChange = useCallback((event: ChangeEvent) => { setRemoteUrl(event.target.value) setConnectError(null) }, []) const handleSubmit = useCallback(async (event: FormEvent) => { event.preventDefault() const trimmedUrl = remoteUrl.trim() if (!trimmedUrl) return setConnectState('connecting') setConnectError(null) const errorMessage = await getConnectErrorMessage({ vaultPath, remoteUrl: trimmedUrl, onRemoteConnected, onClose: handleClose, }) if (errorMessage) { setConnectError(errorMessage) } setConnectState('idle') }, [handleClose, onRemoteConnected, remoteUrl, vaultPath]) const connectDisabled = connectState === 'connecting' || !remoteUrl.trim() return ( Add Remote Connect this local vault to a git remote. Your existing local commits stay intact; Tolaria will only connect the vault when the remote history is safe to use.

Use an empty repository or one created from this vault. SSH keys, Git Credential Manager, and other system git auth methods all work.

{connectError && (

{connectError}

)}
) }