import {DecryptResult} from "@/decrypt/entity"; import {FileSystemDirectoryHandle} from "@/shims-fs"; export enum FilenamePolicy { ArtistAndTitle, TitleOnly, TitleAndArtist, SameAsOriginal, } export const FilenamePolicies: { key: FilenamePolicy, text: string }[] = [ {key: FilenamePolicy.ArtistAndTitle, text: "歌手-歌曲名"}, {key: FilenamePolicy.TitleOnly, text: "歌曲名"}, {key: FilenamePolicy.TitleAndArtist, text: "歌曲名-歌手"}, {key: FilenamePolicy.SameAsOriginal, text: "同源文件名"}, ] export function GetDownloadFilename(data: DecryptResult, policy: FilenamePolicy): string { switch (policy) { case FilenamePolicy.TitleOnly: return `${data.title}.${data.ext}`; case FilenamePolicy.TitleAndArtist: return `${data.title} - ${data.artist}.${data.ext}`; case FilenamePolicy.SameAsOriginal: return `${data.rawFilename}.${data.ext}`; default: case FilenamePolicy.ArtistAndTitle: return `${data.artist} - ${data.title}.${data.ext}`; } } export async function DirectlyWriteFile(data: DecryptResult, policy: FilenamePolicy, dir: FileSystemDirectoryHandle) { let filename = GetDownloadFilename(data, policy) // prevent filename exist try { await dir.getFileHandle(filename) filename = `${new Date().getTime()} - ${filename}` } catch (e) { } const file = await dir.getFileHandle(filename, {create: true}) const w = await file.createWritable() await w.write(data.blob) await w.close() } export function DownloadBlobMusic(data: DecryptResult, policy: FilenamePolicy) { const a = document.createElement('a'); a.href = data.file; a.download = GetDownloadFilename(data, policy) document.body.append(a); a.click(); a.remove(); } export function RemoveBlobMusic(data: DecryptResult) { URL.revokeObjectURL(data.file); if (data.picture?.startsWith("blob:")) { URL.revokeObjectURL(data.picture); } } export class DecryptQueue { private readonly pending: (() => Promise)[]; constructor() { this.pending = [] } queue(fn: () => Promise) { this.pending.push(fn) this.consume() } private consume() { const fn = this.pending.shift() if (fn) fn().then(() => this.consume).catch(console.error) } }