2025-10-18 19:32:05 +00:00
|
|
|
import type { Id } from "@fileone/convex/dataModel"
|
2025-10-03 23:23:05 +00:00
|
|
|
import type {
|
|
|
|
|
DirectoryHandle,
|
2025-10-05 15:01:55 +00:00
|
|
|
DirectoryPathComponent,
|
2025-10-18 14:02:20 +00:00
|
|
|
} from "@fileone/convex/filesystem"
|
2025-10-18 19:55:14 +00:00
|
|
|
import type { DirectoryInfo } from "@fileone/convex/types"
|
2025-10-03 23:23:05 +00:00
|
|
|
import { Link } from "@tanstack/react-router"
|
2025-10-18 19:55:14 +00:00
|
|
|
import type { PrimitiveAtom } from "jotai"
|
|
|
|
|
import { Fragment } from "react"
|
2025-10-03 23:23:05 +00:00
|
|
|
import {
|
|
|
|
|
Breadcrumb,
|
|
|
|
|
BreadcrumbItem,
|
|
|
|
|
BreadcrumbLink,
|
|
|
|
|
BreadcrumbList,
|
|
|
|
|
BreadcrumbPage,
|
|
|
|
|
BreadcrumbSeparator,
|
2025-10-18 19:55:14 +00:00
|
|
|
} from "@/components/ui/breadcrumb"
|
2025-10-03 23:23:05 +00:00
|
|
|
import {
|
|
|
|
|
Tooltip,
|
|
|
|
|
TooltipContent,
|
|
|
|
|
TooltipTrigger,
|
2025-10-18 19:55:14 +00:00
|
|
|
} from "@/components/ui/tooltip"
|
|
|
|
|
import type { FileDragInfo } from "@/files/use-file-drop"
|
|
|
|
|
import { useFileDrop } from "@/files/use-file-drop"
|
|
|
|
|
import { cn } from "@/lib/utils"
|
2025-10-03 23:23:05 +00:00
|
|
|
|
2025-10-18 19:55:14 +00:00
|
|
|
export function DirectoryPathBreadcrumb({
|
|
|
|
|
directory,
|
2025-10-05 15:01:55 +00:00
|
|
|
rootLabel,
|
|
|
|
|
directoryUrlFn,
|
2025-10-18 19:55:14 +00:00
|
|
|
fileDragInfoAtom,
|
2025-10-05 15:01:55 +00:00
|
|
|
}: {
|
2025-10-18 19:55:14 +00:00
|
|
|
directory: DirectoryInfo
|
2025-10-05 15:01:55 +00:00
|
|
|
rootLabel: string
|
|
|
|
|
directoryUrlFn: (directory: Id<"directories">) => string
|
2025-10-18 19:55:14 +00:00
|
|
|
fileDragInfoAtom: PrimitiveAtom<FileDragInfo | null>
|
2025-10-05 15:01:55 +00:00
|
|
|
}) {
|
2025-10-18 19:55:14 +00:00
|
|
|
const breadcrumbItems: React.ReactNode[] = [
|
|
|
|
|
<FilePathBreadcrumbItem
|
|
|
|
|
key={directory.path[0].handle.id}
|
|
|
|
|
component={directory.path[0]}
|
|
|
|
|
rootLabel={rootLabel}
|
|
|
|
|
directoryUrlFn={directoryUrlFn}
|
|
|
|
|
fileDragInfoAtom={fileDragInfoAtom}
|
|
|
|
|
/>,
|
|
|
|
|
]
|
2025-10-03 23:23:05 +00:00
|
|
|
for (let i = 1; i < directory.path.length - 1; i++) {
|
|
|
|
|
breadcrumbItems.push(
|
|
|
|
|
<Fragment key={directory.path[i]?.handle.id}>
|
|
|
|
|
<BreadcrumbSeparator />
|
2025-10-05 00:54:22 +00:00
|
|
|
<FilePathBreadcrumbItem
|
|
|
|
|
component={directory.path[i]!}
|
|
|
|
|
rootLabel={rootLabel}
|
2025-10-05 15:01:55 +00:00
|
|
|
directoryUrlFn={directoryUrlFn}
|
2025-10-18 19:55:14 +00:00
|
|
|
fileDragInfoAtom={fileDragInfoAtom}
|
2025-10-05 00:54:22 +00:00
|
|
|
/>
|
2025-10-03 23:23:05 +00:00
|
|
|
</Fragment>,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Breadcrumb>
|
|
|
|
|
<BreadcrumbList>
|
|
|
|
|
{breadcrumbItems}
|
|
|
|
|
<BreadcrumbSeparator />
|
|
|
|
|
<BreadcrumbItem>
|
|
|
|
|
<BreadcrumbPage>{directory.name}</BreadcrumbPage>{" "}
|
|
|
|
|
</BreadcrumbItem>
|
|
|
|
|
</BreadcrumbList>
|
|
|
|
|
</Breadcrumb>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-05 00:54:22 +00:00
|
|
|
function FilePathBreadcrumbItem({
|
|
|
|
|
component,
|
|
|
|
|
rootLabel,
|
2025-10-05 15:01:55 +00:00
|
|
|
directoryUrlFn,
|
2025-10-18 19:55:14 +00:00
|
|
|
fileDragInfoAtom,
|
2025-10-05 00:54:22 +00:00
|
|
|
}: {
|
2025-10-05 15:01:55 +00:00
|
|
|
component: DirectoryPathComponent
|
2025-10-05 00:54:22 +00:00
|
|
|
rootLabel: string
|
2025-10-05 15:01:55 +00:00
|
|
|
directoryUrlFn: (directory: Id<"directories">) => string
|
2025-10-18 19:55:14 +00:00
|
|
|
fileDragInfoAtom: PrimitiveAtom<FileDragInfo | null>
|
2025-10-05 00:54:22 +00:00
|
|
|
}) {
|
2025-10-03 23:23:05 +00:00
|
|
|
const { isDraggedOver, dropHandlers } = useFileDrop({
|
|
|
|
|
destItem: component.handle as DirectoryHandle,
|
2025-10-18 19:55:14 +00:00
|
|
|
dragInfoAtom: fileDragInfoAtom,
|
2025-10-03 23:23:05 +00:00
|
|
|
})
|
|
|
|
|
|
2025-10-05 00:54:22 +00:00
|
|
|
const dirName = component.name || rootLabel
|
2025-10-03 23:23:05 +00:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Tooltip open={isDraggedOver}>
|
|
|
|
|
<TooltipTrigger asChild>
|
|
|
|
|
<BreadcrumbItem
|
|
|
|
|
className={cn({ "bg-muted": isDraggedOver })}
|
|
|
|
|
{...dropHandlers}
|
|
|
|
|
>
|
|
|
|
|
<BreadcrumbLink asChild>
|
2025-10-05 15:01:55 +00:00
|
|
|
<Link to={directoryUrlFn(component.handle.id)}>
|
2025-10-03 23:23:05 +00:00
|
|
|
{dirName}
|
|
|
|
|
</Link>
|
|
|
|
|
</BreadcrumbLink>
|
|
|
|
|
</BreadcrumbItem>
|
|
|
|
|
</TooltipTrigger>
|
|
|
|
|
<TooltipContent>Move to {dirName}</TooltipContent>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
)
|
|
|
|
|
}
|