From 537465842dd42cb2edd51ae5e6d2140db5acdb60 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Tue, 16 Aug 2022 15:11:11 +0200 Subject: [PATCH] UI --- README.md | 16 +- project.clj | 2 + resources/public/brutalist.css | 325 +++++++++++++++++++++++++++++++++ resources/public/index.html | 13 ++ resources/public/lynks.js | 33 ++++ src/lynks/core.clj | 2 +- src/lynks/main.clj | 19 +- 7 files changed, 400 insertions(+), 10 deletions(-) create mode 100644 resources/public/brutalist.css create mode 100644 resources/public/index.html create mode 100644 resources/public/lynks.js diff --git a/README.md b/README.md index 2f6fd0e..e8457c4 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,22 @@ # lynks -A Clojure library designed to ... well, that part is up to you. +A very simple url shortener application. ## Usage -FIXME +``` +{:listen "127.0.0.1" + :port 13000 + :origin "https//example.com"} +``` + + +``` +lein uberjar +java -jar lynks.jar config.edn +``` + + ## License diff --git a/project.clj b/project.clj index 0666c85..de050ad 100644 --- a/project.clj +++ b/project.clj @@ -12,8 +12,10 @@ [org.clojure/java.jdbc "0.7.12"] [org.xerial/sqlite-jdbc "3.39.2.0"] [metosin/ring-http-response "0.9.3"] + [ring "1.9.5"] [clojure.java-time "0.3.3"] [http-kit "2.3.0"] [duratom "0.5.4"]] :main lynks.main + :uberjar-name "lynks.jar" :repl-options {:init-ns lynks.core}) diff --git a/resources/public/brutalist.css b/resources/public/brutalist.css new file mode 100644 index 0000000..23f13d2 --- /dev/null +++ b/resources/public/brutalist.css @@ -0,0 +1,325 @@ +/* antidesign CSS +author: Yann Esposito +copyright: 2018 © Yann Esposito +*/ +:root { + color-scheme: light dark; +} +@media (prefers-color-scheme: light) { + :root { + --accent: #f60; + --title: var(--accent); + --background: hsl(218,20%,97%); + --foreground: hsl(218,20%,27%); + --fgh: hsl(218,20%,14%); + --border-color: hsl(218,20%,82%); + --accent-fg: var(--background); + --accent-bg: var(--accent); + } +} +@media (prefers-color-scheme: dark) { + :root { + --accent: #94c47d; + --title: var(--accent); + --background: hsl(218,20%,18%); + --foreground: hsl(218,20%,60%); + --fgh: hsl(218,20%,82%); + --border-color: hsl(218,20%,34%); + --accent-fg: var(--background); + --accent-bg: var(--accent); + } +} +#lynks { text-align: left; } +html, body, input, button, pre, textarea { + font-size: 12px; + font-family: Menlo, monospace; + text-rendering: optimizeLegibility; + background-color: var(--background); + color: var(--foreground); + padding: 0; + margin: 0; +} +html { + background-color: var(--background); + color: var(--foreground); +} +h1,h2,h3,h4,h5,h6 { + font-size: 12px; font-weight:bold; + margin: 1ex 0; + text-align: center; +} +h1::after,h1::before { + content: "================"; + display:block; +} +h2::after { + content: "---------------------"; + display:block; + line-height: 0; +} +h3 { opacity: 0.3; font-size: 0.8em; line-height: 1em; margin: 0; padding: 0; } +h3::before { content: "--- "} +h3::after { content: " ---"} +p { margin: 0; padding: 0;} +body { + line-height: 1.2em; + max-width: 85rem; + background: var(--background); + margin: 0 auto; + text-align: center; +} +.block { display: inline-block; + vertical-align: top; + width: 13rem; + overflow: scroll; + padding: 0; + margin: 0; + text-align: left; + } +hr { border: none; + outline: none; + margin: 1ex 0; + padding: 0; + background: var(--border-color); + display: block; } +/* minimal modern colors */ +a { text-decoration: none; outline: none; } +ul { padding-left: 1em; margin: 0; list-style-type: none; padding-left: 0;} + +ul ul { margin-left: 1.5ex; } + +code { padding: 2px; } + +blockquote { + border-left: solid 1em var(--border-color); + margin-left: 0px; + padding-left: 1em; } +pre { font-size: .8em; + padding: 5px; + overflow: scroll; + margin: 0; + } + +/* forms, inputs, buttons */ +/* buttons */ +input,textarea,button { font-size: 0.8em; } +input:focus,textarea:focus { outline: none; + color: var(--accent); + background-color: var(--background); + border-color: var(--accent); } +input::placeholder { + color: var(--foreground); + opacity: 0.3; +} +input[type=submit] { + max-width: auto; + width: auto; + color: var(--foreground); + font-weight: bold; +} +details:hover { cursor: pointer; color: var(--accent); border:none; } +details:hover > summary { color: var(--accent); } +summary:focus { outline: none; } +input[type=submit]:hover, +input[type=submit]:active +{ + color: var(--accent); +} +input,textarea { padding: 4px; + border: 1pt solid var(--border-color); + vertical-align: top; + background-color: var(--background); + } +textarea { min-height: 13em; } +*:focus { outline: solid 2px var(--accent); } + +#release { width: 14em; } +#agenda,#personalagenda { width: 820px; text-align: left; margin: 0 auto;} + +label { + display: inline-block; + min-width: 8em; + line-height: 2em; + margin-right: 1ex; +} + +/* == tables === */ + +table { max-width: 100%; + overflow: scroll; } +th { border-bottom: solid 2px; + padding: 0 1em; } +td { border-bottom: dotted 1px LightGray; + overflow: scroll; + padding: 0 1em; } + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section, +summary { + display: block; + margin: 0; +} +audio, +canvas, +video { + display: inline-block; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden] { + display: none; +} +html { + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +mark { + background: #ff0; + color: #000; +} +code, +kbd, +pre, +samp { + font-size: 1em; +} +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} +small { + font-size: 80%; +} +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 0; +} +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} +legend { + border: 0; + padding: 0; +} +button, +input, +select, +textarea { + font-size: 100%; + margin: 0; +} +button, +input { + line-height: normal; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +input[disabled] { + cursor: default; +} +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0; +} +input[type="search"] { + -webkit-appearance: textfield; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + height: 1.5em; + border-radius: 3px; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} +textarea { + overflow: auto; + vertical-align: top; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +code { padding: 2px; } +li { white-space: nowrap; } +li > a { display: inline-block; width: calc(100% - 2px); padding: 0 1px; } +a { color: var(--foreground); } +a:visited { color: var(--foreground); } +a:hover { color: var(--accent-fg); background-color: var(--accent-bg); font-weight: bold;} +h1 { color: var(--title);} +h2 { color: var(--fgh); } +h3 { color: var(--fgh); } +h4 { color: var(--fgh); } +h5 { color: var(--fgh); } +h6 { color: var(--fgh); } +#personalagendatoggle,#agendatoggle,#worktoggle { float: right; } +#personalagendatoggle:hover, #agendatoggle:hover, #worktoggle:hover { cursor: pointer; color: var(--fgh); } +#release { text-align: left; clear: both; } +#release,#clocks { margin-top: 1rem; } +.selected { text-decoration: underline; } +.org-time-grid { opacity: 0.3; } +.org-agenda-done, .custom-1 { opacity: 0.2; } +.org-super-agenda-header { font-weight: bold; } +.org-tag { opacity: 0.5; float: right; } +.org-link { text-decoration: underline; } +.custom { font-weight: bold; color: hsl(0, 60%, 60%); } diff --git a/resources/public/index.html b/resources/public/index.html new file mode 100644 index 0000000..2dd0e38 --- /dev/null +++ b/resources/public/index.html @@ -0,0 +1,13 @@ + + + + Lynks + + + +

