2025-10-03 23:23:05 +00:00
|
|
|
import type {
|
|
|
|
|
DirectoryHandle,
|
|
|
|
|
PathComponent,
|
|
|
|
|
} from "@fileone/convex/model/filesystem"
|
|
|
|
|
import { Link } from "@tanstack/react-router"
|
|
|
|
|
import { Fragment, useContext } from "react"
|
|
|
|
|
import {
|
|
|
|
|
Breadcrumb,
|
|
|
|
|
BreadcrumbItem,
|
|
|
|
|
BreadcrumbLink,
|
|
|
|
|
BreadcrumbList,
|
|
|
|
|
BreadcrumbPage,
|
|
|
|
|
BreadcrumbSeparator,
|
|
|
|
|
} from "../../components/ui/breadcrumb"
|
|
|
|
|
import {
|
|
|
|
|
Tooltip,
|
|
|
|
|
TooltipContent,
|
|
|
|
|
TooltipTrigger,
|
|
|
|
|
} from "../../components/ui/tooltip"
|
|
|
|
|
import { useFileDrop } from "../../files/use-file-drop"
|
|
|
|
|
import { cn } from "../../lib/utils"
|
|
|
|
|
import { DirectoryPageContext } from "./context"
|
|
|
|
|
import { dragInfoAtom } from "./state"
|
|
|
|
|
|
2025-10-05 00:48:36 +00:00
|
|
|
export function FilePathBreadcrumb({ rootLabel }: { rootLabel: string }) {
|
2025-10-03 23:23:05 +00:00
|
|
|
const { rootDirectory, directory } = useContext(DirectoryPageContext)
|
|
|
|
|
|
|
|
|
|
const breadcrumbItems: React.ReactNode[] = []
|
|
|
|
|
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-03 23:23:05 +00:00
|
|
|
</Fragment>,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Breadcrumb>
|
|
|
|
|
<BreadcrumbList>
|
|
|
|
|
{rootDirectory._id === directory._id ? (
|
|
|
|
|
<BreadcrumbItem>
|
2025-10-05 00:48:36 +00:00
|
|
|
<BreadcrumbPage>{rootLabel}</BreadcrumbPage>
|
2025-10-03 23:23:05 +00:00
|
|
|
</BreadcrumbItem>
|
|
|
|
|
) : (
|
2025-10-05 00:54:22 +00:00
|
|
|
<FilePathBreadcrumbItem
|
|
|
|
|
component={directory.path[0]!}
|
|
|
|
|
rootLabel={rootLabel}
|
|
|
|
|
/>
|
2025-10-03 23:23:05 +00:00
|
|
|
)}
|
|
|
|
|
{breadcrumbItems}
|
|
|
|
|
<BreadcrumbSeparator />
|
|
|
|
|
<BreadcrumbItem>
|
|
|
|
|
<BreadcrumbPage>{directory.name}</BreadcrumbPage>{" "}
|
|
|
|
|
</BreadcrumbItem>
|
|
|
|
|
</BreadcrumbList>
|
|
|
|
|
</Breadcrumb>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-05 00:54:22 +00:00
|
|
|
function FilePathBreadcrumbItem({
|
|
|
|
|
component,
|
|
|
|
|
rootLabel,
|
|
|
|
|
}: {
|
|
|
|
|
component: PathComponent
|
|
|
|
|
rootLabel: string
|
|
|
|
|
}) {
|
2025-10-03 23:23:05 +00:00
|
|
|
const { isDraggedOver, dropHandlers } = useFileDrop({
|
|
|
|
|
destItem: component.handle as DirectoryHandle,
|
|
|
|
|
dragInfoAtom,
|
|
|
|
|
})
|
|
|
|
|
|
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>
|
|
|
|
|
<Link to={`/directories/${component.handle.id}`}>
|
|
|
|
|
{dirName}
|
|
|
|
|
</Link>
|
|
|
|
|
</BreadcrumbLink>
|
|
|
|
|
</BreadcrumbItem>
|
|
|
|
|
</TooltipTrigger>
|
|
|
|
|
<TooltipContent>Move to {dirName}</TooltipContent>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
)
|
|
|
|
|
}
|