feat: add basic file actions

This commit is contained in:
lucaronin
2026-04-27 01:45:16 +02:00
parent d15437face
commit 908daafaa1
26 changed files with 734 additions and 63 deletions

View File

@@ -1,5 +1,5 @@
import type { RefObject } from 'react'
import { PencilSimple, Trash } from '@phosphor-icons/react'
import { ClipboardText, FolderOpen, PencilSimple, Trash } from '@phosphor-icons/react'
import { Button } from '@/components/ui/button'
import { translate, type AppLocale } from '../../lib/i18n'
@@ -13,6 +13,8 @@ interface FolderContextMenuProps {
menu: FolderContextMenuState | null
menuRef: RefObject<HTMLDivElement | null>
onDelete?: (folderPath: string) => void
onReveal?: (folderPath: string) => void
onCopyPath?: (folderPath: string) => void
onRename: (folderPath: string) => void
locale?: AppLocale
}
@@ -21,6 +23,8 @@ export function FolderContextMenu({
menu,
menuRef,
onDelete,
onReveal,
onCopyPath,
onRename,
locale = 'en',
}: FolderContextMenuProps) {
@@ -33,6 +37,30 @@ export function FolderContextMenu({
style={{ left: menu.x, top: menu.y, minWidth: 180 }}
data-testid="folder-context-menu"
>
{onReveal && (
<Button
type="button"
variant="ghost"
className="h-auto w-full justify-start gap-2 px-2 py-1.5 text-sm"
onClick={() => onReveal(menu.path)}
data-testid="reveal-folder-menu-item"
>
<FolderOpen size={14} />
{translate(locale, 'sidebar.action.revealFolderMenu')}
</Button>
)}
{onCopyPath && (
<Button
type="button"
variant="ghost"
className="h-auto w-full justify-start gap-2 px-2 py-1.5 text-sm"
onClick={() => onCopyPath(menu.path)}
data-testid="copy-folder-path-menu-item"
>
<ClipboardText size={14} />
{translate(locale, 'sidebar.action.copyFolderPathMenu')}
</Button>
)}
<Button
type="button"
variant="ghost"

View File

@@ -1,21 +1,19 @@
import { useCallback, useEffect, useRef, useState, type MouseEvent as ReactMouseEvent } from 'react'
import { useCallback, useEffect, useRef, useState, type MouseEvent as ReactMouseEvent, type RefObject } from 'react'
import type { FolderNode } from '../../types'
import type { FolderFileActions } from '../../hooks/useFileActions'
import type { FolderContextMenuState } from './FolderContextMenu'
interface UseFolderContextMenuInput {
onDeleteFolder?: (folderPath: string) => void
folderFileActions?: FolderFileActions
onStartRenameFolder?: (folderPath: string) => void
}
export function useFolderContextMenu({
onDeleteFolder,
onStartRenameFolder,
}: UseFolderContextMenuInput) {
const [contextMenu, setContextMenu] = useState<FolderContextMenuState | null>(null)
const menuRef = useRef<HTMLDivElement>(null)
const closeContextMenu = useCallback(() => setContextMenu(null), [])
function useContextMenuDismiss(
contextMenu: FolderContextMenuState | null,
menuRef: RefObject<HTMLDivElement | null>,
closeContextMenu: () => void,
) {
useEffect(() => {
if (!contextMenu) return
@@ -32,7 +30,19 @@ export function useFolderContextMenu({
document.removeEventListener('mousedown', handleOutsideClick)
document.removeEventListener('keydown', handleEscape)
}
}, [closeContextMenu, contextMenu])
}, [closeContextMenu, contextMenu, menuRef])
}
export function useFolderContextMenu({
onDeleteFolder,
folderFileActions,
onStartRenameFolder,
}: UseFolderContextMenuInput) {
const [contextMenu, setContextMenu] = useState<FolderContextMenuState | null>(null)
const menuRef = useRef<HTMLDivElement>(null)
const closeContextMenu = useCallback(() => setContextMenu(null), [])
useContextMenuDismiss(contextMenu, menuRef, closeContextMenu)
const handleOpenMenu = useCallback((node: FolderNode, event: ReactMouseEvent<HTMLDivElement>) => {
event.preventDefault()
@@ -54,11 +64,23 @@ export function useFolderContextMenu({
onDeleteFolder?.(folderPath)
}, [closeContextMenu, onDeleteFolder])
const handleRevealFromMenu = useCallback((folderPath: string) => {
closeContextMenu()
folderFileActions?.revealFolder(folderPath)
}, [closeContextMenu, folderFileActions])
const handleCopyPathFromMenu = useCallback((folderPath: string) => {
closeContextMenu()
folderFileActions?.copyFolderPath(folderPath)
}, [closeContextMenu, folderFileActions])
return {
closeContextMenu,
contextMenu,
handleCopyPathFromMenu,
handleDeleteFromMenu,
handleOpenMenu,
handleRevealFromMenu,
handleRenameFromMenu,
menuRef,
}