import { open } from '@tauri-apps/plugin-dialog'; import { revealItemInDir } from '@tauri-apps/plugin-opener'; import { getModel, settingsAtom, workspacesAtom } from '@yaakapp-internal/models'; import classNames from 'classnames'; import { useAtomValue } from 'jotai'; import { memo, useCallback, useMemo } from 'react'; import { openWorkspaceFromSyncDir } from '../commands/openWorkspaceFromSyncDir'; import { openWorkspaceSettings } from '../commands/openWorkspaceSettings'; import { switchWorkspace } from '../commands/switchWorkspace'; import { activeWorkspaceAtom, activeWorkspaceIdAtom, activeWorkspaceMetaAtom, } from '../hooks/useActiveWorkspace'; import { useCreateWorkspace } from '../hooks/useCreateWorkspace'; import { useDeleteSendHistory } from '../hooks/useDeleteSendHistory'; import { useWorkspaceActions } from '../hooks/useWorkspaceActions'; import { showDialog } from '../lib/dialog'; import { jotaiStore } from '../lib/jotai'; import { revealInFinderText } from '../lib/reveal'; import { CloneGitRepositoryDialog } from './CloneGitRepositoryDialog'; import type { ButtonProps } from './core/Button'; import { Button } from './core/Button'; import type { DropdownItem } from './core/Dropdown'; import { Icon } from './core/Icon'; import type { RadioDropdownItem } from './core/RadioDropdown'; import { RadioDropdown } from './core/RadioDropdown'; import { SwitchWorkspaceDialog } from './SwitchWorkspaceDialog'; type Props = Pick; export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({ className, ...buttonProps }: Props) { const workspaces = useAtomValue(workspacesAtom); const workspace = useAtomValue(activeWorkspaceAtom); const createWorkspace = useCreateWorkspace(); const workspaceMeta = useAtomValue(activeWorkspaceMetaAtom); const { mutate: deleteSendHistory } = useDeleteSendHistory(); const workspaceActions = useWorkspaceActions(); const openCloneGitRepositoryDialog = useCallback(() => { showDialog({ id: 'clone-git-repository', size: 'md', title: 'Clone Git Repository', render: ({ hide }) => , }); }, []); const { workspaceItems, itemsAfter, itemsBefore } = useMemo<{ workspaceItems: RadioDropdownItem[]; itemsAfter: DropdownItem[]; itemsBefore: DropdownItem[]; }>(() => { const workspaceItems: RadioDropdownItem[] = workspaces.map((w) => ({ key: w.id, label: w.name, value: w.id, leftSlot: w.id === workspace?.id ? : , })); const itemsBefore: DropdownItem[] = [ { label: 'New Workspace', leftSlot: , submenu: [ { label: 'Create Empty', leftSlot: , onSelect: createWorkspace, }, { label: 'Open Folder', leftSlot: , onSelect: async () => { const dir = await open({ title: 'Select Workspace Directory', directory: true, multiple: false, }); if (dir == null) return; openWorkspaceFromSyncDir.mutate(dir); }, }, { label: 'Clone Git Repository', leftSlot: , onSelect: openCloneGitRepositoryDialog, }, ], }, ]; const itemsAfter: DropdownItem[] = [ ...workspaceActions.map((a) => ({ label: a.label, leftSlot: , onSelect: async () => { if (workspace != null) await a.call(workspace); }, })), ...(workspaceActions.length > 0 ? [{ type: 'separator' as const }] : []), { label: 'Workspace Settings', leftSlot: , hotKeyAction: 'workspace_settings.show', onSelect: openWorkspaceSettings, }, { label: revealInFinderText, hidden: workspaceMeta == null || workspaceMeta.settingSyncDir == null, leftSlot: , onSelect: async () => { if (workspaceMeta?.settingSyncDir == null) return; await revealItemInDir(workspaceMeta.settingSyncDir); }, }, { label: 'Clear Send History', color: 'warning', leftSlot: , onSelect: deleteSendHistory, }, ]; return { workspaceItems, itemsAfter, itemsBefore }; }, [ workspaces, workspaceMeta, deleteSendHistory, createWorkspace, openCloneGitRepositoryDialog, workspace?.id, workspace, workspaceActions.map, workspaceActions.length, ]); const handleSwitchWorkspace = useCallback(async (workspaceId: string | null) => { if (workspaceId == null) return; const settings = jotaiStore.get(settingsAtom); const activeWorkspaceId = jotaiStore.get(activeWorkspaceIdAtom); if (workspaceId === activeWorkspaceId) { // Always open a new window if the selected one is already active switchWorkspace.mutate({ workspaceId, inNewWindow: true }); return; } if (typeof settings.openWorkspaceNewWindow === 'boolean') { switchWorkspace.mutate({ workspaceId, inNewWindow: settings.openWorkspaceNewWindow }); return; } const workspace = getModel('workspace', workspaceId); if (workspace == null) return; showDialog({ id: 'switch-workspace', size: 'sm', title: 'Switch Workspace', render: ({ hide }) => , }); }, []); return ( ); });