59 lines
1.6 KiB
TypeScript
59 lines
1.6 KiB
TypeScript
export interface DownloadFileOptions {
|
|
downloadUrl: string;
|
|
fileName: string;
|
|
}
|
|
|
|
const isMobile =
|
|
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
navigator.userAgent,
|
|
);
|
|
|
|
export async function downloadBlobFile({
|
|
downloadUrl,
|
|
fileName,
|
|
}: DownloadFileOptions): Promise<void> {
|
|
// Use window.open for desktop, blob download for mobile
|
|
if (!isMobile) {
|
|
window.open(downloadUrl, "_blank");
|
|
return;
|
|
}
|
|
|
|
const response = await fetch(downloadUrl);
|
|
const blob = await response.blob();
|
|
|
|
const contentType: string | null = response.headers.get("Content-Type");
|
|
|
|
const extensionMap: Record<string, string> = {
|
|
"application/pdf": "pdf",
|
|
"image/jpeg": "jpg",
|
|
"image/png": "png",
|
|
"image/gif": "gif",
|
|
"application/zip": "zip",
|
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
|
"docx",
|
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
|
|
};
|
|
|
|
let extension = contentType ? extensionMap[contentType] : undefined;
|
|
|
|
if (!extension) {
|
|
const urlWithoutQuery = downloadUrl.split("?")[0];
|
|
extension = urlWithoutQuery.includes(".")
|
|
? urlWithoutQuery.split(".").pop()
|
|
: "pdf";
|
|
}
|
|
|
|
const blobForDownload = new Blob([blob], {
|
|
type: "application/octet-stream",
|
|
});
|
|
const url = URL.createObjectURL(blobForDownload);
|
|
const link = document.createElement("a");
|
|
link.href = url;
|
|
link.download = `${fileName}.${extension}`;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
setTimeout(() => {
|
|
document.body.removeChild(link);
|
|
URL.revokeObjectURL(url);
|
|
}, 100);
|
|
}
|