aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-08-01 18:40:35 +0200
committermetamuffin <metamuffin@disroot.org>2023-08-01 18:40:35 +0200
commitad2b4207d48fe19e501e0fac2c1139ce7ef4dea1 (patch)
tree0ce3271c6ca517fa81bdf6373c4515eeb5a53387 /frontend
parent7b1cb4e58347758cab25b73dc6486f5f90efa6df (diff)
downloadfastbangs-ad2b4207d48fe19e501e0fac2c1139ce7ef4dea1.tar
fastbangs-ad2b4207d48fe19e501e0fac2c1139ce7ef4dea1.tar.bz2
fastbangs-ad2b4207d48fe19e501e0fac2c1139ce7ef4dea1.tar.zst
submit ui
Diffstat (limited to 'frontend')
-rw-r--r--frontend/helper.ts4
-rw-r--r--frontend/main.ts10
-rw-r--r--frontend/search.ts8
-rw-r--r--frontend/start.ts3
-rw-r--r--frontend/style.sass8
-rw-r--r--frontend/submit.ts61
-rw-r--r--frontend/ui.ts2
7 files changed, 81 insertions, 15 deletions
diff --git a/frontend/helper.ts b/frontend/helper.ts
index f47d131..2ecfc35 100644
--- a/frontend/helper.ts
+++ b/frontend/helper.ts
@@ -5,6 +5,8 @@ interface Opts<E> {
id?: string,
src?: string,
for?: string,
+ type?: string,
+ href?: string,
onclick?: (e: E) => void,
onchange?: (e: E) => void,
}
@@ -14,6 +16,8 @@ function apply_opts<E extends HTMLElement>(e: E, o: Opts<E>) {
if (o.onclick) e.onclick = () => o.onclick!(e)
if (o.onchange) e.onchange = () => o.onchange!(e)
if (o.for) (e as unknown as HTMLLabelElement).htmlFor = o.for
+ if (o.type && e instanceof HTMLInputElement) e.type = o.type
+ if (o.href && e instanceof HTMLAnchorElement) e.href = o.href;
if (typeof o?.class == "string") e.classList.add(o.class)
if (typeof o?.class == "object") e.classList.add(...o.class)
}
diff --git a/frontend/main.ts b/frontend/main.ts
index c8f134a..6b92616 100644
--- a/frontend/main.ts
+++ b/frontend/main.ts
@@ -1,6 +1,6 @@
/// <reference lib="dom" />
-import { bangs, load_bangs, process_query } from "./query.ts";
-import { add_page_content, status } from "./ui.ts"
+import { load_bangs, process_query } from "./query.ts";
+import { add_page_content } from "./ui.ts"
load_bangs()
@@ -17,12 +17,6 @@ function process_url() {
} else {
add_page_content(engine)
}
- bangs.then(bangs => {
- if (!bangs[engine.toLowerCase()]) {
- status("error", "Engine does not exist")
- window.location.hash = "#"
- }
- })
} else {
add_page_content()
}
diff --git a/frontend/search.ts b/frontend/search.ts
index 0c808db..374cccf 100644
--- a/frontend/search.ts
+++ b/frontend/search.ts
@@ -1,5 +1,6 @@
import { e } from "./helper.ts";
import { bangs, process_query } from "./query.ts";
+import { status } from "./ui.ts"
export function section_info_search() {
return e("section", { class: "info" },
@@ -11,6 +12,13 @@ export function section_info_search() {
export function section_search(engine: string) {
link_engine(engine)
+ bangs.then(bangs => {
+ if (!bangs[engine.toLowerCase()]) {
+ status("error", "Engine does not exist")
+ window.location.hash = "#"
+ }
+ })
+
const heading = document.createElement("h1")
heading.textContent = engine
bangs.then(bangs => heading.textContent = bangs[engine]?.name ?? engine)
diff --git a/frontend/start.ts b/frontend/start.ts
index 1bb1cbb..d686b27 100644
--- a/frontend/start.ts
+++ b/frontend/start.ts
@@ -8,7 +8,8 @@ export function section_info_start() {
e("p", {}, `
This application provides a way to (mostly) locally handle search bangs.
First select a default engine to use, then register this page as a search in your browser
- `)
+ `),
+ e("a", { href: "#~submit" }, "Propose or change a bang"),
)
}
diff --git a/frontend/style.sass b/frontend/style.sass
index 5199a22..eac7239 100644
--- a/frontend/style.sass
+++ b/frontend/style.sass
@@ -20,13 +20,17 @@ h1
&.level-error
color: #ff0000
-
&.level-success
color: #00ff00
+ &.level-warn
+ color: #ffe600
section.info
margin: 5em
+section.submit
+ margin: 5em
+
section.engine-select
margin: 10em
ul
@@ -78,7 +82,5 @@ button
border: 0
cursor: pointer
-
-
label
margin-right: 1em
diff --git a/frontend/submit.ts b/frontend/submit.ts
index e8f696f..2b7a04a 100644
--- a/frontend/submit.ts
+++ b/frontend/submit.ts
@@ -1,9 +1,66 @@
import { e } from "./helper.ts";
-
+import { bangs } from "./query.ts";
+import { status } from "./ui.ts";
export function section_submit() {
- return e("section", {})
+ let skipped_warn = false;
+ const submit_button = e("button", {}, "Submit")
+ const onchange = () => { skipped_warn = false; submit_button.textContent = "Submit" }
+ const bang_input = e("input", { id: "i-bang", type: "text", onchange })
+ const url_input = e("input", { id: "i-url", type: "url", onchange })
+ const email_input = e("input", { id: "i-email", type: "email", onchange })
+ const name_input = e("input", { id: "i-name", type: "text", onchange })
+
+ submit_button.addEventListener("click", async () => {
+ const [bang, url, email, name] = [bang_input.value, url_input.value, email_input.value, name_input.value]
+ const w = [];
+ if (!url.includes("{{{s}}}")) w.push("URL does not include {{{s}}} pattern")
+ if ((await bangs)[bang]) w.push("Bang already exists, it will be overwritten")
+ if (!/^[A-Za-z0-9_-]+$/g.test(bang)) w.push("Bang has uncommon characters")
+
+ if (w.length && !skipped_warn) {
+ status("warn", w.join(", "))
+ setTimeout(() => {
+ submit_button.textContent = "Submit with warnings"
+ skipped_warn = true
+ }, 1000)
+ } else {
+ submit_bang({ bang, url, email, name })
+ bang_input.disabled = true
+ url_input.disabled = true
+ email_input.disabled = true
+ name_input.disabled = true
+ }
+ })
+
+ return e("section", { class: "submit" },
+ e("h1", {}, "Propose or change a bang"),
+ e("p", {}, `
+ Existing bangs with the same name will be overwritten.
+ Use {{{s}}} in the URL in place of the search term.
+ Proposals will come into effect after being approved by an administrator.
+ If an email address is provided, you will be informed about the status of your proposal.
+ `),
+ e("div", {}, e("label", { for: "i-name" }, "Name"), name_input),
+ e("div", {}, e("label", { for: "i-bang" }, "Bang"), bang_input),
+ e("div", {}, e("label", { for: "i-url" }, "Url"), url_input),
+ e("div", {}, e("label", { for: "i-email" }, "Notification email (optional)"), email_input),
+ submit_button
+ )
}
+async function submit_bang(submission: { bang: string, url: string, name: string, email: string }) {
+ status("info", "Submitting bang...");
+ const r = await fetch(`/submitBang`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ "Accept": "application/json"
+ },
+ body: JSON.stringify(submission)
+ })
+ if (r.ok) status("success", "Submission successful")
+ else status("error", "Submission failed")
+} \ No newline at end of file
diff --git a/frontend/ui.ts b/frontend/ui.ts
index 3b223ba..aebd8f7 100644
--- a/frontend/ui.ts
+++ b/frontend/ui.ts
@@ -11,7 +11,7 @@ export function add_page_content(engine?: string) {
}
let status_el: HTMLElement
-export function status(level: "error" | "info" | "success", text: string) {
+export function status(level: "error" | "info" | "success" | "warn", text: string) {
if (!status_el) {
status_el = document.createElement("p")
document.body.append(status_el)