import { useState } from 'react' import { useTranslation } from 'react-i18next' import { ArrowLeftIcon, ArrowRightIcon, CheckIcon, CloudIcon, LaptopIcon, RefreshCcwIcon, TriangleAlertIcon } from 'lucide-react' import { IPicGoCloudConfigSyncConflictChoice, type IPicGoCloudConfigSyncResolution } from '#/types/cloudConfigSync' import { Button } from '@/components/ui/button' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { ScrollArea } from '@/components/ui/scroll-area' import { cn } from '@/lib/utils' import { useCloudConfigSyncStateQuery } from '@/queries/picgo-cloud-config-sync' import { cloudStoreActions, useCloudStore } from '@/store/cloud' function stringifyValue (value: unknown) { if (value === undefined) return 'undefined' if (typeof value === 'string') return value try { return JSON.stringify(value, null, 2) } catch { return String(value) } } export function CloudConflictDialog ({ onAbort, onConfirm }: { onAbort: (resolution?: IPicGoCloudConfigSyncResolution) => Promise | void onConfirm: (resolution: IPicGoCloudConfigSyncResolution) => Promise | void }) { const { t } = useTranslation() const open = useCloudStore.use.isConflictDialogOpen() const { data: syncState } = useCloudConfigSyncStateQuery() const conflicts = syncState?.conflicts ?? [] const confirmLoading = useCloudStore.use.isApplyResolutionLoading() const [selections, setSelections] = useState({}) const remainingCount = conflicts.filter((item) => !selections[item.path]).length const isConfirmDisabled = remainingCount > 0 || conflicts.length === 0 const resetSelections = () => { setSelections({}) } const setChoice = ( path: string, choice: IPicGoCloudConfigSyncConflictChoice ) => { setSelections((current) => ({ ...current, [path]: choice })) } const chooseAll = (choice: IPicGoCloudConfigSyncConflictChoice) => { setSelections( conflicts.reduce((result, item) => { result[item.path] = choice return result }, {}) ) } const handleOpenChange = (nextOpen: boolean) => { if (confirmLoading) return if (!nextOpen) return cloudStoreActions.setIsConflictDialogOpen(nextOpen) } return (
{t('PICGO_CLOUD_CONFIG_SYNC_CONFLICT_TITLE', { count: conflicts.length })} {t('PICGO_CLOUD_CONFIG_SYNC_CONFLICT_DETECTED')}
{conflicts.map((item) => { const currentChoice = selections[item.path] return (
{item.path} {currentChoice ? (
{currentChoice === IPicGoCloudConfigSyncConflictChoice.LOCAL ? t('PICGO_CLOUD_CONFIG_SYNC_LOCAL_VERSION') : t('PICGO_CLOUD_CONFIG_SYNC_CLOUD_VERSION')}
) : null}
{currentChoice === IPicGoCloudConfigSyncConflictChoice.LOCAL ? ( ) : currentChoice === IPicGoCloudConfigSyncConflictChoice.CLOUD ? ( ) : (
)}
) })}
{remainingCount > 0 ? t('PICGO_CLOUD_CONFIG_SYNC_CONFLICT_PENDING') : t('PICGO_CLOUD_CONFIG_SYNC_CONFLICT_RESOLVED')}
) }