diff --git a/src/components/messageStream/MessageBubble.tsx b/src/components/messageStream/MessageBubble.tsx index 0cb931f..5e1fb73 100644 --- a/src/components/messageStream/MessageBubble.tsx +++ b/src/components/messageStream/MessageBubble.tsx @@ -32,22 +32,24 @@ export function MessageBubble({ post }: { post: Post }) { ); return ( -
- - - -
+ + + + + ); } diff --git a/src/components/messageStream/utils/downloadFile.ts b/src/components/messageStream/utils/downloadFile.ts index 99d2fdf..c9050a4 100644 --- a/src/components/messageStream/utils/downloadFile.ts +++ b/src/components/messageStream/utils/downloadFile.ts @@ -1,27 +1,5 @@ import { assetUrl } from "../../../api"; -type SaveFilePicker = (options?: { - suggestedName?: string; - types?: Array<{ - description?: string; - accept: Record; - }>; -}) => Promise<{ - createWritable: () => Promise<{ - write: (data: Blob) => Promise; - close: () => Promise; - }>; -}>; - -type NavigatorWithFileShare = Navigator & { - canShare?: (data: { files?: File[] }) => boolean; - share?: (data: { files?: File[]; title?: string }) => Promise; -}; - -type WindowWithSavePicker = Window & { - showSaveFilePicker?: SaveFilePicker; -}; - export function attachmentDownloadUrl(postId: string, attachmentId: string) { return assetUrl( `/api/posts/${encodeURIComponent(postId)}/attachments/${encodeURIComponent( @@ -39,45 +17,7 @@ export async function downloadAttachment( } export async function downloadFile(url: string, filename: string) { - const res = await fetch(url, { credentials: "include" }); - if (!res.ok) throw new Error(await res.text()); - - const blob = await res.blob(); - const safeName = filename || "download"; - - if (window.isSecureContext) { - const picker = (window as WindowWithSavePicker).showSaveFilePicker; - if (picker) { - const handle = await picker({ - suggestedName: safeName, - types: blob.type - ? [ - { - description: "File", - accept: { [blob.type]: [extensionFromName(safeName)] }, - }, - ] - : undefined, - }); - const writable = await handle.createWritable(); - await writable.write(blob); - await writable.close(); - return; - } - } - - const file = new File([blob], safeName, { - type: blob.type || "application/octet-stream", - }); - const nav = navigator as NavigatorWithFileShare; - if (nav.canShare?.({ files: [file] }) && nav.share) { - await nav.share({ files: [file], title: safeName }); - return; - } - - const objectUrl = URL.createObjectURL(blob); - triggerDownload(objectUrl, safeName); - window.setTimeout(() => URL.revokeObjectURL(objectUrl), 30_000); + triggerDownload(url, filename || "download"); } function triggerDownload(url: string, filename: string) { @@ -89,8 +29,3 @@ function triggerDownload(url: string, filename: string) { a.click(); a.remove(); } - -function extensionFromName(filename: string) { - const match = /\.[^.]+$/.exec(filename); - return match?.[0] || ".bin"; -}