UI
This commit is contained in:
parent
2bfb2990d4
commit
537465842d
7 changed files with 400 additions and 10 deletions
16
README.md
16
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
|
||||
|
||||
|
|
|
@ -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})
|
||||
|
|
325
resources/public/brutalist.css
Normal file
325
resources/public/brutalist.css
Normal file
|
@ -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%); }
|
13
resources/public/index.html
Normal file
13
resources/public/index.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Lynks</title>
|
||||
<link type="text/css" rel="stylesheet" href="brutalist.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>lynks</h1>
|
||||
<h2>here</h2>
|
||||
<ul id="lynks"></ul>
|
||||
<script src="/lynks.js"></script>
|
||||
</body>
|
||||
</html>
|
33
resources/public/lynks.js
Normal file
33
resources/public/lynks.js
Normal file
|
@ -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))));
|
|
@ -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))))
|
||||
|
|
|
@ -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)})))
|
||||
|
|
Loading…
Reference in a new issue