2026-04-19 16:18:35 +02:00
|
|
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
|
|
|
import { invoke } from '@tauri-apps/api/core'
|
|
|
|
|
import { isTauri, mockInvoke } from '../mock-tauri'
|
|
|
|
|
import type { GitRemoteStatus } from '../types'
|
|
|
|
|
import { REQUEST_ADD_REMOTE_EVENT } from '../utils/addRemoteEvents'
|
|
|
|
|
|
|
|
|
|
function tauriCall<T>(command: string, args: Record<string, unknown>): Promise<T> {
|
|
|
|
|
return isTauri() ? invoke<T>(command, args) : mockInvoke<T>(command, args)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function readRemoteStatus(vaultPath: string): Promise<GitRemoteStatus | null> {
|
|
|
|
|
try {
|
|
|
|
|
return await tauriCall<GitRemoteStatus>('git_remote_status', { vaultPath })
|
2026-05-07 19:52:14 +02:00
|
|
|
} catch (error) {
|
|
|
|
|
void error
|
2026-04-19 16:18:35 +02:00
|
|
|
return null
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface UseStatusBarAddRemoteOptions {
|
|
|
|
|
vaultPath: string
|
|
|
|
|
isGitVault: boolean
|
|
|
|
|
remoteStatus?: GitRemoteStatus | null
|
|
|
|
|
onAddRemote?: () => void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface StatusBarAddRemoteState {
|
|
|
|
|
openAddRemote: () => Promise<void>
|
|
|
|
|
closeAddRemote: () => void
|
|
|
|
|
showAddRemote: boolean
|
|
|
|
|
visibleRemoteStatus: GitRemoteStatus | null
|
|
|
|
|
handleRemoteConnected: (message: string) => Promise<void>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface RemoteStatusOverride {
|
|
|
|
|
vaultPath: string
|
|
|
|
|
status: GitRemoteStatus | null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function useStatusBarAddRemote({
|
|
|
|
|
vaultPath,
|
|
|
|
|
isGitVault,
|
|
|
|
|
remoteStatus,
|
|
|
|
|
onAddRemote,
|
|
|
|
|
}: UseStatusBarAddRemoteOptions): StatusBarAddRemoteState {
|
|
|
|
|
const [showAddRemote, setShowAddRemote] = useState(false)
|
|
|
|
|
const [remoteStatusOverride, setRemoteStatusOverride] = useState<RemoteStatusOverride | null>(null)
|
|
|
|
|
|
|
|
|
|
const refreshRemoteStatus = useCallback(async () => {
|
|
|
|
|
const latestStatus = await readRemoteStatus(vaultPath)
|
|
|
|
|
if (latestStatus) {
|
|
|
|
|
setRemoteStatusOverride({ vaultPath, status: latestStatus })
|
|
|
|
|
}
|
|
|
|
|
return latestStatus
|
|
|
|
|
}, [vaultPath])
|
|
|
|
|
|
|
|
|
|
const openAddRemote = useCallback(async () => {
|
|
|
|
|
if (onAddRemote) {
|
|
|
|
|
onAddRemote()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isGitVault) return
|
|
|
|
|
|
|
|
|
|
const latestStatus = await refreshRemoteStatus()
|
|
|
|
|
if (latestStatus?.hasRemote) {
|
|
|
|
|
setShowAddRemote(false)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setShowAddRemote(true)
|
|
|
|
|
}, [isGitVault, onAddRemote, refreshRemoteStatus])
|
|
|
|
|
|
|
|
|
|
const closeAddRemote = useCallback(() => {
|
|
|
|
|
setShowAddRemote(false)
|
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
|
|
const handleRemoteConnected = useCallback(async (message: string) => {
|
|
|
|
|
void message
|
|
|
|
|
await refreshRemoteStatus()
|
|
|
|
|
}, [refreshRemoteStatus])
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const handleRequest = () => {
|
|
|
|
|
void openAddRemote()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window.addEventListener(REQUEST_ADD_REMOTE_EVENT, handleRequest)
|
|
|
|
|
return () => window.removeEventListener(REQUEST_ADD_REMOTE_EVENT, handleRequest)
|
|
|
|
|
}, [openAddRemote])
|
|
|
|
|
|
|
|
|
|
const visibleRemoteStatus = useMemo(
|
|
|
|
|
() => (
|
|
|
|
|
remoteStatusOverride?.vaultPath === vaultPath
|
|
|
|
|
? remoteStatusOverride.status
|
|
|
|
|
: remoteStatus ?? null
|
|
|
|
|
),
|
|
|
|
|
[remoteStatus, remoteStatusOverride, vaultPath],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
openAddRemote,
|
|
|
|
|
closeAddRemote,
|
|
|
|
|
showAddRemote,
|
|
|
|
|
visibleRemoteStatus,
|
|
|
|
|
handleRemoteConnected,
|
|
|
|
|
}
|
|
|
|
|
}
|