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