fix(app): paste clipboard images on mobile (#2793)
Native composers had no path from the device clipboard into image attachments. Route clipboard data URLs through the existing attachment persistence flow and expose the action only in the native attachment sheet.
This commit is contained in:
@@ -143,20 +143,27 @@ function browserElementWorkspaceAttachment(): Extract<
|
||||
|
||||
function createFakePersister(): AttachmentPersister & {
|
||||
blobCalls: Array<{ blob: Blob; mimeType: string; fileName: string | null }>;
|
||||
dataUrlCalls: Array<{ dataUrl: string; mimeType: string; fileName: string | null }>;
|
||||
fileUriCalls: Array<{ uri: string; mimeType: string; fileName: string | null }>;
|
||||
deletedBatches: AttachmentMetadata[][];
|
||||
} {
|
||||
const blobCalls: Array<{ blob: Blob; mimeType: string; fileName: string | null }> = [];
|
||||
const dataUrlCalls: Array<{ dataUrl: string; mimeType: string; fileName: string | null }> = [];
|
||||
const fileUriCalls: Array<{ uri: string; mimeType: string; fileName: string | null }> = [];
|
||||
const deletedBatches: AttachmentMetadata[][] = [];
|
||||
return {
|
||||
blobCalls,
|
||||
dataUrlCalls,
|
||||
fileUriCalls,
|
||||
deletedBatches,
|
||||
persistFromBlob: async ({ blob, mimeType, fileName }) => {
|
||||
blobCalls.push({ blob, mimeType, fileName });
|
||||
return { ...imageMetadata, id: `blob-${blobCalls.length}` };
|
||||
},
|
||||
persistFromDataUrl: async ({ dataUrl, mimeType, fileName }) => {
|
||||
dataUrlCalls.push({ dataUrl, mimeType, fileName });
|
||||
return { ...imageMetadata, id: `data-url-${dataUrlCalls.length}` };
|
||||
},
|
||||
persistFromFileUri: async ({ uri, mimeType, fileName }) => {
|
||||
fileUriCalls.push({ uri, mimeType, fileName });
|
||||
return { ...imageMetadata, id: `uri-${fileUriCalls.length}` };
|
||||
@@ -388,6 +395,25 @@ describe("pickAndPersistImages", () => {
|
||||
]);
|
||||
expect(result).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("persists data_url sources via persistFromDataUrl", async () => {
|
||||
const persister = createFakePersister();
|
||||
const dataUrl = "data:image/png;base64,AAEC";
|
||||
const result = await pickAndPersistImages({
|
||||
pickImages: async () => [
|
||||
{
|
||||
source: { kind: "data_url", dataUrl },
|
||||
mimeType: "image/png",
|
||||
fileName: "clipboard.png",
|
||||
},
|
||||
],
|
||||
persister,
|
||||
});
|
||||
expect(persister.dataUrlCalls).toEqual([
|
||||
{ dataUrl, mimeType: "image/png", fileName: "clipboard.png" },
|
||||
]);
|
||||
expect(result).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("dispatchComposerAgentMessage", () => {
|
||||
|
||||
Reference in New Issue
Block a user