///
///
///
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);
}
});
};