import { MenuEntry } from "@islands/KMenu/types.ts"; import { debounce } from "@lib/helpers.ts"; import { getCookie } from "@lib/string.ts"; import { BookResource } from "@lib/marka/schema.ts"; interface HardcoverBook { id: string; slug: string; title: string; subtitle?: string; author_names: string[]; series_names?: string[]; release_year?: string; image?: string; } export const createNewBook: MenuEntry = { title: "Create new book", meta: "", icon: "IconSquareRoundedPlus", cb: (state) => { state.menus["input_book"] = { title: "Search", entries: [], }; state.menus["loading"] = { title: "Search", entries: [ { title: "Loading", icon: "IconLoader2", cb() {}, }, ], }; state.activeMenu.value = "input_book"; state.activeState.value = "normal"; let currentQuery: string; const search = debounce(async function search(query: string) { try { currentQuery = query; if (query.length < 2) { state.menus["input_book"] = { title: "Search", entries: [ { title: "Type at least 2 characters...", cb: () => {}, }, ], }; state.activeMenu.value = "input_book"; return; } const response = await fetch("/api/hardcover/query?q=" + encodeURIComponent(query)); if (!response.ok) { throw new Error(await response.text()); } const books = await response.json() as HardcoverBook[]; if (query !== currentQuery) return; if (books.length === 0) { state.menus["input_book"] = { title: "Search", entries: [ { title: "No results found", cb: () => {}, }, ], }; } else { state.menus["input_book"] = { title: "Search", entries: books.map((b) => { return { title: `${b.title}${b.release_year ? ` (${b.release_year})` : ""}${b.author_names?.length ? ` - ${b.author_names.join(", ")}` : ""}`, cb: async () => { try { state.activeState.value = "loading"; const response = await fetch("/api/books/" + b.id, { method: "POST", }); if (!response.ok) { throw new Error(await response.text()); } const book = await response.json() as BookResource; unsub(); globalThis.location.href = "/books/" + book.name; } catch (_e: unknown) { state.activeState.value = "error"; state.loadingText.value = _e instanceof Error ? _e.message : "Unknown error"; } }, }; }), }; } state.activeMenu.value = "input_book"; } catch (_e: unknown) { state.activeState.value = "error"; state.loadingText.value = _e instanceof Error ? _e.message : "Unknown error"; } }, 500); const unsub = state.commandInput.subscribe((value) => { if (!value) { state.menus["input_book"] = { title: "Search", entries: [], }; state.activeMenu.value = "input_book"; return; } state.activeMenu.value = "loading"; search(value); }); }, visible: () => { if (!getCookie("session_cookie")) return false; if ( !globalThis?.location?.pathname?.includes("book") && globalThis?.location?.pathname !== "/" ) return false; return true; }, };