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()
})}
)
}