diff --git a/src/components/Album.tsx b/src/components/Album.tsx index 9c4ed2a..512c38e 100644 --- a/src/components/Album.tsx +++ b/src/components/Album.tsx @@ -1,9 +1,10 @@ import { useEffect, useState } from 'react' -import { getCors, getDownloadUrl, getTracks } from 'utils/search' +import { getDownloadUrl, getTracks, triggerDownload } from 'utils/search' import type { AlbumRow, TrackRow } from 'utils/types' import Loader from './Loader' import ClipboardBtn from './ClipboardBtn' +import { AlbumDLBtn } from './AlbumDLBtn' export default function Album(props: { album: AlbumRow; lastReqRef: React.RefObject }) { const { album, lastReqRef } = props @@ -15,7 +16,7 @@ export default function Album(props: { album: AlbumRow; lastReqRef: React.RefObj

{album.name}

- +
@@ -77,10 +78,10 @@ function TrackDownload(props: { track: TrackRow; lastReqRef: React.RefObject }) { + const { album, lastReqRef } = props + const [loading, setLoading] = useState(false) + + function handleClick(ev: React.MouseEvent) { + ev.stopPropagation() + setLoading(true) + downloadAlbum(album, lastReqRef).finally(() => setLoading(false)) + } + + return ( + + ) +} diff --git a/src/utils/search.ts b/src/utils/search.ts index 451759d..29dd62e 100644 --- a/src/utils/search.ts +++ b/src/utils/search.ts @@ -102,12 +102,12 @@ export async function getDownloadUrl(trackPageUrl: string, lastReqRef: React.Ref const flacLinks = audioLinks.filter((link) => link.endsWith('.flac')) if (flacLinks.length > 0) { - return flacLinks[0] + return getCors(flacLinks[0]) } const mp3Links = audioLinks.filter((link) => link.endsWith('.mp3')) if (mp3Links.length > 0) { - return mp3Links[0] + return getCors(mp3Links[0]) } throw new Error('Failed to fetch download url') @@ -121,3 +121,27 @@ export async function copyDownloadUrls(albumUrl: string, lastReqRef: React.RefOb await navigator.clipboard.writeText(filterUrl.join('\n')) toast.success('Copied links to the clipboard!') } + +export function triggerDownload(url: string, fileName: string) { + const fileLink = document.createElement('a') + fileLink.href = url + fileLink.setAttribute('download', fileName) + document.body.appendChild(fileLink) + fileLink.click() + fileLink.remove() +} + +export async function downloadAlbum(album: AlbumRow, lastReqRef: React.RefObject) { + const trackList = await getTracks(album.url, lastReqRef) + const newZip = new JSZip() + + const downloadList = await Promise.all( + trackList.map(async (t) => ({ ...t, blob: await (await fetch(await getDownloadUrl(t.url, lastReqRef))).blob() })) + ) + + downloadList.forEach((d) => { + newZip.file(d.fileName, d.blob) + }) + const zipBlob = window.URL.createObjectURL(await newZip.generateAsync({ type: 'blob' })) + triggerDownload(zipBlob, `${album.name}.zip`) +}