diff options
author | metamuffin <metamuffin@disroot.org> | 2023-07-26 17:29:26 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-07-26 17:29:26 +0200 |
commit | 165bf2df95d42d3ff029ade606e38308e93eacc8 (patch) | |
tree | 453eee1f9bd0671f423e26ee702cf1fefb28dd6f | |
parent | f35043b395adf9ffa06b71000dfba6f560d44cb7 (diff) | |
download | fastbangs-165bf2df95d42d3ff029ade606e38308e93eacc8.tar fastbangs-165bf2df95d42d3ff029ade606e38308e93eacc8.tar.bz2 fastbangs-165bf2df95d42d3ff029ade606e38308e93eacc8.tar.zst |
front page and lots of stuff
-rw-r--r-- | frontend/main.ts | 18 | ||||
-rw-r--r-- | frontend/query.ts | 17 | ||||
-rw-r--r-- | frontend/style.sass | 74 | ||||
-rw-r--r-- | frontend/ui.ts | 60 |
4 files changed, 122 insertions, 47 deletions
diff --git a/frontend/main.ts b/frontend/main.ts index c9cd654..a5c18e7 100644 --- a/frontend/main.ts +++ b/frontend/main.ts @@ -1,6 +1,6 @@ /// <reference lib="dom" /> -import { load_bangs, process_query } from "./query.ts"; -import { add_page_content } from "./ui.ts" +import { bangs, load_bangs, process_query } from "./query.ts"; +import { add_page_content, status } from "./ui.ts" globalThis.addEventListener("hashchange", () => process_url()) @@ -12,13 +12,21 @@ globalThis.addEventListener("load", () => { function process_url() { if (document.location.hash.length != 0) { const input = document.location.hash.substring(1) - const [default_engine, query_encoded] = input.split("#") + const [engine, query_encoded] = input.split("#") if (query_encoded) { const query = decodeURIComponent(query_encoded.replaceAll("+", " ")) - process_query(default_engine, query) + process_query(engine, query) } else { - return add_page_content(default_engine) + add_page_content(engine) } + bangs.then(bangs => { + console.log("bop"); + + if (!bangs[engine]) { + status("error", "Engine does not exist") + window.location.hash = "#" + } + }) } else { add_page_content() } diff --git a/frontend/query.ts b/frontend/query.ts index c0cc9ea..f3c7e07 100644 --- a/frontend/query.ts +++ b/frontend/query.ts @@ -1,14 +1,15 @@ import { status } from "./ui.ts" // TODO embed this information into bangs.js -const ENGINE_NAMES: {[key:string]:string} = { +const ENGINE_PINNED: Set<string> = new Set(["ddg", "qw", "qwl", "g"]) +const ENGINE_NAMES: { [key: string]: string } = { "ddg": "DuckDuckGo", "qw": "Qwant", "qwl": "Qwant Lite", "g": "Google", } -interface Bangs { [key: string]: { url: string, name: string } } +interface Bangs { [key: string]: { url: string, name?: string, pinned?: boolean } | undefined } export let bangs: Promise<Bangs>; export function load_bangs() { status("info", "Loading bangs...") @@ -16,9 +17,15 @@ export function load_bangs() { (async () => { const bangs_res = await fetch("/bangs.json") if (!bangs_res.ok) return status("error", "could not download bangs.json") - const k: {[key:string]:string} = await bangs_res.json() + const k: { [key: string]: string } = await bangs_res.json() status("info", "Bangs loaded.") - r(Object.fromEntries(Object.entries(k).map(([key,url]) => [key, { url, name: ENGINE_NAMES[key] ?? key }]))) + r(Object.fromEntries(Object.entries(k).map( + ([key, url]) => [key, { + url, + name: ENGINE_NAMES[key], + pinned: ENGINE_PINNED.has(key) + }] + ))) })() }) } @@ -38,5 +45,5 @@ export async function process_query(default_engine: string, query: string) { } async function search_url(engine: string, query: string) { - return (await bangs)[engine].url.replace("{{{s}}}", encodeURIComponent(query).replaceAll("%20", "+")) + return (await bangs)[engine]!.url.replace("{{{s}}}", encodeURIComponent(query).replaceAll("%20", "+")) } diff --git a/frontend/style.sass b/frontend/style.sass index e61799a..eeaa708 100644 --- a/frontend/style.sass +++ b/frontend/style.sass @@ -1,16 +1,13 @@ -$ac-dark: rgb(52, 35, 50) +$ac-dark: rgb(29, 24, 29) $ac-light: rgb(255, 116, 227) body background-color: $ac-dark margin: 0px -p, h1, h2, h3, h4, h5, h6, input, button +p, h1, h2, h3, h4, h5, h6, input, button, label, li color: white -section.info - margin: 5em - .status background-color: black padding: 1em @@ -24,36 +21,61 @@ section.info &.level-success color: #00ff00 +section.info + margin: 5em + +section.engine-select + margin: 10em + ul + list-style: none + display: flex + flex-direction: row + flex-wrap: wrap + li + background-color: #00000040 + border-radius: 0.5em + padding: 1em + margin: 0.5em + &.pinned + width: 30% + cursor: pointer + transition: background-color 0.1s ease-out + &:hover + background-color: #00000080 section.search width: 100vw height: 50vh - display: flex; + display: flex flex-direction: column - place-content: center; - align-items: center; + place-content: center + align-items: center font-size: large font-weight: 500 - input, button - border-radius: 0.5em - padding: 0.5em +input, button + border-radius: 0.5em + padding: 0.5em + +input + width: 25em + border: 0.15em solid $ac-light + background-color: rgba(0, 0, 0, 0.3) + outline: none + transition: background-color 0.1s ease-out, border-color 0.1s ease-out + &:focus + background-color: rgba(0, 0, 0, 0.5) + border-color: lightgray !important + +button + margin-left: 1em + background-color: $ac-light + backdrop-filter: blur(5px) + border: 0 + cursor: pointer - input - width: 25em - border: 0.15em solid $ac-light - background-color: rgba(0, 0, 0, 0.3) - outline: none - &:focus - transition: 0.1s ease-out - background-color: rgba(0, 0, 0, 0.5) - border-color: lightgray !important - button - margin-left: 1em - background-color: $ac-light - backdrop-filter: blur(5px) - border: 0 - cursor: pointer +label + margin-right: 1em diff --git a/frontend/ui.ts b/frontend/ui.ts index 4096204..6a254c7 100644 --- a/frontend/ui.ts +++ b/frontend/ui.ts @@ -1,15 +1,16 @@ import { bangs, process_query } from "./query.ts"; export function add_page_content(engine?: string) { - document.getElementById("content")?.remove() + //@ts-ignore HTMLCollectionOf is an iterator + for (const e of [...document.getElementsByTagName("section")]) e.remove() if (engine) { - document.body.append(create_search_bar(engine), create_search_info()) + document.body.append(section_search(engine), section_info_search()) } else { - document.body.append(create_start_page()) + document.body.append(section_info_start(), section_engine_select()) } } -function create_search_bar(engine: string) { +function section_search(engine: string) { const section = document.createElement("section") section.classList.add("search") @@ -27,7 +28,7 @@ function create_search_bar(engine: string) { const heading = document.createElement("h1") heading.textContent = engine - bangs.then(bangs => heading.textContent = bangs[engine].name) + bangs.then(bangs => heading.textContent = bangs[engine]?.name ?? engine) const input = document.createElement("input") input.type = "input" @@ -49,7 +50,47 @@ function create_search_bar(engine: string) { return section } -function create_search_info() { +function section_engine_select() { + const section = document.createElement("section") + section.classList.add("engine-select") + + const select = async (e: string) => { + if (!(await bangs)[e]) return status("error", `Engine ${JSON.stringify(e)} does not exist.`) + window.location.hash = `#${e}` + } + + const heading = document.createElement("h2") + heading.textContent = "Select a search engine" + + const listing = document.createElement("ul") + bangs.then(bangs => { + for (const key in bangs) if (bangs[key]!.pinned) { + const li = document.createElement("li") + li.classList.add("pinned") + li.textContent = bangs[key]!.name ?? key + li.onclick = () => select(key) + listing.prepend(li) + } + }) + const other = document.createElement("li") + const label = document.createElement("label") + label.textContent = "Select other engine by bang:" + const input = document.createElement("input") + input.type = "input" + input.addEventListener("keydown", ev => { + if (ev.code == "Enter") select(input.value) + }) + const submit = document.createElement("button") + submit.textContent = "Select" + submit.addEventListener("click", () => select(input.value)) + other.append(label, input, submit) + listing.append(other) + + section.append(heading, listing) + return section +} + +function section_info_search() { const section = document.createElement("section") section.classList.add("info") @@ -63,10 +104,9 @@ function create_search_info() { return section } - -function create_start_page() { +function section_info_start() { const section = document.createElement("section") - section.id = "content" + section.classList.add("info") const heading = document.createElement("h1") heading.textContent = "Projectname" @@ -78,8 +118,6 @@ function create_start_page() { return section } - - let status_el: HTMLElement export function status(level: "error" | "info" | "success", text: string) { if (!status_el) { |