mirror of
https://git.unlock-music.dev/um/um-react.git
synced 2025-07-03 18:52:11 +08:00
Merge pull request 'feat: 全部下载' (#91) from awalol/um-react:downloadall-fork-chakra-to-daisy into chakra-to-daisy
Reviewed-on: https://git.unlock-music.dev/um/um-react/pulls/91 Reviewed-by: 鲁树人 <lsr@noreply.unlock-music.dev>
This commit is contained in:
commit
cbb6347251
@ -15,6 +15,7 @@ import { Bounce, ToastContainer } from 'react-toastify';
|
|||||||
import { SettingsHome } from '~/features/settings/SettingsHome';
|
import { SettingsHome } from '~/features/settings/SettingsHome';
|
||||||
import { FAQ_PAGES } from '~/faq/FAQPages';
|
import { FAQ_PAGES } from '~/faq/FAQPages';
|
||||||
import { FaqHome } from '~/faq/FaqHome';
|
import { FaqHome } from '~/faq/FaqHome';
|
||||||
|
import { DownloadAll } from '~/components/DownloadAll.tsx';
|
||||||
|
|
||||||
// Private to this file only.
|
// Private to this file only.
|
||||||
const store = setupStore();
|
const store = setupStore();
|
||||||
@ -71,6 +72,7 @@ export function AppRoot() {
|
|||||||
transition={Bounce}
|
transition={Bounce}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<DownloadAll />
|
||||||
<Footer />
|
<Footer />
|
||||||
</Provider>
|
</Provider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
65
src/components/DownloadAll.tsx
Normal file
65
src/components/DownloadAll.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { DecryptedAudioFile, selectFiles } from '~/features/file-listing/fileListingSlice';
|
||||||
|
import { FaDownload } from 'react-icons/fa';
|
||||||
|
import { useAppSelector } from '~/hooks';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
|
export function DownloadAll() {
|
||||||
|
const files = useAppSelector(selectFiles);
|
||||||
|
const filesLength = Object.keys(files).length;
|
||||||
|
const onClickDownloadAll = async () => {
|
||||||
|
let dir: FileSystemDirectoryHandle | undefined;
|
||||||
|
let success = 0;
|
||||||
|
try {
|
||||||
|
dir = await window.showDirectoryPicker();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
if (e instanceof Error && e.name === 'AbortError') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const [_, file] of Object.entries(files)) {
|
||||||
|
try {
|
||||||
|
if (dir) {
|
||||||
|
await DownloadNew(dir, file);
|
||||||
|
} else {
|
||||||
|
await DownloadOld(file);
|
||||||
|
}
|
||||||
|
success++;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`下载失败: ${file.fileName}`, e);
|
||||||
|
toast.error(`出现错误: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (success === filesLength) {
|
||||||
|
toast.success(`成功下载: ${success}/${filesLength}首`);
|
||||||
|
} else {
|
||||||
|
toast.error(`成功下载: ${success}/${filesLength}首`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
style={{ width: '48px', height: '48px', paddingInline: '0px', margin: '10px', marginLeft: 'auto' }}
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={onClickDownloadAll}
|
||||||
|
title="下载全部"
|
||||||
|
>
|
||||||
|
<FaDownload />
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function DownloadNew(dir: FileSystemDirectoryHandle, file: DecryptedAudioFile) {
|
||||||
|
const fileHandle = await dir.getFileHandle(file.cleanName + '.' + file.ext, { create: true });
|
||||||
|
const writable = await fileHandle.createWritable();
|
||||||
|
await fetch(file.decrypted).then((res) => res.body?.pipeTo(writable));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function DownloadOld(file: DecryptedAudioFile) {
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = file.decrypted;
|
||||||
|
a.download = file.cleanName + '.' + file.ext;
|
||||||
|
document.body.append(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user