diff --git a/app/components/general-layout.tsx b/app/components/general-layout.tsx index 2afff41..25af46f 100644 --- a/app/components/general-layout.tsx +++ b/app/components/general-layout.tsx @@ -45,6 +45,7 @@ import { TooltipTrigger, TooltipProvider, } from "./ui/tooltip"; +import filesize from "./lib/filesize"; export const GeneralLayout = ({ children }: React.PropsWithChildren) => { const location = useLocation(); @@ -223,7 +224,7 @@ const UploadFileForm = () => { /> ))} - + {hasErrored ? (

An error occurred

@@ -277,7 +278,6 @@ const UploadFileItem = ({ failedState?: FailedUppyFile, Record>; onRemove: (id: string) => void; }) => { - const sizeInMb = bytestoMegabytes(file.size).toFixed(2); return (
{file.name} {" "} - ({sizeInMb}MB) + ({filesize(file.size, 2)})

- {file.name} ({sizeInMb}MB) + {file.name} ({filesize(file.size, 2)})

diff --git a/app/components/lib/filesize.ts b/app/components/lib/filesize.ts new file mode 100644 index 0000000..2c46d91 --- /dev/null +++ b/app/components/lib/filesize.ts @@ -0,0 +1,46 @@ +// Copied from https://github.com/hustcc/filesize.js + +type SPEC = { + readonly radix: number; + readonly unit: string[]; +}; + +const si = { + radix: 1e3, + unit: ["b", "kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"], +}; +const iec = { + radix: 1024, + unit: ["b", "Kib", "Mib", "Gib", "Tib", "Pib", "Eib", "Zib", "Yib"], +}; +const jedec = { + radix: 1024, + unit: ["b", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"], +}; + +export const SPECS = { + si, + iec, + jedec, +} as const; + +/** + * file size + * @param bytes Number of file size bytes + * @param fixed Number of decimal, default is 1. + * @param spec String of file size spec, default is jedec. Options: si, iec, jedec. + */ +export default function filesize(bytes: number, fixed = 1, spec: keyof typeof SPECS = "jedec"): string { + let _bytes = Math.abs(bytes); + + const { radix, unit } = SPECS[spec]; + + let loop = 0; + + // calculate + while (_bytes >= radix) { + _bytes /= radix; + ++loop; + } + return `${bytes.toFixed(fixed)} ${unit[loop]}`; +} diff --git a/app/routes/file-manager/columns.tsx b/app/routes/file-manager/columns.tsx index 20b5920..a0a381f 100644 --- a/app/routes/file-manager/columns.tsx +++ b/app/routes/file-manager/columns.tsx @@ -13,6 +13,8 @@ import { import { cn } from "~/utils"; import type { FileItem } from "~/data/file-provider"; import { usePinning } from "~/hooks/usePinning"; +import filesize from "~/components/lib/filesize"; + // This type is used to define the shape of our data. // You can use a Zod schema here if you want. @@ -64,6 +66,10 @@ export const columns: ColumnDef[] = [ { accessorKey: "size", header: "Size", + cell: ({ row }) => { + const size = row.getValue("size"); + return size ? filesize(size as number, 2) : ""; + }, }, { accessorKey: "pinned", diff --git a/package.json b/package.json index d80d405..0604528 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "@conform-to/react": "^1.0.2", "@conform-to/zod": "^1.0.2", "@fontsource-variable/manrope": "^5.0.19", - "@radix-ui/react-accordion": "^1.1.2", "@lumeweb/portal-sdk": "0.0.0-20240327035051", + "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.5",