|
1 | 1 | "use client"; |
2 | 2 |
|
3 | 3 | // Headless attachments: generic structural parts, accept matching, and the |
4 | | -// platform-default ingestion (blob URL + generated id — the browser-native way |
5 | | -// to reference a picked File; override via Composer.Attachments' create/destroy |
6 | | -// for upload-to-storage etc.). Policy (accepted types, counts, sizes), media |
7 | | -// taxonomy, send serialization, and copy are the consumer's. Card visuals |
8 | | -// belong to the styled layer. |
| 4 | +// platform-default ingestion (a blob URL that doubles as the id — the |
| 5 | +// browser-native way to reference a picked File; override via |
| 6 | +// Composer.Attachments' create/destroy for upload-to-storage etc.). Policy |
| 7 | +// (accepted types, counts, sizes), media taxonomy, send serialization, and copy |
| 8 | +// are the consumer's. Card visuals belong to the styled layer. |
9 | 9 |
|
10 | | -import { nanoid } from "nanoid"; |
11 | 10 | import { type ReactNode, useEffect, useState } from "react"; |
12 | 11 | import { createPortal } from "react-dom"; |
13 | 12 | import type { PrimitiveProps } from "../internal/primitive-props"; |
@@ -37,13 +36,12 @@ export type AttachmentErrorCode = "accept" | "max_file_size" | "max_files"; |
37 | 36 | // item referencing it by blob URL. Overridable per composer (create/destroy). |
38 | 37 | // --------------------------------------------------------------------------- |
39 | 38 |
|
40 | | -export const toAttachmentItem = (file: File): AttachmentItem => ({ |
41 | | - id: nanoid(), |
42 | | - url: URL.createObjectURL(file), |
43 | | - filename: file.name, |
44 | | - mediaType: file.type, |
45 | | - fileSize: file.size, |
46 | | -}); |
| 39 | +// Every createObjectURL call mints a fresh `blob:<origin>/<uuid>`, so the URL |
| 40 | +// is also a unique id — even for the same File added twice. |
| 41 | +export const toAttachmentItem = (file: File): AttachmentItem => { |
| 42 | + const url = URL.createObjectURL(file); |
| 43 | + return { id: url, url, filename: file.name, mediaType: file.type, fileSize: file.size }; |
| 44 | +}; |
47 | 45 |
|
48 | 46 | export const revokeAttachmentUrl = (item: Pick<AttachmentItem, "url">) => { |
49 | 47 | if (item.url?.startsWith("blob:")) { |
|
0 commit comments