Create universal file download logic

This commit is contained in:
Sam Becker 2024-09-21 15:55:54 -05:00
parent d3c8db474e
commit 17b999f8d3
3 changed files with 24 additions and 15 deletions

View File

@ -3,14 +3,13 @@ import { clsx } from 'clsx/lite';
import { downloadFileNameForPhoto, Photo } from '@/photo';
import LoaderButton from './primitives/LoaderButton';
import { useState } from 'react';
import { downloadFileFromBrowser } from '@/utility/url';
export default function DownloadButton({
photo,
dim,
className,
}: {
photo: Photo
dim?: boolean
className?: string
}) {
const [isLoading, setIsLoading] = useState(false);
@ -20,7 +19,7 @@ export default function DownloadButton({
title="Download Original File"
className={clsx(
className,
dim ? 'text-dim' : 'text-medium',
'text-medium',
'-mx-0.5 translate-x-0.5',
'sm:mx-0 sm:translate-x-0'
)}
@ -30,17 +29,8 @@ export default function DownloadButton({
isLoading={isLoading}
onClick={async () => {
setIsLoading(true);
const blob = await fetch(photo.url)
.then(response => response.blob())
downloadFileFromBrowser(photo.url, downloadFileNameForPhoto(photo))
.finally(() => setIsLoading(false));
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = downloadFileNameForPhoto(photo);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
}}
/>
);

View File

@ -5,6 +5,7 @@ import { clsx } from 'clsx/lite';
import { ReactNode, useState, useTransition } from 'react';
import LoaderButton from '../primitives/LoaderButton';
import { usePathname, useRouter } from 'next/navigation';
import { downloadFileFromBrowser } from '@/utility/url';
export default function MoreMenuItem({
label,
@ -53,8 +54,10 @@ export default function MoreMenuItem({
}
}
if (href && href !== pathname) {
if (Boolean(hrefDownloadName)) {
window.open(href, '_blank');
if (hrefDownloadName) {
setIsLoading(true);
downloadFileFromBrowser(href, hrefDownloadName)
.finally(() => setIsLoading(false));
} else {
startTransition(() => router.push(href));
}

View File

@ -10,3 +10,19 @@ export const makeUrlAbsolute = (url?: string) => url !== undefined
? (!url.startsWith('http') ? `https://${url}` : url)
.replace(/\/$/, '')
: undefined;
export const downloadFileFromBrowser = async (
url: string,
fileName: string,
) => {
const blob = await fetch(url)
.then(response => response.blob());
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
};