import {
FolderFill,
FolderSymlinkFill,
FileEarmark,
FiletypeExe,
FileEarmarkBinary,
} from "react-bootstrap-icons";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuTrigger,
ContextMenuSeparator,
ContextMenuLabel,
} from "@/components/ui/context-menu";
import { TextTooltip } from "./text-tooltip";
export enum FolderElementType {
Folder = 0,
File,
}
export interface FolderElement {
name: string;
type: FolderElementType;
}
type ClickHandler = (element: FolderElement) => void;
type CreateFolderHandler = () => void;
type RemoveElementHandler = (element: FolderElement) => void;
type RenameElementHandler = (element: FolderElement) => void;
type DownloadElementHandler = (element: FolderElement) => void;
type AddFilesHandler = () => void;
type IconReader = (element: FolderElement) => string | null;
export interface FolderProps {
elements: FolderElement[];
iconReader: IconReader;
clickHandler: ClickHandler;
createFolderHandler: CreateFolderHandler;
removeElementHandler: RemoveElementHandler;
renameElementHandler: RenameElementHandler;
downloadElementHandler: DownloadElementHandler;
addFilesHandler: AddFilesHandler;
}
function elementComparator(e1: FolderElement, e2: FolderElement) {
if (e1.type != e2.type) {
return e1.type - e2.type;
}
return e1.name.localeCompare(e2.name);
}
function getIcon(
element: FolderElement,
iconReader: IconReader,
className: string = "",
) {
const icon = iconReader(element);
if (icon) {
return (
);
}
switch (element.type) {
case FolderElementType.File:
if (element.name.endsWith(".dll")) {
return ;
}
if (element.name.endsWith(".exe")) {
return ;
}
return ;
case FolderElementType.Folder:
return element.name == ".." ? (
) : (
);
default:
return <>>;
}
}
function renderIcon(element: FolderElement, iconReader: IconReader) {
let className = "w-11 h-11 flex-1";
return getIcon(element, iconReader, className);
}
function renderElement(element: FolderElement, props: FolderProps) {
return (
props.clickHandler(element)}
className="folder-element cursor-default select-none flex flex-col gap-2 items-center text-center text-xs p-2 m-2 w-27 h-25 rounded-lg border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
>
{renderIcon(element, props.iconReader)}
{element.name}
);
}
export function trimFilename(filename: string, limit = 25) {
if (limit < 4) {
limit = 4;
}
if (filename.length < limit) {
return filename;
}
return filename.substring(0, limit - 3) + "...";
}
function renderElementWithContext(element: FolderElement, props: FolderProps) {
if (element.name == "..") {
return renderElement(element, props);
}
return (
{renderElement(element, props)}
{trimFilename(element.name)}
{element.type != FolderElementType.File ? (
<>>
) : (
props.downloadElementHandler(element)}
>
Download
)}
props.renameElementHandler(element)}>
Rename
props.removeElementHandler(element)}>
Delete
);
}
function renderElementWrapper(element: FolderElement, props: FolderProps) {
return (
{renderElementWithContext(element, props)}
);
}
export function Folder(props: FolderProps) {
return (
{props.elements
.sort(elementComparator)
.map((e) => renderElementWrapper(e, props))}
Create new Folder
Add Files
);
}