Share the one HTTP envelope and the one byte formatter

Both stores carried their own ~28-line request<T>, and formatBytes existed
twice – the second copy had lost the "B" branch, so a small sprite would have
read as 0 KB had its caller ever passed one under a kilobyte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5 committed 2026-09-10 07:14:23 +02:00
1 parent 787a19d525
commit b13b130da7
11 files changed
+80 -78

No files matched your search

+2 -7
View File
@@ -3,9 +3,11 @@ import type { StoredTexture } from '../../core/store/TextureStore';
import {
Button,
drawControlBox,
formatBytes,
HStack,
Label,
Popup,
pressCount,
ScrollContainer,
type Size,
Spacer,
@@ -14,7 +16,6 @@ import {
truncate,
Widget,
} from '../../ui';
import { pressCount } from '../../ui/clicks';
import { textureLibrary } from '../../viewport/TextureLibrary';
import { importStoredImage, pickAndImport, type TextureImportDeps } from '../textureImport';
import { CAPTION_HEIGHT, containRect, gridMetrics, type GridMetrics, tileAt, tileRect } from './imageGrid';
@@ -273,12 +274,6 @@ function describe(item: PickerItem): string {
return item.assetName ? `${size} – already in the project as "${item.assetName}"` : size;
}
function formatBytes(bytes: number): string {
if (bytes >= 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
// A small sprite is a few hundred bytes, and "0 KB" reads like a broken file.
return bytes >= 1024 ? `${Math.round(bytes / 1024)} KB` : `${bytes} B`;
}
let current: ImagePicker | null = null;
export function openImagePicker(deps: TextureImportDeps): ImagePicker {
+1 -6
View File
@@ -2,6 +2,7 @@ import { CreateTextureCommand } from '../core/commands/assetCommands';
import { nextAssetName } from '../core/commands/naming';
import type { TextureAsset } from '../core/model/Asset';
import type { TextureStore, UploadedTexture } from '../core/store/TextureStore';
import { formatBytes } from '../ui';
import type { EditorState } from './state';
/** What the picker offers and a drop accepts; the server rejects everything else anyway. */
@@ -196,12 +197,6 @@ function assetNameFor(file: File): string {
return file.name.replace(/\.[^.]+$/, '').trim() || 'Texture';
}
function formatBytes(bytes: number): string {
return bytes >= 1024 * 1024 ? `${(bytes / 1024 / 1024).toFixed(1)} MB` : `${Math.round(bytes / 1024)} KB`;
}
// --- ways in ---------------------------------------------------------------------------------
/** Opens the browser's file dialog; resolves empty when the dialog was cancelled. */
export function pickImageFiles(): Promise<File[]> {
return new Promise((resolve) => {