lynks

+

here

+ + + + diff --git a/resources/public/lynks.js b/resources/public/lynks.js new file mode 100644 index 0000000..022b2df --- /dev/null +++ b/resources/public/lynks.js @@ -0,0 +1,33 @@ +function newspan(txt) { + const s = document.createElement("span"); + const t = document.createTextNode(txt); + s.appendChild(t); + return s; +} + +function add(n,lst) { + lst.forEach((e) => n.appendChild(e)); +} + +function entryNode(entry) { + const created = newspan(entry.created); + const label = newspan(entry.label); + const url = newspan(entry.url); + + const a = document.createElement("a"); + a.href = entry.url; + add(a,[created,newspan(" "),label,newspan(" "),url]) + return a; +} + +function appendEntry (entry) { + const u = document.getElementById("lynks"); + const li = document.createElement("li"); + const a = entryNode(entry); + li.appendChild(a); + u.appendChild(li); +} +fetch('/y') + .then((response) => response.json()) + .then((lst) => + (lst.forEach (entry => appendEntry(entry)))); diff --git a/src/lynks/core.clj b/src/lynks/core.clj index d472e03..58e6be4 100644 --- a/src/lynks/core.clj +++ b/src/lynks/core.clj @@ -119,5 +119,5 @@ ;; coercing request parameters coercion/coerce-request-middleware]}}) (ring/routes - (swagger-ui/create-swagger-ui-handler {:path "/"}) + (ring/create-resource-handler {:path "/" :root "public"}) (ring/create-default-handler)))) diff --git a/src/lynks/main.clj b/src/lynks/main.clj index 7b10614..a499381 100644 --- a/src/lynks/main.clj +++ b/src/lynks/main.clj @@ -1,8 +1,10 @@ (ns lynks.main - (:require [org.httpkit.server :as http-kit] - [clojure.edn :as edn] - [lynks.core :refer [app]]) - (:gen-class)) + (:gen-class) + (:require + [clojure.edn :as edn] + [lynks.core :refer [app]] + [org.httpkit.server :as http-kit] + [ring.middleware.reload :as reload])) (defn -main [& args] (let [config (or (some-> args first slurp clojure.edn/read-string) {}) @@ -16,6 +18,9 @@ (str "http://" listen (when port (str ":" port)))))] (println origin) - (http-kit/run-server (app origin) - {:ip (or listen "127.0.0.1") - :port (or port 13000)}))) + (http-kit/run-server + (reload/wrap-reload (fn [req] ((app origin) req)) + {:dirs ["src" + "resources/public"]}) + {:ip (or listen "127.0.0.1") + :port (or port 13000)})))