import { Image, Package, Trash, TrashSimple } from '@phosphor-icons/react'; import { libraryClient, useLibraryContext, useLibraryMutation } from '@sd/client'; import { ContextMenu, dialogManager, ModifierKeys, toast } from '@sd/ui'; import { Menu } from '~/components/Menu'; import { useKeybindFactory } from '~/hooks/useKeybindFactory'; import { isNonEmpty } from '~/util'; import { usePlatform } from '~/util/Platform'; import { useExplorerContext } from '../../Context'; import { CopyAsPathBase } from '../../CopyAsPath'; import DeleteDialog from '../../FilePath/DeleteDialog'; import EraseDialog from '../../FilePath/EraseDialog'; import { Conditional, ConditionalItem } from '../ConditionalItem'; import { useContextMenuContext } from '../context'; import OpenWith from './OpenWith'; export * from './CutCopyItems'; export const Delete = new ConditionalItem({ useCondition: () => { const { selectedFilePaths } = useContextMenuContext(); if (!isNonEmpty(selectedFilePaths)) return null; const locationId = selectedFilePaths[0].location_id; if (locationId === null) return null; return { selectedFilePaths, locationId }; }, Component: ({ selectedFilePaths, locationId }) => { const keybind = useKeybindFactory(); return ( dialogManager.create((dp) => ( p.id)} /> )) } /> ); } }); export const CopyAsPath = new ConditionalItem({ useCondition: () => { const { selectedFilePaths } = useContextMenuContext(); if (!isNonEmpty(selectedFilePaths) || selectedFilePaths.length > 1) return null; return { selectedFilePaths }; }, Component: ({ selectedFilePaths }) => ( libraryClient.query(['files.getPath', selectedFilePaths[0].id])} /> ) }); export const Compress = new ConditionalItem({ useCondition: () => { const { selectedFilePaths } = useContextMenuContext(); if (!isNonEmpty(selectedFilePaths)) return null; return { selectedFilePaths }; }, Component: ({ selectedFilePaths: _ }) => { const keybind = useKeybindFactory(); return ( ); } }); export const Crypto = new ConditionalItem({ useCondition: () => { const { selectedFilePaths } = useContextMenuContext(); if (!isNonEmpty(selectedFilePaths)) return null; return { selectedFilePaths }; }, Component: ({ selectedFilePaths: _ }) => { return ( <> {/* { if (keyManagerUnlocked && hasMountedKeys) { dialogManager.create((dp) => ( )); } else if (!keyManagerUnlocked) { showAlertDialog({ title: 'Key manager locked', value: 'The key manager is currently locked. Please unlock it and try again.' }); } else if (!hasMountedKeys) { showAlertDialog({ title: 'No mounted keys', value: 'No mounted keys were found. Please mount a key and try again.' }); } }} /> */} {/* should only be shown if the file is a valid spacedrive-encrypted file (preferably going from the magic bytes) */} {/* { if (keyManagerUnlocked) { dialogManager.create((dp) => ( )); } else { showAlertDialog({ title: 'Key manager locked', value: 'The key manager is currently locked. Please unlock it and try again.' }); } }} /> */} ); } }); export const SecureDelete = new ConditionalItem({ useCondition: () => { const { selectedFilePaths } = useContextMenuContext(); if (!isNonEmpty(selectedFilePaths)) return null; const locationId = selectedFilePaths[0].location_id; if (locationId === null) return null; return { locationId, selectedFilePaths }; }, Component: ({ locationId, selectedFilePaths }) => ( dialogManager.create((dp) => ( )) } disabled /> ) }); export const ParentFolderActions = new ConditionalItem({ useCondition: () => { const { parent } = useExplorerContext(); if (parent?.type !== 'Location') return null; return { parent }; }, Component: ({ parent }) => { const { selectedFilePaths } = useContextMenuContext(); const fullRescan = useLibraryMutation('locations.fullRescan'); const generateThumbnails = useLibraryMutation('jobs.generateThumbsForLocation'); return ( <> { try { await fullRescan.mutateAsync({ location_id: parent.location.id, reidentify_objects: false }); } catch (error) { toast.error({ title: `Failed to rescan location`, body: `Error: ${error}.` }); } }} label="Rescan Directory" icon={Package} /> { try { await generateThumbnails.mutateAsync({ id: parent.location.id, path: selectedFilePaths[0]?.materialized_path ?? '/', regenerate: true }); } catch (error) { toast.error({ title: `Failed to generate thumbnails`, body: `Error: ${error}.` }); } }} label="Regen Thumbnails" icon={Image} /> ); } }); export const OpenOrDownload = new ConditionalItem({ useCondition: () => { const { selectedFilePaths } = useContextMenuContext(); const { openFilePaths } = usePlatform(); if (!openFilePaths || !isNonEmpty(selectedFilePaths)) return null; return { openFilePaths, selectedFilePaths }; }, Component: ({ openFilePaths, selectedFilePaths }) => { const keybind = useKeybindFactory(); const { platform } = usePlatform(); const updateAccessTime = useLibraryMutation('files.updateAccessTime'); const { library } = useLibraryContext(); if (platform === 'web') return ; else return ( <> { if (selectedFilePaths.length < 1) return; updateAccessTime .mutateAsync( selectedFilePaths.map((p) => p.object_id!).filter(Boolean) ) .catch(console.error); try { await openFilePaths( library.uuid, selectedFilePaths.map((p) => p.id) ); } catch (error) { toast.error({ title: `Failed to open file`, body: `Error: ${error}.` }); } }} /> ); } });