import type { ReactNode } from 'react' import { Clock3Icon, CloudIcon, HelpCircleIcon, LoaderCircleIcon } from 'lucide-react' import { useTranslation } from 'react-i18next' import { IPicGoCloudConfigSyncSessionStatus, IPicGoCloudEncryptionMethod } from '#/types/cloudConfigSync' import { Button } from '@/components/ui/button' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { Separator } from '@/components/ui/separator' import { Skeleton } from '@/components/ui/skeleton' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' import { useCloudConfigSyncStateQuery } from '@/queries/picgo-cloud-config-sync' import { usePicGoCloudUsageQuery } from '@/queries/picgo-cloud-usage' import { useCloudStore } from '@/store/cloud' import { CloudCardShell } from './cloud-card-shell' import { formatCloudSyncTime } from './utils' function ConfigDetailRow ({ label, labelHelp, labelHelpContent, value }: { label: string labelHelp?: string labelHelpContent?: ReactNode value: ReactNode }) { return (
{label} {labelHelp ? ( {labelHelpContent ?? labelHelp} ) : null}
{value}
) } interface CloudConfigSyncCardProps { onStartSync: () => Promise onEncryptionChange: (value: unknown) => Promise onOpenEncryptionDocs: () => void } export function CloudConfigSyncCard ({ onStartSync, onEncryptionChange, onOpenEncryptionDocs }: CloudConfigSyncCardProps) { const { t } = useTranslation() const isEncryptionMethodUpdating = useCloudStore.use.isEncryptionMethodUpdating() const { data: syncState, isLoading: isSyncStateLoading, isError: isSyncStateError, isFetching: isSyncStateFetching, refetch: refetchSyncState } = useCloudConfigSyncStateQuery() const { data: usageData, isLoading: isUsageLoading, isError: isUsageError, isFetching: isUsageFetching, refetch: refetchUsage } = usePicGoCloudUsageQuery() const sessionStatus = syncState?.sessionStatus ?? IPicGoCloudConfigSyncSessionStatus.IDLE const isConfigSyncRunning = sessionStatus === IPicGoCloudConfigSyncSessionStatus.SYNCING const isConfigSyncBusy = sessionStatus !== IPicGoCloudConfigSyncSessionStatus.IDLE const isEncryptionDisabled = isConfigSyncBusy || isSyncStateLoading || isEncryptionMethodUpdating return (

{t('PICGO_CLOUD_CONFIG_SYNC_TITLE')}

{t('PICGO_CLOUD_CONFIG_SYNC_CARD_DESC')}

{isSyncStateError ? (

{t('PICGO_CLOUD_CONFIG_SYNC_LOAD_FAILED')}

) : (

{t('PICGO_CLOUD_ENCRYPTION_MODE_TIP_AUTO')}

{t('PICGO_CLOUD_ENCRYPTION_MODE_TIP_SERVER')}

{t('PICGO_CLOUD_ENCRYPTION_MODE_TIP_E2E')}

} value={ isSyncStateLoading ? : (
) } /> : (
{formatCloudSyncTime( syncState?.lastSyncedAt, t('PICGO_CLOUD_LAST_SYNC_TIME_NONE') )}
) } /> { refetchUsage().catch(() => {}) }} /> } />
)}
) } function SyncQuotaValue ({ isLoading, isError, isFetching, used, limit, onRetry }: { isLoading: boolean isError: boolean isFetching: boolean used: number | undefined limit: number | undefined onRetry: () => void }) { const { t } = useTranslation() if (isLoading) { return } if (isError || used === undefined || limit === undefined) { return (
{t('PICGO_CLOUD_USAGE_LOAD_FAILED')}
) } return (
{t('PICGO_CLOUD_USAGE_PROGRESS', { used: used.toLocaleString(), total: limit.toLocaleString() })}
) }