mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-09 09:54:40 +00:00
* fix(app): preserve image attachment MIME types Image intake discarded clipboard and desktop path metadata, then guessed JPEG when a later file object had no type. Resolve MIME once at the platform boundary and require it downstream. * fix(app): honor native picker MIME metadata
71 lines
1.7 KiB
TypeScript
71 lines
1.7 KiB
TypeScript
import type { AttachmentMetadata } from "@/attachments/types";
|
|
import { persistAttachmentFromBlob } from "@/attachments/service";
|
|
import { resolveRasterImageMimeType } from "@/attachments/file-types";
|
|
|
|
export interface ClipboardItemLike {
|
|
kind?: string;
|
|
type?: string;
|
|
getAsFile?: () => File | null;
|
|
}
|
|
|
|
export interface ClipboardDataLike {
|
|
items?: ArrayLike<ClipboardItemLike> | null;
|
|
}
|
|
|
|
export type ImageAttachmentFromFile = AttachmentMetadata;
|
|
|
|
export interface ClipboardImageFile {
|
|
file: File;
|
|
mimeType: string;
|
|
}
|
|
|
|
export function collectImageFilesFromClipboardData(
|
|
clipboardData?: ClipboardDataLike | null,
|
|
): ClipboardImageFile[] {
|
|
if (!clipboardData?.items) {
|
|
return [];
|
|
}
|
|
|
|
const files: ClipboardImageFile[] = [];
|
|
for (const item of Array.from(clipboardData.items)) {
|
|
if (item?.kind !== "file") {
|
|
continue;
|
|
}
|
|
const mimeType = resolveRasterImageMimeType({ mimeType: item.type });
|
|
if (!mimeType) {
|
|
continue;
|
|
}
|
|
const file = item.getAsFile?.();
|
|
if (!file) {
|
|
continue;
|
|
}
|
|
files.push({ file, mimeType });
|
|
}
|
|
|
|
return files;
|
|
}
|
|
|
|
export async function filesToImageAttachments(
|
|
files: readonly ClipboardImageFile[],
|
|
): Promise<ImageAttachmentFromFile[]> {
|
|
const attachments = await Promise.all(
|
|
files.map(async ({ file, mimeType }) => {
|
|
try {
|
|
return await persistAttachmentFromBlob({
|
|
blob: file,
|
|
mimeType,
|
|
fileName: file.name,
|
|
});
|
|
} catch (error) {
|
|
console.error("[attachments] Failed to persist file attachment", {
|
|
fileName: file.name,
|
|
error,
|
|
});
|
|
return null;
|
|
}
|
|
}),
|
|
);
|
|
|
|
return attachments.filter((entry): entry is ImageAttachmentFromFile => entry !== null);
|
|
}
|