maestro/ui/src/lib/fileAttachments.ts
oss-sync 63d34d7cf6
All checks were successful
CI / build-and-test (push) Successful in 6m22s
sync: update from private repo (061c701c)
2026-07-09 03:01:06 +00:00

44 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 添付ファイル共通ヘルパー。
* - toBase64: File → base64data: URL のヘッダを除去)
* - uniqueAttachmentName: クリップボード画像の "image.png" 問題と名前衝突を解決。
* 添付一覧は name を React key / 削除キーに使うため一意である必要がある。
*/
export async function toBase64(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const result = String(reader.result ?? '');
resolve(result.includes(',') ? result.split(',')[1]! : result);
};
reader.onerror = () => reject(reader.error ?? new Error('file read error'));
reader.readAsDataURL(file);
});
}
function splitExt(name: string): { stem: string; ext: string } {
const dot = name.lastIndexOf('.');
if (dot <= 0) return { stem: name, ext: '' };
return { stem: name.slice(0, dot), ext: name.slice(dot) };
}
export function uniqueAttachmentName(
original: string,
taken: Set<string>,
now: Date = new Date(),
): string {
let base = original;
// ブラウザのクリップボード画像は一律 "image.png" で来るため日時名に差し替える
if (original === 'image.png') {
const pad = (n: number, w = 2) => String(n).padStart(w, '0');
const stamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
base = `pasted-${stamp}.png`;
}
if (!taken.has(base)) return base;
const { stem, ext } = splitExt(base);
for (let i = 2; ; i++) {
const candidate = `${stem}-${i}${ext}`;
if (!taken.has(candidate)) return candidate;
}
}