diff --git a/frontend/package.json b/frontend/package.json index 03c451f..ade5123 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -35,6 +35,7 @@ "react-dnd": "^11.1.3", "react-dnd-html5-backend": "^11.1.3", "react-dom": "^18.2.0", + "react-intl": "^6.4.7", "react-is": "^18.2.0", "react-router-dom": "^6.4.5", "react-virtuoso": "^4.6.1", diff --git a/frontend/src/pages/backup.tsx b/frontend/src/pages/backup.tsx index 14e08f4..3d4447d 100644 --- a/frontend/src/pages/backup.tsx +++ b/frontend/src/pages/backup.tsx @@ -9,6 +9,7 @@ import { cli, convertSourceFiles } from "../api"; import { Root } from "../api"; import { AddFileAction, RefreshListAction, CreateBackupJobAction } from "../actions"; import { JobArchiveParam, JobCreateRequest, Source } from "../entity"; +import { chonkyI18n } from "../tools"; const useBackupSourceBrowser = (source: RefObject) => { const [files, setFiles] = useState(Array(1).fill(null)); @@ -64,6 +65,7 @@ const useBackupSourceBrowser = (source: RefObject) => { fileActions, defaultFileViewActionId: ChonkyActions.EnableListView.id, doubleClickDelay: 300, + i18n: chonkyI18n, }; }; @@ -139,6 +141,7 @@ const useBackupTargetBrowser = () => { fileActions, defaultFileViewActionId: ChonkyActions.EnableListView.id, doubleClickDelay: 300, + i18n: chonkyI18n, }; }; diff --git a/frontend/src/pages/file.tsx b/frontend/src/pages/file.tsx index a7c1cf1..a422712 100644 --- a/frontend/src/pages/file.tsx +++ b/frontend/src/pages/file.tsx @@ -12,6 +12,7 @@ import { ToobarInfo } from "../components/toolbarInfo"; import { useDetailModal, DetailModal } from "./file-detail"; import { FileGetReply } from "../entity"; +import { chonkyI18n } from "../tools"; const useDualSide = () => { const left = useRef(null); @@ -165,6 +166,7 @@ const useFileBrowser = (storageKey: string, refreshAll: () => Promise, ope defaultFileViewActionId: ChonkyActions.EnableListView.id, doubleClickDelay: 300, totalSize, + i18n: chonkyI18n, }; }; diff --git a/frontend/src/pages/restore.tsx b/frontend/src/pages/restore.tsx index e4b6e69..d59184a 100644 --- a/frontend/src/pages/restore.tsx +++ b/frontend/src/pages/restore.tsx @@ -2,15 +2,15 @@ import { useState, useEffect, useMemo, useCallback, FC, useRef, RefObject } from import Grid from "@mui/material/Grid"; import Box from "@mui/material/Box"; -import { FileBrowser, FileNavbar, FileToolbar, FileList, FileContextMenu, FileArray, FileBrowserHandle } from "@samuelncui/chonky"; +import { FileBrowser, FileNavbar, FileToolbar, FileList, FileContextMenu, FileArray, FileBrowserHandle, defaultFormatters } from "@samuelncui/chonky"; import { ChonkyActions, ChonkyFileActionData, FileData } from "@samuelncui/chonky"; import { ToobarInfo } from "../components/toolbarInfo"; -import { cli, convertFiles } from "../api"; -import { Root } from "../api"; +import { Root, cli, convertFiles } from "../api"; import { AddFileAction, RefreshListAction, CreateRestoreJobAction } from "../actions"; import { JobCreateRequest, JobRestoreParam, Source } from "../entity"; +import { chonkyI18n } from "../tools"; const useRestoreSourceBrowser = (target: RefObject) => { const [files, setFiles] = useState(Array(1).fill(null)); @@ -82,6 +82,7 @@ const useRestoreSourceBrowser = (target: RefObject) => { fileActions, defaultFileViewActionId: ChonkyActions.EnableListView.id, doubleClickDelay: 300, + i18n: chonkyI18n, }; }; @@ -132,6 +133,7 @@ const useRestoreTargetBrowser = () => { fileActions, defaultFileViewActionId: ChonkyActions.EnableListView.id, doubleClickDelay: 300, + i18n: chonkyI18n, }; }; diff --git a/frontend/src/tools.ts b/frontend/src/tools.ts index 0e5e476..ff1289c 100644 --- a/frontend/src/tools.ts +++ b/frontend/src/tools.ts @@ -1,4 +1,8 @@ +import { IntlShape } from "react-intl"; +import { Nullable } from "tsdef"; + import { filesize } from "filesize"; +import { I18nConfig, FileData, defaultFormatters } from "@samuelncui/chonky"; export const hexEncode = (buf: string) => { var str = ""; @@ -8,11 +12,7 @@ export const hexEncode = (buf: string) => { return str; }; -export const formatFilesize = (size: number | bigint): string => - filesize(size as any as number, { - base: 2, - standard: "jedec", - }) as string; +export const formatFilesize = (size: number | bigint): string => filesize(size as any as number, { standard: "iec" }) as string; export const download = (buf: Uint8Array, filename: string, contentType: string) => { const blob = new Blob([buf], { type: contentType }); @@ -27,3 +27,13 @@ export const sleep = (ms: number): Promise => new Promise((resolve) => { setTimeout(resolve, ms); }); + +export const chonkyI18n: I18nConfig = { + formatters: { + ...defaultFormatters, + formatFileSize: (_intl: IntlShape, file: Nullable): Nullable => { + if (!file || typeof file.size !== "number") return null; + return filesize(file.size, { standard: "iec" }) as string; + }, + }, +};