/// /// /// import { searchForPages } from "../scrapbox-userscript-std/rest.ts"; import { toTitleLc, useStatusBar } from "../scrapbox-userscript-std/dom.ts"; import { pool } from "../async-lib/mod.ts"; import type { Scrapbox } from "../scrapbox-jp%2Ftypes/userscript.ts"; import type { SearchGyazo } from "./gyazo.ts"; import { makeGyazoArea, makeSearchResult } from "./dom.ts"; declare const scrapbox: Scrapbox; declare global { interface Window { searchGyazo: SearchGyazo; } } export const setup = () => { launch(); scrapbox.addListener("page:changed", launch); }; const launch = () => { if (scrapbox.Layout !== "list") return; if (!/search\/page/.test(location.href)) return; const { button, list } = makeGyazoArea(); button.addEventListener("click", async () => { const { render, dispose } = useStatusBar(); try { const query = new URLSearchParams(location.search).get("q") ?? ""; render({ type: "spinner" }, { type: "text", text: `Searching Gyazo for "${query}"...`, }); const images = await window.searchGyazo(query); const project = scrapbox.Project.name; const titles = new Set(); await Promise.all([...pool(3, images, async ({ url, image_id }) => { if (!image_id || !url) return; const result = await searchForPages(image_id, project); if (!result.ok) return; const { pages } = result.value; for (const { title, lines } of pages) { if (titles.has(toTitleLc(title))) continue; titles.add(toTitleLc(title)); render({ type: "spinner" }, { type: "text", text: `Searching Gyazo for "${query}"... Found ${titles.size} pages.`, }); list.append(makeSearchResult(project, title, url, lines)); } })]); render({ type: "check-circle" }, { type: "text", text: `Found ${titles.size} pages.`, }); } catch (e) { if ("name" in e && "message" in e) { render({ type: "exclamation-triangle" }, { type: "text", text: `${e.name} ${e.message}`, }); } else { render({ type: "exclamation-triangle" }, { type: "text", text: `Unexpected error occurs! (see developer console)`, }); } console.error(e); } finally { setTimeout(dispose, 1000); } }); };