diff --git a/blocksuite/affine/blocks/attachment/src/attachment-block.ts b/blocksuite/affine/blocks/attachment/src/attachment-block.ts index 18e523fc2f..9cf1a627a5 100644 --- a/blocksuite/affine/blocks/attachment/src/attachment-block.ts +++ b/blocksuite/affine/blocks/attachment/src/attachment-block.ts @@ -22,7 +22,7 @@ import { TelemetryProvider, ThemeProvider, } from '@blocksuite/affine-shared/services'; -import { humanFileSize } from '@blocksuite/affine-shared/utils'; +import { formatSize } from '@blocksuite/affine-shared/utils'; import { AttachmentIcon, ResetIcon, @@ -316,7 +316,7 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent file.size > maxFileSize); if (exceeded) { - const size = humanFileSize(maxFileSize, true, 0); + const size = formatSize(maxFileSize); toast(std.host, `You can only upload files less than ${size}`); } diff --git a/blocksuite/affine/blocks/image/src/image-block.ts b/blocksuite/affine/blocks/image/src/image-block.ts index de3f98ceeb..639f877b1f 100644 --- a/blocksuite/affine/blocks/image/src/image-block.ts +++ b/blocksuite/affine/blocks/image/src/image-block.ts @@ -9,7 +9,7 @@ import { ThemeProvider, ToolbarRegistryIdentifier, } from '@blocksuite/affine-shared/services'; -import { humanFileSize } from '@blocksuite/affine-shared/utils'; +import { formatSize } from '@blocksuite/affine-shared/utils'; import { IS_MOBILE } from '@blocksuite/global/env'; import { BrokenImageIcon, ImageIcon } from '@blocksuite/icons/lit'; import { BlockSelection } from '@blocksuite/std'; @@ -142,7 +142,7 @@ export class ImageBlockComponent extends CaptionedBlockComponent file.size > maxFileSize); if (exceeded) { - const size = humanFileSize(maxFileSize, true, 0); + const size = formatSize(maxFileSize); toast(std.host, `You can only upload files less than ${size}`); } diff --git a/blocksuite/affine/components/src/resource/resource.ts b/blocksuite/affine/components/src/resource/resource.ts index 678d5dcaad..60efd2df92 100644 --- a/blocksuite/affine/components/src/resource/resource.ts +++ b/blocksuite/affine/components/src/resource/resource.ts @@ -20,7 +20,7 @@ export type StateKind = export type StateInfo = { icon: TemplateResult; title?: string; - description?: string; + description?: string | null; }; export type ResolvedStateInfoPart = { diff --git a/blocksuite/affine/shared/package.json b/blocksuite/affine/shared/package.json index 6a636a90c3..5aa18764ff 100644 --- a/blocksuite/affine/shared/package.json +++ b/blocksuite/affine/shared/package.json @@ -22,6 +22,7 @@ "@types/hast": "^3.0.4", "@types/lodash-es": "^4.17.12", "@types/mdast": "^4.0.4", + "bytes": "^3.1.2", "dompurify": "^3.2.4", "fractional-indexing": "^3.2.0", "lit": "^3.2.0", @@ -70,6 +71,7 @@ "!dist/__tests__" ], "devDependencies": { + "@types/bytes": "^3.1.5", "vitest": "3.1.3" }, "version": "0.21.0" diff --git a/blocksuite/affine/shared/src/utils/index.ts b/blocksuite/affine/shared/src/utils/index.ts index 0339924963..09f88adf27 100644 --- a/blocksuite/affine/shared/src/utils/index.ts +++ b/blocksuite/affine/shared/src/utils/index.ts @@ -25,3 +25,4 @@ export * from './title'; export * from './url'; export * from './virtual-padding'; export * from './zod-schema'; +export { default as formatSize } from 'bytes'; diff --git a/blocksuite/affine/shared/src/utils/math.ts b/blocksuite/affine/shared/src/utils/math.ts index e99ca058ac..7cf11e4a61 100644 --- a/blocksuite/affine/shared/src/utils/math.ts +++ b/blocksuite/affine/shared/src/utils/math.ts @@ -7,39 +7,3 @@ export function rangeWrap(n: number, min: number, max: number) { n = (n - min + max) % max; return min + (Number.isNaN(n) ? 0 : n); } - -/** - * Format bytes as human-readable text. - * - * @param bytes Number of bytes. - * @param si True to use metric (SI) units, aka powers of 1000. False to use - * binary (IEC), aka powers of 1024. - * @param dp Number of decimal places to display. - * - * @return Formatted string. - * - * Credit: https://stackoverflow.com/questions/10420352/converting-file-size-in-bytes-to-human-readable-string - */ -export function humanFileSize(bytes: number, si = true, dp = 1) { - const thresh = si ? 1000 : 1024; - - if (Math.abs(bytes) < thresh) { - return bytes + ' bytes'; - } - - const units = si - ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] - : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; - let u = -1; - const r = 10 ** dp; - - do { - bytes /= thresh; - ++u; - } while ( - Math.round(Math.abs(bytes) * r) / r >= thresh && - u < units.length - 1 - ); - - return bytes.toFixed(dp) + ' ' + units[u]; -} diff --git a/blocksuite/playground/apps/_common/components/attachment-viewer-panel.ts b/blocksuite/playground/apps/_common/components/attachment-viewer-panel.ts index 32153db93c..9e3ec0a6f5 100644 --- a/blocksuite/playground/apps/_common/components/attachment-viewer-panel.ts +++ b/blocksuite/playground/apps/_common/components/attachment-viewer-panel.ts @@ -1,7 +1,7 @@ import { getAttachmentFileIcon } from '@blocksuite/affine/components/icons'; import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit'; import type { AttachmentBlockModel } from '@blocksuite/affine-model'; -import { humanFileSize } from '@blocksuite/affine-shared/utils'; +import { formatSize } from '@blocksuite/affine-shared/utils'; import { ArrowDownBigIcon, ArrowUpBigIcon, @@ -18,7 +18,7 @@ const DPI = window.devicePixelRatio; type FileInfo = { name: string; - size: string; + size: string | null; isPDF: boolean; icon: TemplateResult; }; @@ -161,7 +161,7 @@ export class AttachmentViewerPanel extends SignalWatcher( name, icon, isPDF, - size: humanFileSize(size), + size: formatSize(size), }; if (!isPDF) return; diff --git a/tests/blocksuite/e2e/attachment.spec.ts b/tests/blocksuite/e2e/attachment.spec.ts index 1958ed3d92..d6d81fa044 100644 --- a/tests/blocksuite/e2e/attachment.spec.ts +++ b/tests/blocksuite/e2e/attachment.spec.ts @@ -143,7 +143,7 @@ test('can insert attachment from slash menu', async ({ page }, testInfo) => { await waitLoading(); expect(await getName()).toBe(FILE_NAME); - expect(await getSize()).toBe('45.8 kB'); + expect(await getSize()).toBe('44.73KB'); expect(await getPageSnapshot(page, true)).toMatchSnapshot( `${testInfo.title}.json` @@ -285,7 +285,7 @@ test(`support dragging attachment block directly`, async ({ await waitLoading(); expect(await getName()).toBe(FILE_NAME); - expect(await getSize()).toBe('45.8 kB'); + expect(await getSize()).toBe('44.73KB'); expect(await getPageSnapshot(page, true)).toMatchSnapshot( `${testInfo.title}_1.json` diff --git a/yarn.lock b/yarn.lock index e9880e395a..ab1e2afc18 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3703,9 +3703,11 @@ __metadata: "@lit/context": "npm:^1.1.2" "@preact/signals-core": "npm:^1.8.0" "@toeverything/theme": "npm:^1.1.14" + "@types/bytes": "npm:^3.1.5" "@types/hast": "npm:^3.0.4" "@types/lodash-es": "npm:^4.17.12" "@types/mdast": "npm:^4.0.4" + bytes: "npm:^3.1.2" dompurify: "npm:^3.2.4" fractional-indexing: "npm:^3.2.0" lit: "npm:^3.2.0"