50 lines
1.2 KiB
TypeScript
50 lines
1.2 KiB
TypeScript
export type BasketItem = {
|
|
source: string;
|
|
media_type: string;
|
|
id: string;
|
|
title: string;
|
|
artist: string;
|
|
};
|
|
|
|
const KEY = "srip-basket";
|
|
|
|
export function loadBasket(): BasketItem[] {
|
|
try {
|
|
const raw = JSON.parse(localStorage.getItem(KEY) ?? "[]");
|
|
return Array.isArray(raw) ? raw : [];
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function save(items: BasketItem[]) {
|
|
localStorage.setItem(KEY, JSON.stringify(items));
|
|
window.dispatchEvent(new Event("basket-change"));
|
|
}
|
|
|
|
export function basketKey(item: Pick<BasketItem, "media_type" | "id">): string {
|
|
return `${item.media_type}:${item.id}`;
|
|
}
|
|
|
|
export function inBasket(item: Pick<BasketItem, "media_type" | "id">): boolean {
|
|
return loadBasket().some((b) => basketKey(b) === basketKey(item));
|
|
}
|
|
|
|
export function toggleBasket(item: BasketItem): boolean {
|
|
const items = loadBasket();
|
|
const k = basketKey(item);
|
|
const next = items.some((b) => basketKey(b) === k)
|
|
? items.filter((b) => basketKey(b) !== k)
|
|
: [...items, item];
|
|
save(next);
|
|
return next.some((b) => basketKey(b) === k);
|
|
}
|
|
|
|
export function removeFromBasket(item: Pick<BasketItem, "media_type" | "id">) {
|
|
save(loadBasket().filter((b) => basketKey(b) !== basketKey(item)));
|
|
}
|
|
|
|
export function clearBasket() {
|
|
save([]);
|
|
}
|