import { e } from "./helper.ts" import { bangs } from "./query.ts" import { status } from "./ui.ts" import { pw_modal } from "./pwmodal.ts" import fuzzysort from "./fuzzysort.js" export function section_info_start() { return e("section", { class: "info" }, e("h1", {}, "Fastbangs"), e("p", {}, ` This application provides a way to (mostly) locally handle search bangs. To use it: `), e("ul", {}, e("li", {}, "Select a fallback search engine, used when a search doesn't contain a bang"), e("li", {}, "Add this search engine to your browser, or bookmark this page"), ), e("span", {}, "Can't find a search engine? "), e("a", { href: "#~submit" }, "Propose or change a bang."), ) } export function section_engine_select() { const select = async (e: string) => { const engine = e.toLowerCase() if (!(await bangs)[engine]) return status("error", `Engine ${JSON.stringify(e)} does not exist.`) window.location.hash = `#${e}` } const listing = e("ul", {}) bangs.then(bangs => { for (const key in bangs) if (bangs[key]!.pinned) { listing.append(e("li", { class: "pinned", onclick: () => select(key) }, bangs[key]!.name ?? key)) } }) const submit = e("button", {}, "Select") submit.addEventListener("click", () => select(input.value)) const searchResults = e("ul", { class: "dropdown" }) const input = e("input", { type: "search" }) input.addEventListener("keydown", ev => { if (ev.code == "Enter") select(input.value) }) input.addEventListener("keyup", _ => { setSearchResults(searchResults, input, () => submit.click()) }) const manualInput = e("div", { id: "engine-select-manual" }, e("label", {}, "Search engines:"), input, submit, searchResults ) return e("section", { class: "engine-select" }, e("h2", {}, "Select a search engine"), manualInput, listing ) } export function section_admin_btn() { const modal = pw_modal() return e("section", { class: "admin-btn" }, e("button", { class: "open-modal", onclick: () => modal.showModal() }, "Admin Login"), modal ) } interface FuzzItem { score: number, obj: E } let bangsSearch: Promise<(query: string) => FuzzItem<{ bang: string, name: string, url: string }>[]> | undefined = undefined; function setSearchResults(ul: HTMLElement, input: HTMLInputElement, submit: () => void) { if (bangsSearch === undefined) { bangsSearch = bangs.then(bangs => { const searchSpace: { bang: string, name: string, url: string }[] = [] for (const k in bangs) { searchSpace.push({ bang: k, name: bangs[k]!.name!, url: bangs[k]!.url! }) } return q => fuzzysort.go(q, searchSpace, { threshhold: -5000, limit: 5, keys: ["bang", "name"], }) }) } bangsSearch!.then(fs => { ul.innerHTML = "" const results = fs(input.value) if (results.length === 0) ul.style.display = "none" else { ul.style.display = "flex" for (const r of results) { const it = r.obj const li = e("li", {}, e("p", { class: "name" }, it.name), e("p", { class: "bang" }, it.bang) ) li.addEventListener("click", () => { input.value = it.bang submit() }) ul.appendChild(li) } } }) }