Files
R3ap3r 3178b8f4f7 Aurora SpotiRip desktop and web app
- Spotify playlist, library, album and artist browsing with in-app playback
- Song, playlist and album downloads via spotdl with YouTube and Bandcamp fallbacks
- Electron desktop app (castLabs Widevine) with a permanent sidebar layout
- Linux and Windows packaging scripts
2026-09-25 23:20:57 -05:00

61 lines
2.4 KiB
TypeScript

import type { WritableDirectoryHandle } from "./mp3Tags";
const DB_NAME = "aurora-spotirip";
const STORE_NAME = "handles";
const OUTPUT_KEY = "output-directory";
type PermissionedDirectoryHandle = WritableDirectoryHandle & {
queryPermission?: (options?: { mode?: "read" | "readwrite" }) => Promise<"granted" | "denied" | "prompt">;
requestPermission?: (options?: { mode?: "read" | "readwrite" }) => Promise<"granted" | "denied" | "prompt">;
};
function openDb() {
return new Promise<IDBDatabase>((resolve, reject) => {
const request = indexedDB.open(DB_NAME, 1);
request.onupgradeneeded = () => {
if (!request.result.objectStoreNames.contains(STORE_NAME)) {
request.result.createObjectStore(STORE_NAME);
}
};
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error || new Error("Unable to open local folder settings."));
});
}
export async function saveOutputDirectory(handle: WritableDirectoryHandle) {
const db = await openDb();
try {
await new Promise<void>((resolve, reject) => {
const tx = db.transaction(STORE_NAME, "readwrite");
tx.objectStore(STORE_NAME).put(handle, OUTPUT_KEY);
tx.oncomplete = () => resolve();
tx.onerror = () => reject(tx.error || new Error("Unable to save output folder."));
});
} finally {
db.close();
}
}
export async function loadOutputDirectory(): Promise<WritableDirectoryHandle | undefined> {
if (typeof indexedDB === "undefined") return undefined;
const db = await openDb();
try {
return await new Promise<WritableDirectoryHandle | undefined>((resolve, reject) => {
const tx = db.transaction(STORE_NAME, "readonly");
const request = tx.objectStore(STORE_NAME).get(OUTPUT_KEY);
request.onsuccess = () => resolve(request.result as WritableDirectoryHandle | undefined);
request.onerror = () => reject(request.error || new Error("Unable to restore output folder."));
});
} finally {
db.close();
}
}
export async function ensureDirectoryWritePermission(handle: WritableDirectoryHandle) {
const permissioned = handle as PermissionedDirectoryHandle;
if (!permissioned.queryPermission || !permissioned.requestPermission) return true;
const current = await permissioned.queryPermission({ mode: "readwrite" });
if (current === "granted") return true;
return (await permissioned.requestPermission({ mode: "readwrite" })) === "granted";
}