import { Drawer, DrawerBody, DrawerFooter, DrawerHeader, cn } from '@heroui/react' import { Autocomplete, AutocompleteItem, Button, DrawerContent, Input } from '@heroui/react' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { message } from '@tauri-apps/plugin-dialog' import { platform } from '@tauri-apps/plugin-os' import { ChevronDown, ChevronUp, RefreshCcwIcon } from 'lucide-react' import { type Key, startTransition, useCallback, useMemo, useState } from 'react' import rclone from '../../lib/rclone/client' import { OVERRIDES } from '../../lib/rclone/overrides' import type { BackendOption } from '../../types/rclone' import RemoteField from './RemoteField' export default function RemoteCreateDrawer({ isOpen, onClose, }: { isOpen: boolean; onClose: () => void }) { const queryClient = useQueryClient() const [config, setConfig] = useState>({}) const [showMoreOptions, setShowMoreOptions] = useState(false) const backendsQuery = useQuery({ queryKey: ['backends'], queryFn: async () => { const backends = await rclone('/config/providers') return backends.providers }, }) const sortedEnrichedBackends = useMemo(() => { const backends = backendsQuery.data ?? [] return backends .filter((b) => !['uptobox', 'tardigrade'].includes(b.Name)) .map((backend) => { const override = OVERRIDES[backend.Name as keyof typeof OVERRIDES] return { ...backend, Description: override?.Description || backend.Description, } }) .sort((a, b) => { return a.Name.localeCompare(b.Name) }) }, [backendsQuery.data]) const currentBackend = useMemo( () => (config.type ? sortedEnrichedBackends.find((b) => b.Name === config.type) : null), [config.type, sortedEnrichedBackends] ) const currentBackendFields = useMemo( () => currentBackend ? (currentBackend.Options as BackendOption[]).filter((opt) => { if (!opt.Provider) return true if (opt.Provider.includes(config.provider) && !opt.Provider.startsWith('!')) return true if ( config.type === 's3' && config.provider === 'Other' && opt.Provider.includes('!') ) return true return false }) || [] : [], [currentBackend, config.provider, config.type] ) const createRemoteMutation = useMutation({ mutationFn: async ({ name, type, parameters, }: { name: string; type: string; parameters: Record }) => { console.log('[RemoteCreateDrawer] newRemoteConfig', name, type, parameters) await rclone('/config/create', { params: { query: { name, type, parameters: JSON.stringify(parameters), }, }, }) return name }, onSuccess: async (name) => { queryClient.setQueryData(['remotes', 'list', 'all'], (old: string[] | undefined) => [ ...(old ?? []), name, ]) onClose() setConfig({}) setShowMoreOptions(false) }, onError: async (error) => { console.error('Failed to create remote:', error) const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred' if (errorMessage.includes('address already in use')) { await message( 'Rclone Oauth Client is stuck, please restart the UI to add new remotes', { title: 'Busy', kind: 'error', } ) return } await message(errorMessage, { title: 'Could not create remote', kind: 'error', }) }, }) const handleTypeChange = useCallback((key: Key | null) => { const newType = key ? String(key) : undefined // preserve name when resetting type setConfig((prev) => ({ name: prev.name, type: newType })) }, []) return ( { startTransition(() => { setConfig({}) setShowMoreOptions(false) createRemoteMutation.reset() }) onClose() }} hideCloseButton={true} > {(close) => ( <> Create Remote
setConfig({ ...config, name: value })} isRequired={true} autoComplete="off" autoCapitalize="off" autoCorrect="off" spellCheck="false" /> {sortedEnrichedBackends.map((backend) => ( } > {backend.Description || backend.Name} ))} {/* Normal Fields */} {currentBackendFields .filter((opt) => !opt.Advanced) .map((opt) => ( ))} {/* Advanced Fields */} {currentBackendFields.some((opt) => opt.Advanced) && (
{showMoreOptions && (
{currentBackendFields .filter((opt) => opt.Advanced) .map((opt) => ( ))}
)}
)}
)}
) }