simple-fs-server/islands/DirList.tsx

93 lines
2.9 KiB
TypeScript

import { Head, asset } from "$fresh/runtime.ts";
import { useState } from "preact/hooks";
import { extname, join } from "path/posix.ts";
import { ComponentChild } from "preact";
import UpList from "./UpList.tsx";
import {extToIcon} from "../src/media.ts";
function ListItem(props:{
href: string,
icon: string,
children: ComponentChild
}) {
return (
<li class="p-1 hover:bg-gray-400 transition-colors">
<a class="flex gap-2" href={props.href}>
<img src={asset(props.icon)}/><p class="">{props.children}</p></a>
</li>
);
}
export interface EntryInfo{
name: string;
isFile: boolean;
isDirectory: boolean;
isSymlink: boolean;
size: number;
lastModified?: Date;
}
interface DirListProps {
path: string;
files: EntryInfo[];
}
export function DirList(props: DirListProps) {
const data = props;
const [files, setFiles] = useState(data.files);
return (<div>
<UpList path={data.path}></UpList>
<ul class="border-2 rounded-md">
<li class="p-1 flex gap-2">
<button class="flex" onClick={sortDir}>
<img src={asset("/icon/sort-down.svg")}/> Sort Directory
</button>
<button class="flex" onClick={sortAlpha}>
<img src={asset("/icon/sort-alpha-down.svg")} /> Sort Alphabet
</button>
</li>
<ListItem key=".." href={`/dir/${join(data.path,"..")}`}
icon="/icon/back.svg"
>...</ListItem>
{files.map((file) => (
<ListItem key={file.name} href={`/dir/${join(data.path,file.name)}`}
icon={file.isDirectory ? "/icon/folder.svg": extToIcon(extname(file.name))}
>{file.name}</ListItem>
))}
</ul>
</div>)
function sortDir() {
// sort by directory first then by index
const sorted_files = files.map((x,i)=>
([x,i] as [EntryInfo, number]))
.sort(
([a, ai],[b,bi]) => {
if (a.isDirectory && !b.isDirectory) {
return -1;
} else if (!a.isDirectory && b.isDirectory) {
return 1;
} else {
return ai - bi;
}
});
setFiles(sorted_files.map(([x,_])=>x));
}
function sortAlpha() {
// sort by alphabet first then by index
const sorted_files = files.map((x,i)=>
([x,i] as [EntryInfo, number]))
.sort(
([a, ai],[b,bi]) => {
const ret = a.name.localeCompare(b.name);
if (ret === 0) {
return ai - bi;
} else {
return ret;
}
});
setFiles(sorted_files.map(([x,_])=>x));
}
}
export default DirList;