import { accounts } from "$lib/stores/accounts.svelte"; import { auth } from "$lib/stores/auth.svelte"; const BASE = import.meta.env.VITE_API_BASE ?? "/api"; const FILENAME_STAR = /filename\*=UTF-8''([^;]+)/i; const FILENAME_PLAIN = /filename="?([^";]+)"?/i; function nameFromHeader(header: string | null, fallback: string): string { if (!header) { return fallback; } const encoded = FILENAME_STAR.exec(header); if (encoded) { return decodeURIComponent(encoded[1]); } const plain = FILENAME_PLAIN.exec(header); return plain ? plain[1] : fallback; } function saveBlob(blob: Blob, fileName: string) { const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = fileName; document.body.append(link); link.click(); link.remove(); setTimeout(() => URL.revokeObjectURL(url), 1000); } async function save(path: string, fallback: string): Promise { const response = await fetch(`${BASE}${path}`, { headers: auth.token ? { Authorization: `Bearer ${auth.token}` } : {}, }); if (!response.ok) { throw new Error(`download failed: ${response.status}`); } const fileName = nameFromHeader( response.headers.get("content-disposition"), fallback ); saveBlob(await response.blob(), fileName); } export function downloadMedia(mediaId: number): Promise { return save(`/media/${mediaId}?download=true`, `media_${mediaId}`); } export function downloadMediaVersion(versionId: number): Promise { return save( `/media/version/${versionId}?download=true`, `media_${versionId}` ); } export function downloadStory(peerId: number, storyId: number): Promise { return save( `/stories/${peerId}/${storyId}/media?download=true&account_id=${accounts.selectedId}`, `story_${peerId}_${storyId}` ); }