Align compact message bubbles within media column
This commit is contained in:
@@ -1,27 +1,5 @@
|
||||
import { assetUrl } from "../../../api";
|
||||
|
||||
type SaveFilePicker = (options?: {
|
||||
suggestedName?: string;
|
||||
types?: Array<{
|
||||
description?: string;
|
||||
accept: Record<string, string[]>;
|
||||
}>;
|
||||
}) => Promise<{
|
||||
createWritable: () => Promise<{
|
||||
write: (data: Blob) => Promise<void>;
|
||||
close: () => Promise<void>;
|
||||
}>;
|
||||
}>;
|
||||
|
||||
type NavigatorWithFileShare = Navigator & {
|
||||
canShare?: (data: { files?: File[] }) => boolean;
|
||||
share?: (data: { files?: File[]; title?: string }) => Promise<void>;
|
||||
};
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user