mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-11-09 20:00:12 +00:00
Compare commits
28 Commits
7ff492df6c
...
e86f5f4c3c
Author | SHA1 | Date | |
---|---|---|---|
e86f5f4c3c | |||
3b0701e772 | |||
9874dce520 | |||
2f50ab36fd | |||
6124b9b3f3 | |||
a8ce35c13f | |||
26d9864051 | |||
a3a22d353c | |||
dd5eecf9f9 | |||
7e0e0b0520 | |||
8bee09cd01 | |||
deb117fc34 | |||
a9a0005007 | |||
4eb7afead6 | |||
d1b5b74060 | |||
cf91ee62ed | |||
277690ef79 | |||
f7f3530a33 | |||
2d3a5c739c | |||
3dbb993d35 | |||
508168b49e | |||
0e1cbd7e7b | |||
e73ecb7a52 | |||
62be8adc65 | |||
acc8892f26 | |||
0f0355fd01 | |||
a31f174375 | |||
18ae03554f |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
node_modules/
|
||||
site/node_modules/
|
||||
site/out/
|
||||
site/tempts/
|
||||
mail/*.html
|
||||
dist/
|
||||
build/
|
||||
@ -18,4 +19,5 @@ instructions-debian.txt
|
||||
cl.md
|
||||
./telegram/
|
||||
mautrix/
|
||||
tempts/
|
||||
matacc.txt
|
||||
|
@ -13,24 +13,31 @@ before:
|
||||
- npm install
|
||||
- npm install esbuild
|
||||
- mkdir -p data/web/css
|
||||
- npx esbuild --bundle css/base.css --outfile=./data/web/css/bundle.css --external:remixicon.css --minify
|
||||
- cp node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 data/web/css/
|
||||
- cp -r html data/
|
||||
- node scripts/missing-colors.js html data/html
|
||||
- cp -r lang data/
|
||||
- cp LICENSE data/
|
||||
- cp jfa-go.service data/
|
||||
- python3 scripts/enumerate_config.py -i config/config-base.json -o data/config-base.json
|
||||
- python3 scripts/generate_ini.py -i config/config-base.json -o data/config-default.ini
|
||||
- python3 scripts/compile_mjml.py -o data/
|
||||
- npx esbuild --bundle ts/admin.ts --outfile=./data/web/js/admin.js --minify
|
||||
- npx esbuild --bundle ts/pwr.ts --outfile=./data/web/js/pwr.js --minify
|
||||
- npx esbuild --bundle ts/form.ts --outfile=./data/web/js/form.js --minify
|
||||
- npx esbuild --bundle ts/setup.ts --outfile=./data/web/js/setup.js --minify
|
||||
- npx esbuild --bundle ts/crash.ts --outfile=./data/crash.js --minify
|
||||
- rm -rf tempts
|
||||
- cp -r ts tempts
|
||||
- scripts/dark-variant.sh tempts
|
||||
- scripts/dark-variant.sh tempts/modules
|
||||
- npx esbuild --bundle tempts/admin.ts --outfile=./data/web/js/admin.js --minify
|
||||
- npx esbuild --bundle tempts/pwr.ts --outfile=./data/web/js/pwr.js --minify
|
||||
- npx esbuild --bundle tempts/form.ts --outfile=./data/web/js/form.js --minify
|
||||
- npx esbuild --bundle tempts/setup.ts --outfile=./data/web/js/setup.js --minify
|
||||
- npx esbuild --bundle tempts/crash.ts --outfile=./data/crash.js --minify
|
||||
- rm -r tempts
|
||||
- npx esbuild --bundle css/base.css --outfile=./data/web/css/bundle.css --external:remixicon.css --minify
|
||||
- cp html/crash.html data/
|
||||
- npx uncss data/crash.html --csspath web/css --output data/bundle.css
|
||||
- node scripts/inline.js root data data/crash.html data/crash.html
|
||||
- rm data/bundle.css
|
||||
- npx tailwindcss -i data/web/css/bundle.css -o data/web/css/bundle.css
|
||||
- mv data/crash.html data/html/
|
||||
- go get -u github.com/swaggo/swag/cmd/swag
|
||||
- swag init -g main.go
|
||||
|
@ -6,7 +6,7 @@ RUN apt-get update -y \
|
||||
&& apt-get install build-essential python3-pip curl software-properties-common sed -y \
|
||||
&& (curl -sL https://deb.nodesource.com/setup_14.x | bash -) \
|
||||
&& apt-get install nodejs \
|
||||
&& (cd /opt/build; make configuration npm email typescript bundle-css inline swagger copy INTERNAL=off GOESBUILD=on) \
|
||||
&& (cd /opt/build; make configuration npm email typescript variants-html bundle-css inline swagger copy INTERNAL=off GOESBUILD=on) \
|
||||
&& sed -i 's#id="password_resets-watch_directory" placeholder="/config/jellyfin"#id="password_resets-watch_directory" value="/jf" disabled#g' /opt/build/build/data/html/setup.html
|
||||
|
||||
|
||||
|
35
Makefile
35
Makefile
@ -52,14 +52,17 @@ ifeq ($(DEBUG), on)
|
||||
SOURCEMAP := --sourcemap
|
||||
TYPECHECK := tsc -noEmit --project ts/tsconfig.json
|
||||
# jank
|
||||
COPYTS := rm -r $(DATA)/web/js/ts; cp -r ts $(DATA)/web/js
|
||||
COPYTS := rm -r $(DATA)/web/js/ts; cp -r tempts $(DATA)/web/js/ts
|
||||
UNCSS := cp $(DATA)/web/css/bundle.css $(DATA)/bundle.css
|
||||
TAILWIND := --content ""
|
||||
else
|
||||
LDFLAGS := -s -w $(LDFLAGS)
|
||||
SOURCEMAP :=
|
||||
COPYTS :=
|
||||
TYPECHECK :=
|
||||
UNCSS := npx uncss $(DATA)/crash.html --csspath web/css --output $(DATA)/bundle.css
|
||||
UNCSS := npx tailwindcss -i $(DATA)/web/css/bundle.css -o $(DATA)/bundle.css --content "html/crash.html"
|
||||
# UNCSS := npx uncss $(DATA)/crash.html --csspath web/css --output $(DATA)/bundle.css
|
||||
TAILWIND :=
|
||||
endif
|
||||
|
||||
RACE ?= off
|
||||
@ -91,13 +94,18 @@ email:
|
||||
|
||||
typescript:
|
||||
$(TYPECHECK)
|
||||
$(adding dark variants to typescript)
|
||||
-rm -r tempts
|
||||
cp -r ts tempts
|
||||
scripts/dark-variant.sh tempts
|
||||
scripts/dark-variant.sh tempts/modules
|
||||
$(info compiling typescript)
|
||||
-mkdir -p $(DATA)/web/js
|
||||
-$(ESBUILD) --bundle ts/admin.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/admin.js --minify
|
||||
-$(ESBUILD) --bundle ts/pwr.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/pwr.js --minify
|
||||
-$(ESBUILD) --bundle ts/form.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/form.js --minify
|
||||
-$(ESBUILD) --bundle ts/setup.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/setup.js --minify
|
||||
-$(ESBUILD) --bundle ts/crash.ts --outfile=./$(DATA)/crash.js --minify
|
||||
-$(ESBUILD) --bundle tempts/admin.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/admin.js --minify
|
||||
-$(ESBUILD) --bundle tempts/pwr.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/pwr.js --minify
|
||||
-$(ESBUILD) --bundle tempts/form.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/form.js --minify
|
||||
-$(ESBUILD) --bundle tempts/setup.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/setup.js --minify
|
||||
-$(ESBUILD) --bundle tempts/crash.ts --outfile=./$(DATA)/crash.js --minify
|
||||
$(COPYTS)
|
||||
|
||||
swagger:
|
||||
@ -118,6 +126,8 @@ bundle-css:
|
||||
-mkdir -p $(DATA)/web/css
|
||||
$(info bundling css)
|
||||
$(ESBUILD) --bundle css/base.css --outfile=$(DATA)/web/css/bundle.css --external:remixicon.css --minify
|
||||
npx tailwindcss -i $(DATA)/web/css/bundle.css -o $(DATA)/web/css/bundle.css $(TAILWIND)
|
||||
# npx postcss -o $(DATA)/web/css/bundle.css $(DATA)/web/css/bundle.css
|
||||
|
||||
inline:
|
||||
cp html/crash.html $(DATA)/crash.html
|
||||
@ -125,11 +135,16 @@ inline:
|
||||
node scripts/inline.js root $(DATA) $(DATA)/crash.html $(DATA)/crash.html
|
||||
rm $(DATA)/bundle.css
|
||||
|
||||
variants-html:
|
||||
$(info copying html)
|
||||
cp -r html $(DATA)/
|
||||
$(info adding dark variants to html)
|
||||
node scripts/missing-colors.js html $(DATA)/html
|
||||
|
||||
copy:
|
||||
$(info copying fonts)
|
||||
cp -r node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 $(DATA)/web/css/
|
||||
$(info copying html)
|
||||
cp -r html $(DATA)/
|
||||
$(info copying crash page)
|
||||
mv $(DATA)/crash.html $(DATA)/html/
|
||||
$(info copying static data)
|
||||
-mkdir -p $(DATA)/web
|
||||
@ -159,4 +174,4 @@ clean:
|
||||
-rm docs/docs.go docs/swagger.json docs/swagger.yaml
|
||||
go clean
|
||||
|
||||
all: configuration npm email typescript bundle-css inline swagger copy compile
|
||||
all: configuration npm email typescript variants-html bundle-css inline swagger copy compile
|
||||
|
122
css/base.css
122
css/base.css
@ -1,4 +1,7 @@
|
||||
@import "../node_modules/a17t/dist/a17t.css";
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@import "remixicon.css";
|
||||
@import "./modal.css";
|
||||
@import "./dark.css";
|
||||
@ -12,14 +15,39 @@
|
||||
--border-width-8: 8px;
|
||||
}
|
||||
|
||||
.light-theme {
|
||||
.light {
|
||||
--settings-section-button-filter: 90%;
|
||||
}
|
||||
|
||||
.body {
|
||||
.dark {
|
||||
--settings-section-button-filter: 80%;
|
||||
}
|
||||
|
||||
.dark body {
|
||||
background-color: #101010;
|
||||
}
|
||||
|
||||
.dark select, .dark option, .dark input {
|
||||
background: #202020;
|
||||
}
|
||||
|
||||
html:not(.dark) .card.\@low:not(.\~neutral):not(.\~positive):not(.\~urge):not(.\~warning):not(.\~info):not(.\~critical) {
|
||||
--color-fill: va(--color-fill);
|
||||
--color-content: var(--color-content);
|
||||
--color-accent: var(--color-accent);
|
||||
--color-muted: var(--color-muted);
|
||||
background-color: #fff;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.light-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dark-only {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
margin: 5% 20% 5% 20%;
|
||||
}
|
||||
@ -27,6 +55,7 @@
|
||||
@media (max-width: 1100px) {
|
||||
.page-container {
|
||||
margin: 2%;
|
||||
margin-top: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +79,8 @@
|
||||
|
||||
.banner.header {
|
||||
margin-bottom: var(--spacing-4,1rem);
|
||||
max-width: calc(100% + 2.2rem); /* no idea why this works */
|
||||
margin-left: -1.1rem;
|
||||
}
|
||||
|
||||
.banner.footer {
|
||||
@ -70,54 +101,6 @@ div.card:contains(section.banner.footer) {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.mb-half {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.mb-1 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.mb-2 {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.mt-half {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.mt-1 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.ml-1 {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.ml-half {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.mr-half {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.mr-1 {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.p-1 {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.pb-1 {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.pl-1 {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.al {
|
||||
text-align: left;
|
||||
}
|
||||
@ -203,15 +186,6 @@ span.sm:not(.heading) {
|
||||
}
|
||||
}
|
||||
|
||||
.fr {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.monospace {
|
||||
background-color: inherit; /* so we can use a17t code blocks */
|
||||
font-family: Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;
|
||||
}
|
||||
|
||||
sup.\~critical, .text-critical {
|
||||
color: var(--color-critical-normal-content);
|
||||
}
|
||||
@ -377,10 +351,8 @@ sup.\~critical, .text-critical {
|
||||
}
|
||||
|
||||
.settings-section-button {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 2.5rem;
|
||||
background-color: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
.settings-section-button:hover, .settings-section-button:focus {
|
||||
@ -392,8 +364,6 @@ sup.\~critical, .text-critical {
|
||||
}
|
||||
|
||||
.settings-section-button.selected {
|
||||
background-color: var(--color-neutral-normal-fill);
|
||||
--buton-filter-brightness: var(--settings-section-button-filter);
|
||||
filter: brightness(var(--settings-section-button-filter)) !important;
|
||||
}
|
||||
|
||||
@ -421,11 +391,21 @@ select, textarea {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
html.dark textarea {
|
||||
background-color: #202020
|
||||
}
|
||||
|
||||
input {
|
||||
color: inherit;
|
||||
border: 0 solid var(--color-neutral-300);
|
||||
}
|
||||
|
||||
table {
|
||||
color: var(--color-content);
|
||||
}
|
||||
|
||||
|
||||
|
||||
p.top {
|
||||
margin-top: 0px;
|
||||
}
|
||||
@ -462,6 +442,8 @@ pre {
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
word-wrap: break-word; /* Internet Explorer 5.5+ */
|
||||
background-color: var(--color-content-high) !important;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.circle {
|
||||
@ -543,10 +525,18 @@ div.card:contains(section.banner.footer) {
|
||||
padding: var(--spacing-4, 1rem);
|
||||
}
|
||||
|
||||
.button.discord.\!normal {
|
||||
.button.discord.\@low {
|
||||
background-color: rgba(88, 101, 242,60%);
|
||||
}
|
||||
|
||||
.button.discord.\!normal:not(.lang-link) {
|
||||
.button.discord.\@low:not(.lang-link) {
|
||||
color: rgba(38, 51, 192, 90%);
|
||||
}
|
||||
|
||||
.pb-0i {
|
||||
padding-bottom: 0px !important
|
||||
}
|
||||
|
||||
.text-center-i {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
91
css/dark.css
91
css/dark.css
@ -1,91 +0,0 @@
|
||||
.dark-theme {
|
||||
|
||||
--settings-section-button-filter: 110%;
|
||||
|
||||
--color-neutral-900: rgba(255, 255, 255, 0.87);
|
||||
--color-neutral-800: rgba(255, 255, 255, 0.8);
|
||||
--color-neutral-700: rgba(255, 255, 255, 0.73);
|
||||
--color-neutral-600: rgba(255, 255, 255, 0.66);
|
||||
--color-neutral-500: rgb(153, 153, 153);
|
||||
--color-neutral-400: #383838;
|
||||
--color-neutral-300: #303030;
|
||||
--color-neutral-200: #292929;
|
||||
--color-neutral-100: #242424;
|
||||
--color-neutral-50: #202020;
|
||||
--color-neutral-000: #101010;
|
||||
|
||||
--color-critical-900: #fef2f2;
|
||||
--color-critical-800: #fee2e2;
|
||||
--color-critical-700: #fecaca;
|
||||
--color-critical-600: #fca5a5;
|
||||
--color-critical-500: #f87171;
|
||||
--color-critical-400: #ef4444;
|
||||
--color-critical-300: #dc2626;
|
||||
--color-critical-200: #b91c1c;
|
||||
--color-critical-100: #991b1b;
|
||||
--color-critical-50: #7f1d1d;
|
||||
--color-critical-000: #441313;
|
||||
|
||||
--color-warning-900: #fffbeb;
|
||||
--color-warning-800: #fef3c7;
|
||||
--color-warning-700: #fde68a;
|
||||
--color-warning-600: #fcd34d;
|
||||
--color-warning-500: #fbbf24;
|
||||
--color-warning-400: #f59e0b;
|
||||
--color-warning-300: #d97706;
|
||||
--color-warning-200: #b45309;
|
||||
--color-warning-100: #92400e;
|
||||
--color-warning-50: #783900;
|
||||
--color-warning-000: #411e01;
|
||||
|
||||
--color-positive-900: #f0fdf4;
|
||||
--color-positive-800: #dcfce7;
|
||||
--color-positive-700: #bbf7d0;
|
||||
--color-positive-600: #86efac;
|
||||
--color-positive-500: #4ade80;
|
||||
--color-positive-400: #22c55e;
|
||||
--color-positive-300: #16a34a;
|
||||
--color-positive-200: #15803d;
|
||||
--color-positive-100: #166534;
|
||||
--color-positive-50: #14532d;
|
||||
--color-positive-000: #0f2e1b;
|
||||
|
||||
--color-urge-900: #e0ffff;
|
||||
--color-urge-800: #c0fbff;
|
||||
--color-urge-700: #a0f4ff;
|
||||
--color-urge-600: #80e9ff;
|
||||
--color-urge-500: #60dbfb;
|
||||
--color-urge-400: #40cbf3;
|
||||
--color-urge-300: #20b9e9;
|
||||
--color-urge-200: #00a4dc; /* tab buttons */
|
||||
--color-urge-100: #0054bc;
|
||||
--color-urge-50: #00169a;
|
||||
--color-urge-000: #050076;
|
||||
|
||||
--color-info-900: #f5f3ff;
|
||||
--color-info-800: #ede9fe;
|
||||
--color-info-700: #ddd6fe;
|
||||
--color-info-600: #c4b5fd;
|
||||
--color-info-500: #a78bfa;
|
||||
--color-info-400: #8b5cf6;
|
||||
--color-info-300: #7c3aed;
|
||||
--color-info-200: #6d28d9;
|
||||
--color-info-100: #5b21b6;
|
||||
--color-info-50: #4c1d95;
|
||||
--color-info-000: #240e44;
|
||||
|
||||
|
||||
--color-neutral-normal-content: #ffffff;
|
||||
}
|
||||
|
||||
.light-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dark-only {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.dark-theme select option {
|
||||
background: #202020;
|
||||
}
|
351
css/dark.js
Normal file
351
css/dark.js
Normal file
@ -0,0 +1,351 @@
|
||||
var c = {
|
||||
inherit: 'inherit',
|
||||
current: 'currentColor',
|
||||
transparent: 'transparent',
|
||||
black: '#000',
|
||||
white: '#fff',
|
||||
d_neutral: {
|
||||
900: "rgba(255, 255, 255, 0.87)",
|
||||
800: "rgba(255, 255, 255, 0.8)",
|
||||
700: "rgba(255, 255, 255, 0.73)",
|
||||
600: "rgba(255, 255, 255, 0.66)",
|
||||
500: "rgb(153, 153, 153)",
|
||||
400: "#383838",
|
||||
300: "#303030",
|
||||
200: "#292929",
|
||||
100: "#242424",
|
||||
50: "#202020",
|
||||
000: "#101010"
|
||||
},
|
||||
d_critical: {
|
||||
900: "#fef2f2",
|
||||
800: "#fee2e2",
|
||||
700: "#fecaca",
|
||||
600: "#fca5a5",
|
||||
500: "#f87171",
|
||||
400: "#ef4444",
|
||||
300: "#dc2626",
|
||||
200: "#b91c1c",
|
||||
100: "#991b1b",
|
||||
50: "#7f1d1d",
|
||||
000: "#441313"
|
||||
},
|
||||
d_warning: {
|
||||
900: "#fffbeb",
|
||||
800: "#fef3c7",
|
||||
700: "#fde68a",
|
||||
600: "#fcd34d",
|
||||
500: "#fbbf24",
|
||||
400: "#f59e0b",
|
||||
300: "#d97706",
|
||||
200: "#b45309",
|
||||
100: "#92400e",
|
||||
50: "#783900",
|
||||
000: "#411e01"
|
||||
},
|
||||
d_positive: {
|
||||
900: "#f0fdf4",
|
||||
800: "#dcfce7",
|
||||
700: "#bbf7d0",
|
||||
600: "#86efac",
|
||||
500: "#4ade80",
|
||||
400: "#22c55e",
|
||||
300: "#16a34a",
|
||||
200: "#15803d",
|
||||
100: "#166534",
|
||||
50: "#14532d",
|
||||
000: "#0f2e1b"
|
||||
},
|
||||
d_urge: {
|
||||
900: "#e0ffff",
|
||||
800: "#c0fbff",
|
||||
700: "#a0f4ff",
|
||||
600: "#80e9ff",
|
||||
500: "#60dbfb",
|
||||
400: "#40cbf3",
|
||||
300: "#20b9e9",
|
||||
200: "#00a4dc",
|
||||
100: "#0054bc",
|
||||
50: "#00169a",
|
||||
000: "#050076"
|
||||
},
|
||||
d_info: {
|
||||
900: "#f5f3ff",
|
||||
800: "#ede9fe",
|
||||
700: "#ddd6fe",
|
||||
600: "#c4b5fd",
|
||||
500: "#a78bfa",
|
||||
400: "#8b5cf6",
|
||||
300: "#7c3aed",
|
||||
200: "#6d28d9",
|
||||
100: "#5b21b6",
|
||||
50: "#4c1d95",
|
||||
000: "#240e44"
|
||||
},
|
||||
slate: {
|
||||
50: '#f8fafc',
|
||||
100: '#f1f5f9',
|
||||
200: '#e2e8f0',
|
||||
300: '#cbd5e1',
|
||||
400: '#94a3b8',
|
||||
500: '#64748b',
|
||||
600: '#475569',
|
||||
700: '#334155',
|
||||
800: '#1e293b',
|
||||
900: '#0f172a'
|
||||
},
|
||||
gray: {
|
||||
50: '#f9fafb',
|
||||
100: '#f3f4f6',
|
||||
200: '#e5e7eb',
|
||||
300: '#d1d5db',
|
||||
400: '#9ca3af',
|
||||
500: '#6b7280',
|
||||
600: '#4b5563',
|
||||
700: '#374151',
|
||||
800: '#1f2937',
|
||||
900: '#111827'
|
||||
},
|
||||
zinc: {
|
||||
50: '#fafafa',
|
||||
100: '#f4f4f5',
|
||||
200: '#e4e4e7',
|
||||
300: '#d4d4d8',
|
||||
400: '#a1a1aa',
|
||||
500: '#71717a',
|
||||
600: '#52525b',
|
||||
700: '#3f3f46',
|
||||
800: '#27272a',
|
||||
900: '#18181b'
|
||||
},
|
||||
neutral: {
|
||||
50: '#fafafa',
|
||||
100: '#f5f5f5',
|
||||
200: '#e5e5e5',
|
||||
300: '#d4d4d4',
|
||||
400: '#a3a3a3',
|
||||
500: '#737373',
|
||||
600: '#525252',
|
||||
700: '#404040',
|
||||
800: '#262626',
|
||||
900: '#171717'
|
||||
},
|
||||
stone: {
|
||||
50: '#fafaf9',
|
||||
100: '#f5f5f4',
|
||||
200: '#e7e5e4',
|
||||
300: '#d6d3d1',
|
||||
400: '#a8a29e',
|
||||
500: '#78716c',
|
||||
600: '#57534e',
|
||||
700: '#44403c',
|
||||
800: '#292524',
|
||||
900: '#1c1917'
|
||||
},
|
||||
red: {
|
||||
50: '#fef2f2',
|
||||
100: '#fee2e2',
|
||||
200: '#fecaca',
|
||||
300: '#fca5a5',
|
||||
400: '#f87171',
|
||||
500: '#ef4444',
|
||||
600: '#dc2626',
|
||||
700: '#b91c1c',
|
||||
800: '#991b1b',
|
||||
900: '#7f1d1d'
|
||||
},
|
||||
orange: {
|
||||
50: '#fff7ed',
|
||||
100: '#ffedd5',
|
||||
200: '#fed7aa',
|
||||
300: '#fdba74',
|
||||
400: '#fb923c',
|
||||
500: '#f97316',
|
||||
600: '#ea580c',
|
||||
700: '#c2410c',
|
||||
800: '#9a3412',
|
||||
900: '#7c2d12'
|
||||
},
|
||||
amber: {
|
||||
50: '#fffbeb',
|
||||
100: '#fef3c7',
|
||||
200: '#fde68a',
|
||||
300: '#fcd34d',
|
||||
400: '#fbbf24',
|
||||
500: '#f59e0b',
|
||||
600: '#d97706',
|
||||
700: '#b45309',
|
||||
800: '#92400e',
|
||||
900: '#78350f'
|
||||
},
|
||||
yellow: {
|
||||
50: '#fefce8',
|
||||
100: '#fef9c3',
|
||||
200: '#fef08a',
|
||||
300: '#fde047',
|
||||
400: '#facc15',
|
||||
500: '#eab308',
|
||||
600: '#ca8a04',
|
||||
700: '#a16207',
|
||||
800: '#854d0e',
|
||||
900: '#713f12'
|
||||
},
|
||||
lime: {
|
||||
50: '#f7fee7',
|
||||
100: '#ecfccb',
|
||||
200: '#d9f99d',
|
||||
300: '#bef264',
|
||||
400: '#a3e635',
|
||||
500: '#84cc16',
|
||||
600: '#65a30d',
|
||||
700: '#4d7c0f',
|
||||
800: '#3f6212',
|
||||
900: '#365314'
|
||||
},
|
||||
green: {
|
||||
50: '#f0fdf4',
|
||||
100: '#dcfce7',
|
||||
200: '#bbf7d0',
|
||||
300: '#86efac',
|
||||
400: '#4ade80',
|
||||
500: '#22c55e',
|
||||
600: '#16a34a',
|
||||
700: '#15803d',
|
||||
800: '#166534',
|
||||
900: '#14532d'
|
||||
},
|
||||
emerald: {
|
||||
50: '#ecfdf5',
|
||||
100: '#d1fae5',
|
||||
200: '#a7f3d0',
|
||||
300: '#6ee7b7',
|
||||
400: '#34d399',
|
||||
500: '#10b981',
|
||||
600: '#059669',
|
||||
700: '#047857',
|
||||
800: '#065f46',
|
||||
900: '#064e3b'
|
||||
},
|
||||
teal: {
|
||||
50: '#f0fdfa',
|
||||
100: '#ccfbf1',
|
||||
200: '#99f6e4',
|
||||
300: '#5eead4',
|
||||
400: '#2dd4bf',
|
||||
500: '#14b8a6',
|
||||
600: '#0d9488',
|
||||
700: '#0f766e',
|
||||
800: '#115e59',
|
||||
900: '#134e4a'
|
||||
},
|
||||
cyan: {
|
||||
50: '#ecfeff',
|
||||
100: '#cffafe',
|
||||
200: '#a5f3fc',
|
||||
300: '#67e8f9',
|
||||
400: '#22d3ee',
|
||||
500: '#06b6d4',
|
||||
600: '#0891b2',
|
||||
700: '#0e7490',
|
||||
800: '#155e75',
|
||||
900: '#164e63'
|
||||
},
|
||||
sky: {
|
||||
50: '#f0f9ff',
|
||||
100: '#e0f2fe',
|
||||
200: '#bae6fd',
|
||||
300: '#7dd3fc',
|
||||
400: '#38bdf8',
|
||||
500: '#0ea5e9',
|
||||
600: '#0284c7',
|
||||
700: '#0369a1',
|
||||
800: '#075985',
|
||||
900: '#0c4a6e'
|
||||
},
|
||||
blue: {
|
||||
50: '#eff6ff',
|
||||
100: '#dbeafe',
|
||||
200: '#bfdbfe',
|
||||
300: '#93c5fd',
|
||||
400: '#60a5fa',
|
||||
500: '#3b82f6',
|
||||
600: '#2563eb',
|
||||
700: '#1d4ed8',
|
||||
800: '#1e40af',
|
||||
900: '#1e3a8a'
|
||||
},
|
||||
indigo: {
|
||||
50: '#eef2ff',
|
||||
100: '#e0e7ff',
|
||||
200: '#c7d2fe',
|
||||
300: '#a5b4fc',
|
||||
400: '#818cf8',
|
||||
500: '#6366f1',
|
||||
600: '#4f46e5',
|
||||
700: '#4338ca',
|
||||
800: '#3730a3',
|
||||
900: '#312e81'
|
||||
},
|
||||
violet: {
|
||||
50: '#f5f3ff',
|
||||
100: '#ede9fe',
|
||||
200: '#ddd6fe',
|
||||
300: '#c4b5fd',
|
||||
400: '#a78bfa',
|
||||
500: '#8b5cf6',
|
||||
600: '#7c3aed',
|
||||
700: '#6d28d9',
|
||||
800: '#5b21b6',
|
||||
900: '#4c1d95'
|
||||
},
|
||||
purple: {
|
||||
50: '#faf5ff',
|
||||
100: '#f3e8ff',
|
||||
200: '#e9d5ff',
|
||||
300: '#d8b4fe',
|
||||
400: '#c084fc',
|
||||
500: '#a855f7',
|
||||
600: '#9333ea',
|
||||
700: '#7e22ce',
|
||||
800: '#6b21a8',
|
||||
900: '#581c87'
|
||||
},
|
||||
fuchsia: {
|
||||
50: '#fdf4ff',
|
||||
100: '#fae8ff',
|
||||
200: '#f5d0fe',
|
||||
300: '#f0abfc',
|
||||
400: '#e879f9',
|
||||
500: '#d946ef',
|
||||
600: '#c026d3',
|
||||
700: '#a21caf',
|
||||
800: '#86198f',
|
||||
900: '#701a75'
|
||||
},
|
||||
pink: {
|
||||
50: '#fdf2f8',
|
||||
100: '#fce7f3',
|
||||
200: '#fbcfe8',
|
||||
300: '#f9a8d4',
|
||||
400: '#f472b6',
|
||||
500: '#ec4899',
|
||||
600: '#db2777',
|
||||
700: '#be185d',
|
||||
800: '#9d174d',
|
||||
900: '#831843'
|
||||
},
|
||||
rose: {
|
||||
50: '#fff1f2',
|
||||
100: '#ffe4e6',
|
||||
200: '#fecdd3',
|
||||
300: '#fda4af',
|
||||
400: '#fb7185',
|
||||
500: '#f43f5e',
|
||||
600: '#e11d48',
|
||||
700: '#be123c',
|
||||
800: '#9f1239',
|
||||
900: '#881337'
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = c;
|
@ -1,6 +1,6 @@
|
||||
.loader {
|
||||
height: auto;
|
||||
color: rgba(0, 0, 0, 0);
|
||||
color: rgba(0, 0, 0, 0) !important;
|
||||
}
|
||||
|
||||
.loader .dot {
|
||||
|
3
go.mod
3
go.mod
@ -14,6 +14,7 @@ replace github.com/hrfee/jfa-go/linecache => ./linecache
|
||||
|
||||
require (
|
||||
github.com/bwmarrin/discordgo v0.23.2
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
|
||||
github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
@ -49,7 +50,7 @@ require (
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2
|
||||
github.com/swaggo/gin-swagger v1.3.3
|
||||
github.com/swaggo/swag v1.7.6 // indirect
|
||||
github.com/swaggo/swag v1.7.8 // indirect
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.4 // indirect
|
||||
github.com/ugorji/go v1.2.6 // indirect
|
||||
|
8
go.sum
8
go.sum
@ -24,6 +24,8 @@ github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt
|
||||
github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -256,6 +258,8 @@ github.com/swaggo/swag v1.6.7/go.mod h1:xDhTyuFIujYiN3DKWC/H/83xcfHp+UE/IzWWampG
|
||||
github.com/swaggo/swag v1.7.4/go.mod h1:zD8h6h4SPv7t3l+4BKdRquqW1ASWjKZgT6Qv9z3kNqI=
|
||||
github.com/swaggo/swag v1.7.6 h1:UbAqHyXkW2J+cDjs5S43MkuYR7a6stB7Am7SK8NBmRg=
|
||||
github.com/swaggo/swag v1.7.6/go.mod h1:7vLqNYEtYoIsD14wXgy9oDS65MNiDANrPtbk9rnLuj0=
|
||||
github.com/swaggo/swag v1.7.8 h1:w249t0l/kc/DKMGlS0fppNJQxKyJ8heNaUWB6nsH3zc=
|
||||
github.com/swaggo/swag v1.7.8/go.mod h1:gZ+TJ2w/Ve1RwQsA2IRoSOTidHz6DX+PIG8GWvbnoLU=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
||||
github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
@ -288,6 +292,7 @@ github.com/writeas/go-strip-markdown v2.0.1+incompatible/go.mod h1:Rsyu10ZhbEK9p
|
||||
github.com/xhit/go-simple-mail/v2 v2.10.0 h1:nib6RaJ4qVh5HD9UE9QJqnUZyWp3upv+Z6CFxaMj0V8=
|
||||
github.com/xhit/go-simple-mail/v2 v2.10.0/go.mod h1:kA1XbQfCI4JxQ9ccSN6VFyIEkkugOm7YiPkA5hKiQn4=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
@ -301,6 +306,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -347,6 +353,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||
@ -366,6 +373,7 @@ golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
|
||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -7,10 +7,12 @@
|
||||
</head>
|
||||
<body class="section">
|
||||
<div class="page-container">
|
||||
<h1 class="heading">Page not found.</h1>
|
||||
<p class="content">
|
||||
{{ .contactMessage }}
|
||||
</p>
|
||||
<div class="card">
|
||||
<h1 class="heading">Page not found.</h1>
|
||||
<p class="content">
|
||||
{{ .contactMessage }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
382
html/admin.html
382
html/admin.html
@ -22,23 +22,23 @@
|
||||
<div id="modal-login" class="modal">
|
||||
<form class="modal-content card" id="form-login" href="">
|
||||
<span class="heading">{{ .strings.login }}</span>
|
||||
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="login-user">
|
||||
<input type="password" class="field input ~neutral !high mb-1" placeholder="{{ .strings.password }}" id="login-password">
|
||||
<input type="text" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.username }}" id="login-user">
|
||||
<input type="password" class="field input ~neutral @high mb-4" placeholder="{{ .strings.password }}" id="login-password">
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.login }}</span>
|
||||
<span class="button ~urge @low full-width center supra submit">{{ .strings.login }}</span>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
<div id="modal-add-user" class="modal">
|
||||
<form class="modal-content card" id="form-add-user" href="">
|
||||
<span class="heading">{{ .strings.newUser }} <span class="modal-close">×</span></span>
|
||||
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="add-user-user">
|
||||
<input type="email" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.emailAddress }}">
|
||||
<input type="password" class="field input ~neutral !high mb-1" placeholder="{{ .strings.password }}" id="add-user-password">
|
||||
<input type="text" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.username }}" id="add-user-user">
|
||||
<input type="email" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.emailAddress }}">
|
||||
<input type="password" class="field input ~neutral @high mb-4" placeholder="{{ .strings.password }}" id="add-user-password">
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.create }}</span>
|
||||
<span class="button ~urge @low full-width center supra submit">{{ .strings.create }}</span>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
@ -46,29 +46,29 @@
|
||||
<div class="modal-content content card">
|
||||
<img src="{{ .urlBase }}/banner.svg" class="banner header" alt="jfa-go banner">
|
||||
<span class="heading"><span class="modal-close">×</span></span>
|
||||
<p>{{ .strings.version }} <span class="code monospace">{{ .version }}</span></p>
|
||||
<p>{{ .strings.commitNoun }} <span class="code monospace">{{ .commit }}</span></p>
|
||||
<p>{{ .strings.version }} <span class="code font-mono bg-inherit">{{ .version }}</span></p>
|
||||
<p>{{ .strings.commitNoun }} <span class="code font-mono bg-inherit">{{ .commit }}</span></p>
|
||||
<div class="row col flex">
|
||||
<a class="button ~neutral mr-half mt-1 mb-1 lang-link" href="https://github.com/hrfee/jfa-go"><i class="ri-github-line mr-half"></i>github</a>
|
||||
<a class="button ~urge mt-1 mb-1 mr-half lang-link" href="https://wiki.jfa-go.com">wiki/docs</a>
|
||||
<a class="button ~positive mt-1 mb-1 mr-half lang-link" href="https://weblate.jfa-go.com">translation</a>
|
||||
<div class="dropdown mr-half" tabindex="0">
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button ~info mt-1 mb-1 dropdown-button lang-link">
|
||||
<i class="ri-hand-heart-line mr-half"></i>
|
||||
<a class="button ~neutral mr-2 mt-4 mb-4 lang-link" href="https://github.com/hrfee/jfa-go"><i class="ri-github-line mr-2"></i>github</a>
|
||||
<a class="button ~urge mt-4 mb-4 mr-2 lang-link" href="https://wiki.jfa-go.com">wiki/docs</a>
|
||||
<a class="button ~positive mt-4 mb-4 mr-2 lang-link" href="https://weblate.jfa-go.com">translation</a>
|
||||
<div class="dropdown mr-2" tabindex="0">
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button ~info mt-4 mb-4 dropdown-button lang-link">
|
||||
<i class="ri-hand-heart-line mr-2"></i>
|
||||
donate
|
||||
<span class="ml-1 chev"></span>
|
||||
<span class="ml-2 chev"></span>
|
||||
</a>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~info !low">
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button input ~neutral field mb-half lang-link">GitHub</a>
|
||||
<a href="https://ko-fi.com/hrfee" target="_blank" class="button input ~neutral field mb-half lang-link">Ko-fi</a>
|
||||
<div class="card ~neutral @low">
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button input ~neutral field mb-2 lang-link">GitHub</a>
|
||||
<a href="https://ko-fi.com/hrfee" target="_blank" class="button input ~neutral field mb-2 lang-link">Ko-fi</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="button ~urge mt-1 mb-1 !normal discord lang-link" href="https://discord.com/invite/MrtvuQmyhP" target="_blank"><i class="ri-discord-line mr-half"></i>discord</a>
|
||||
<a class="button ~urge mt-4 mb-4 @low discord lang-link" href="https://discord.com/invite/MrtvuQmyhP" target="_blank"><i class="ri-discord-line mr-2"></i>discord</a>
|
||||
</div>
|
||||
<p><a href="https://github.com/hrfee/jfa-go/blob/main/LICENSE">Available under the MIT License.</a></p>
|
||||
<pre class="monospace">{{ .license }}</pre>
|
||||
<pre class="font-mono bg-inherit">{{ .license }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal-logs" class="modal">
|
||||
@ -80,45 +80,45 @@
|
||||
<div id="modal-modify-user" class="modal">
|
||||
<form class="modal-content card" id="form-modify-user" href="">
|
||||
<span class="heading"><span id="header-modify-user"></span> <span class="modal-close">×</span></span>
|
||||
<p class="content">{{ .strings.modifySettingsDescription }}</p>
|
||||
<div class="flex-row mb-1">
|
||||
<label class="flex-row-group mr-1">
|
||||
<p class="content my-4">{{ .strings.modifySettingsDescription }}</p>
|
||||
<div class="flex-row mb-4">
|
||||
<label class="flex-row-group mr-2">
|
||||
<input type="radio" name="modify-user-source" class="unfocused" id="radio-use-profile" checked>
|
||||
<span class="button ~neutral !high supra full-width center">{{ .strings.profile }}</span>
|
||||
<span class="button ~neutral @high supra full-width center">{{ .strings.profile }}</span>
|
||||
</label>
|
||||
<label class="flex-row-group ml-1">
|
||||
<label class="flex-row-group ml-2">
|
||||
<input type="radio" name="modify-user-source" class="unfocused" id="radio-use-user">
|
||||
<span class="button ~neutral !normal supra full-width center">{{ .strings.user }}</span>
|
||||
<span class="button ~neutral @low supra full-width center">{{ .strings.user }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="select ~neutral !normal mb-1">
|
||||
<div class="select ~neutral @low mb-4">
|
||||
<select id="modify-user-profiles"></select>
|
||||
</div>
|
||||
<div class="select ~neutral !normal mb-1 unfocused">
|
||||
<div class="select ~neutral @low mb-4 unfocused">
|
||||
<select id="modify-user-users"></select>
|
||||
</div>
|
||||
<label class="switch mb-1">
|
||||
<label class="switch mb-4">
|
||||
<input type="checkbox" id="modify-user-homescreen" checked>
|
||||
<span>{{ .strings.applyHomescreenLayout }}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.apply }}</span>
|
||||
<span class="button ~urge @low full-width center supra submit">{{ .strings.apply }}</span>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
<div id="modal-delete-user" class="modal">
|
||||
<form class="modal-content card" id="form-delete-user" href="">
|
||||
<span class="heading"><span id="header-delete-user"></span> <span class="modal-close">×</span></span>
|
||||
<div class="content mt-half">
|
||||
<label class="switch mb-1">
|
||||
<div class="content mt-8">
|
||||
<label class="switch mb-4">
|
||||
<input type="checkbox" id="delete-user-notify" checked>
|
||||
<span>{{ .strings.sendDeleteNotificationEmail }}</span>
|
||||
</label>
|
||||
<textarea id="textarea-delete-user" class="textarea full-width ~neutral !normal mb-1" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
|
||||
<textarea id="textarea-delete-user" class="textarea full-width ~neutral @low mb-4" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~critical !normal full-width center supra submit">{{ .strings.delete }}</span>
|
||||
<span class="button ~critical @low full-width center supra submit">{{ .strings.delete }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
@ -126,11 +126,11 @@
|
||||
<div id="modal-extend-expiry" class="modal">
|
||||
<form class="modal-content card" id="form-extend-expiry" href="">
|
||||
<span class="heading"><span id="header-extend-expiry"></span> <span class="modal-close">×</span></span>
|
||||
<div class="content mt-half">
|
||||
<div class="content mt-8">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label supra" for="extend-expiry-months">{{ .strings.inviteMonths }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="extend-expiry-months">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -138,7 +138,7 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="label supra" for="extend-expiry-days">{{ .strings.inviteDays }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="extend-expiry-days">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -148,7 +148,7 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label supra" for="extend-expiry-hours">{{ .strings.inviteHours }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="extend-expiry-hours">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -156,21 +156,21 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="label supra" for="extend-expiry-minutes">{{ .strings.inviteMinutes }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="extend-expiry-minutes">
|
||||
<option>0</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label class="switch mb-1">
|
||||
<label class="switch mb-4">
|
||||
<input type="checkbox" id="expiry-extend-enable" checked>
|
||||
<span>{{ .strings.sendDeleteNotificationEmail }}</span>
|
||||
</label>
|
||||
<textarea id="textarea-extend-enable" class="textarea full-width ~neutral !normal mb-1" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
|
||||
<textarea id="textarea-extend-enable" class="textarea full-width ~neutral @low mb-4" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~critical !normal full-width center supra submit">{{ .strings.submit }}</span>
|
||||
<span class="button ~critical @low full-width center supra submit">{{ .strings.submit }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
@ -179,33 +179,33 @@
|
||||
<form class="modal-content wide card" id="form-announce" href="">
|
||||
<span class="heading"><span id="header-announce"></span> <span class="modal-close">×</span></span>
|
||||
<div class="row">
|
||||
<div class="col flex-col content mt-half">
|
||||
<div class="col card ~neutral @low">
|
||||
<div id="announce-details">
|
||||
<span class="label supra" for="editor-variables" id="label-editor-variables">{{ .strings.variables }}</span>
|
||||
<div id="announce-variables">
|
||||
<span class="button ~urge !normal mb-1 mt-half" id="announce-variables-username" style="margin-left: 0.25rem; margin-right: 0.25rem;"><span class="monospace">{username}</span></span>
|
||||
<span class="button ~urge @low mb-2 mt-4" id="announce-variables-username" style="margin-left: 0.25rem; margin-right: 0.25rem;"><span class="font-mono bg-inherit">{username}</span></span>
|
||||
</div>
|
||||
<label class="label supra" for="announce-subject"> {{ .strings.subject }}</label>
|
||||
<input type="text" id="announce-subject" class="input ~neutral !normal mb-1 mt-half">
|
||||
<input type="text" id="announce-subject" class="input ~neutral @low mb-2 mt-4">
|
||||
<label class="label supra" for="textarea-announce">{{ .strings.message }}</label>
|
||||
<textarea id="textarea-announce" class="textarea full-width ~neutral !normal mt-half monospace"></textarea>
|
||||
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>
|
||||
<textarea id="textarea-announce" class="textarea full-width ~neutral @low mt-4 font-mono"></textarea>
|
||||
<p class="support mt-4 mb-2">{{ .strings.markdownSupported }}</p>
|
||||
</div>
|
||||
<label class="label unfocused" id="announce-name"><p class="supra">{{ .strings.name }}</p>
|
||||
<input type="text" class="input ~neutral !normal mb-1 mt-half">
|
||||
<input type="text" class="input ~neutral @low mb-2 mt-4">
|
||||
<p class="support">{{ .strings.templateEnterName }}</p>
|
||||
</label>
|
||||
<div class="row flex-expand">
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal center supra submit">{{ .strings.send }}</span>
|
||||
<span class="button ~urge @low center supra submit">{{ .strings.send }}</span>
|
||||
</label>
|
||||
<span class="button ~info !normal center supra" id="save-announce">{{ .strings.saveAsTemplate }}</span>
|
||||
<span class="button ~info @low center supra" id="save-announce">{{ .strings.saveAsTemplate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col card ~neutral !low">
|
||||
<div class="col card ~neutral @low">
|
||||
<span class="subheading supra">{{ .strings.preview }}</span>
|
||||
<div class="mt-half" id="announce-preview"></div>
|
||||
<div class="mt-8" id="announce-preview"></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -213,13 +213,13 @@
|
||||
<div id="modal-customize" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading">{{ .strings.customizeMessages }} <span class="modal-close">×</span></span>
|
||||
<p class="content">{{ .strings.customizeMessagesDescription }}</p>
|
||||
<p class="content my-4">{{ .strings.customizeMessagesDescription }}</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ .strings.name }}</th>
|
||||
<th>{{ .strings.reset }}</th>
|
||||
<th class="table-inline justify-center">{{ .strings.reset }}</th>
|
||||
<th>{{ .strings.edit }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -232,68 +232,68 @@
|
||||
<form class="modal-content wide card" id="form-editor" href="">
|
||||
<span class="heading"><span id="header-editor"></span> <span class="modal-close">×</span></span>
|
||||
<div class="row">
|
||||
<div class="col flex-col content mt-half">
|
||||
<div class="col card ~neutral @low">
|
||||
<span class="label supra" for="editor-variables" id="label-editor-variables">{{ .strings.variables }}</span>
|
||||
<div id="editor-variables"></div>
|
||||
<div id="editor-variables" class="mt-4"></div>
|
||||
<span class="label supra" for="editor-conditionals" id="label-editor-conditionals">{{ .strings.conditionals }}</span>
|
||||
<div id="editor-conditionals"></div>
|
||||
<label class="label supra" for="textarea-editor">{{ .strings.message }}</label>
|
||||
<textarea id="textarea-editor" class="textarea full-width flex-auto ~neutral !normal mt-half monospace"></textarea>
|
||||
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>
|
||||
<textarea id="textarea-editor" class="textarea full-width flex-auto ~neutral @low mt-4 font-mono"></textarea>
|
||||
<p class="support mt-4 mb-2">{{ .strings.markdownSupported }}</p>
|
||||
<div class="flex-row">
|
||||
<label class="full-width ml-half">
|
||||
<label class="full-width ml-2">
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
|
||||
<span class="button ~urge @low full-width center supra submit">{{ .strings.submit }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col card ~neutral !low">
|
||||
<div class="col card ~neutral @low">
|
||||
<span class="subheading supra">{{ .strings.preview }}</span>
|
||||
<div class="mt-half" id="editor-preview"></div>
|
||||
<div class="mt-8" id="editor-preview"></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id="modal-restart" class="modal">
|
||||
<div class="modal-content card ~critical !low">
|
||||
<div class="modal-content card ~critical @low">
|
||||
<span class="heading">{{ .strings.settingsRestartRequired }} <span class="modal-close">×</span></span>
|
||||
<p class="content pb-1">{{ .strings.settingsRestartRequiredDescription }}</p>
|
||||
<div class="fr">
|
||||
<span class="button ~info !normal mb-half" id="settings-apply-no-restart">{{ .strings.settingsApplyRestartLater }}</span>
|
||||
<span class="button ~critical !normal" id="settings-apply-restart">{{ .strings.settingsApplyRestartNow }}</span>
|
||||
<p class="content my-4">{{ .strings.settingsRestartRequiredDescription }}</p>
|
||||
<div class="float-right">
|
||||
<span class="button ~info @low mb-2" id="settings-apply-no-restart">{{ .strings.settingsApplyRestartLater }}</span>
|
||||
<span class="button ~critical @low" id="settings-apply-restart">{{ .strings.settingsApplyRestartNow }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal-refresh" class="modal">
|
||||
<div class="modal-content card ~neutral !normal">
|
||||
<div class="modal-content card ~neutral @low">
|
||||
<span class="heading">{{ .strings.settingsApplied }}</span>
|
||||
<p class="content">{{ .strings.settingsRefreshPage }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal-send-pwr" class="modal">
|
||||
<div class="modal-content card ~neutral !normal">
|
||||
<div class="modal-content card ~neutral @low">
|
||||
<span class="heading">{{ .strings.sendPWR }}</span>
|
||||
<p class="content" id="send-pwr-note"></p>
|
||||
<span class="button ~urge !normal mt-half" id="send-pwr-link">{{ .strings.copy }}</span>
|
||||
<p class="content my-2" id="send-pwr-note"></p>
|
||||
<span class="button ~urge @low mt-2" id="send-pwr-link">{{ .strings.copy }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal-ombi-profile" class="modal">
|
||||
<form class="modal-content card" id="form-ombi-defaults" href="">
|
||||
<span class="heading">{{ .strings.ombiProfile }} <span class="modal-close">×</span></span>
|
||||
<p class="content">{{ .strings.ombiUserDefaultsDescription }}</p>
|
||||
<div class="select ~neutral !normal mb-1">
|
||||
<p class="content my-4">{{ .strings.ombiUserDefaultsDescription }}</p>
|
||||
<div class="select ~neutral @low mb-4">
|
||||
<select></select>
|
||||
</div>
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
|
||||
<span class="button ~urge @low full-width center supra submit">{{ .strings.submit }}</span>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
<div id="modal-user-profiles" class="modal">
|
||||
<div class="modal-content wide card">
|
||||
<span class="heading">{{ .strings.userProfiles }} <span class="modal-close">×</span></span>
|
||||
<p class="support lg">{{ .strings.userProfilesDescription }}</p>
|
||||
<p class="content my-4">{{ .strings.userProfilesDescription }}</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
@ -305,7 +305,7 @@
|
||||
{{ end }}
|
||||
<th>{{ .strings.from }}</th>
|
||||
<th>{{ .strings.userProfilesLibraries }}</th>
|
||||
<th><span class="button ~neutral !high" id="button-profile-create">{{ .strings.create }}</span></th>
|
||||
<th><span class="button ~neutral @high" id="button-profile-create">{{ .strings.create }}</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="table-profiles"></tbody>
|
||||
@ -316,23 +316,23 @@
|
||||
<div id="modal-add-profile" class="modal">
|
||||
<form class="modal-content card" id="form-add-profile" href="">
|
||||
<span class="heading">{{ .strings.addProfile }} <span class="modal-close">×</span></span>
|
||||
<p class="content">{{ .strings.addProfileDescription }}</p>
|
||||
<p class="content my-4">{{ .strings.addProfileDescription }}</p>
|
||||
<label>
|
||||
<span class="supra">{{ .strings.addProfileNameOf }} </span>
|
||||
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.name }}" id="add-profile-name">
|
||||
<input type="text" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.name }}" id="add-profile-name">
|
||||
<label>
|
||||
<span class="supra">{{ .strings.user }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<div class="select ~neutral @low mt-4 mb-2">
|
||||
<select id="add-profile-user"></select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="switch mb-1">
|
||||
<label class="switch mb-4">
|
||||
<input type="checkbox" id="add-profile-homescreen" checked>
|
||||
<span>{{ .strings.addProfileStoreHomescreenLayout }}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.create }}</span>
|
||||
<span class="button ~urge @low full-width center supra submit">{{ .strings.create }}</span>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
@ -341,41 +341,41 @@
|
||||
<span class="heading">{{ .strings.updates }} <span class="modal-close">×</span></span>
|
||||
<p class="content">
|
||||
<h2>
|
||||
<a id="update-version"></a> (<span class="monospace" id="update-commit"></span>)
|
||||
<a id="update-version"></a> (<span class="font-mono bg-inherit" id="update-commit"></span>)
|
||||
</h2>
|
||||
<p class="content" id="update-description"></p>
|
||||
<p class="support" id="update-date"></p>
|
||||
<div class="content markdown-box" id="update-changelog"></div>
|
||||
</p>
|
||||
<span class="button ~info !normal full-width center" id="update-download">{{ .strings.download }}</span>
|
||||
<span class="button ~urge !normal full-width center" id="update-update">{{ .strings.update }}</span>
|
||||
<span class="button ~info @low full-width center" id="update-download">{{ .strings.download }}</span>
|
||||
<span class="button ~urge @low full-width center" id="update-update">{{ .strings.update }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ if .telegramEnabled }}
|
||||
<div id="modal-telegram" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1">{{ .strings.linkTelegram }}</span>
|
||||
<p class="content mb-1">{{ .strings.sendPIN }}</p>
|
||||
<span class="heading mb-4">{{ .strings.linkTelegram }}</span>
|
||||
<p class="content mb-4">{{ .strings.sendPIN }}</p>
|
||||
<h1 class="ac" id="telegram-pin"></h1>
|
||||
<a class="subheading link-center" id="telegram-link" target="_blank">
|
||||
<span class="shield ~info mr-1">
|
||||
<span class="shield ~info mr-2">
|
||||
<span class="icon">
|
||||
<i class="ri-telegram-line"></i>
|
||||
</span>
|
||||
</span>
|
||||
@<span id="telegram-username">
|
||||
</a>
|
||||
<span class="button ~info !normal full-width center mt-1" id="telegram-waiting">{{ .strings.success }}</span>
|
||||
<span class="button ~info @low full-width center mt-4" id="telegram-waiting">{{ .strings.success }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<div id="modal-discord" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1"><span id="discord-header"></span><span class="modal-close">×</span></span>
|
||||
<p class="content mb-1" id="discord-description"></p>
|
||||
<span class="heading mb-4"><span id="discord-header"></span><span class="modal-close">×</span></span>
|
||||
<p class="content mb-4" id="discord-description"></p>
|
||||
<div class="row">
|
||||
<input type="search" class="col sm field ~neutral !normal input" id="discord-search" placeholder="user#1234">
|
||||
<input type="search" class="col sm field ~neutral @low input" id="discord-search" placeholder="user#1234">
|
||||
</div>
|
||||
<table class="table"><tbody id="discord-list"></tbody></table>
|
||||
</div>
|
||||
@ -384,76 +384,78 @@
|
||||
<div id="modal-matrix" class="modal">
|
||||
<form class="modal-content card" id="form-matrix" href="">
|
||||
<span class="heading">{{ .strings.linkMatrix }}</span>
|
||||
<p class="content">{{ .strings.linkMatrixDescription }}</p>
|
||||
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.matrixHomeServer }}" id="matrix-homeserver">
|
||||
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="matrix-user">
|
||||
<input type="password" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.password }}" id="matrix-password">
|
||||
<p class="content my-4">{{ .strings.linkMatrixDescription }}</p>
|
||||
<input type="text" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.matrixHomeServer }}" id="matrix-homeserver">
|
||||
<input type="text" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.username }}" id="matrix-user">
|
||||
<input type="password" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.password }}" id="matrix-password">
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
|
||||
<span class="button ~urge @low full-width center supra submit">{{ .strings.submit }}</span>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
<div id="notification-box"></div>
|
||||
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
||||
<span class="button ~urge dropdown-button">
|
||||
<i class="ri-global-line"></i>
|
||||
<span class="ml-1 chev"></span>
|
||||
</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral !low">
|
||||
<label class="switch pb-1">
|
||||
<input type="radio" name="lang-time" id="lang-12h">
|
||||
<span>{{ .strings.time12h }}</span>
|
||||
</label>
|
||||
<label class="switch pb-1">
|
||||
<input type="radio" name="lang-time" id="lang-24h">
|
||||
<span>{{ .strings.time24h }}</span>
|
||||
</label>
|
||||
<div id="lang-list"></div>
|
||||
<div class="top-4 left-4 absolute">
|
||||
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
||||
<span class="button ~urge dropdown-button">
|
||||
<i class="ri-global-line"></i>
|
||||
<span class="ml-2 chev"></span>
|
||||
</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<label class="switch pb-4">
|
||||
<input type="radio" name="lang-time" id="lang-12h">
|
||||
<span>{{ .strings.time12h }}</span>
|
||||
</label>
|
||||
<label class="switch pb-4">
|
||||
<input type="radio" name="lang-time" id="lang-24h">
|
||||
<span>{{ .strings.time24h }}</span>
|
||||
</label>
|
||||
<div id="lang-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="button ~warning" alt="{{ .strings.theme }}" id="button-theme"><i class="ri-sun-line"></i></span>
|
||||
</span>
|
||||
<span class="button ~warning" alt="{{ .strings.theme }}" id="button-theme"><i class="ri-sun-line"></i></span>
|
||||
</div>
|
||||
<div class="page-container">
|
||||
<div class="mb-1">
|
||||
<div class="mb-4">
|
||||
<header class="flex flex-wrap items-center justify-between">
|
||||
<div class="text-neutral-700">
|
||||
<span id="button-tab-invites" class="tab-button portal">{{ .strings.invites }}</span>
|
||||
<span id="button-tab-accounts" class="tab-button portal">{{ .strings.accounts }}</span>
|
||||
<span id="button-tab-settings" class="tab-button portal">{{ .strings.settings }}</span>
|
||||
<div>
|
||||
<span id="button-tab-invites" class="text-3xl button portal ~neutral dark:~d_neutral @low mr-2 px-5">{{ .strings.invites }}</span>
|
||||
<span id="button-tab-accounts" class="text-3xl button portal ~neutral dark:~d_neutral @low mr-2 px-5">{{ .strings.accounts }}</span>
|
||||
<span id="button-tab-settings" class="text-3xl button portal ~neutral dark:~d_neutral @low mr-2 px-5">{{ .strings.settings }}</span>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<div class="text-neutral-700">
|
||||
<span class="button ~critical !normal mb-1 unfocused" id="logout-button">{{ .strings.logout }}</span>
|
||||
<div class="mb-4">
|
||||
<div>
|
||||
<span class="button ~critical @low mb-4 unfocused" id="logout-button">{{ .strings.logout }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab-invites">
|
||||
<div class="card ~neutral !low invites mb-1">
|
||||
<div class="card @low invites dark:~d_neutral mb-4">
|
||||
<span class="heading">{{ .strings.invites }}</span>
|
||||
<div id="invites"></div>
|
||||
</div>
|
||||
<div class="card ~neutral !low">
|
||||
<div class="card @low dark:~d_neutral">
|
||||
<span class="heading">{{ .strings.create }}</span>
|
||||
<div class="row" id="create-inv">
|
||||
<div class="card ~neutral !normal col">
|
||||
<div class="row mb-1">
|
||||
<label class="col mr-1">
|
||||
<div class="card ~neutral @low col">
|
||||
<div class="row mb-2">
|
||||
<label class="col mr-2">
|
||||
<input type="radio" name="duration" class="unfocused" id="radio-inv-duration" checked>
|
||||
<span class="button ~neutral !high supra full-width center">{{ .strings.inviteDuration }}</span>
|
||||
<span class="button ~neutral @high supra full-width center">{{ .strings.inviteDuration }}</span>
|
||||
</label>
|
||||
<label class="col ml-1">
|
||||
<label class="col ml-2">
|
||||
<input type="radio" name="duration" class="unfocused" id="radio-user-expiry">
|
||||
<span class="button ~neutral !normal supra full-width center">{{ .strings.userExpiry }}</span>
|
||||
<span class="button ~neutral @low supra full-width center">{{ .strings.userExpiry }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="inv-duration">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label supra" for="create-months">{{ .strings.inviteMonths }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="create-months">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -461,7 +463,7 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="label supra" for="create-days">{{ .strings.inviteDays }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="create-days">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -471,7 +473,7 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label supra" for="create-hours">{{ .strings.inviteHours }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="create-hours">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -479,7 +481,7 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="label supra" for="create-minutes">{{ .strings.inviteMinutes }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="create-minutes">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -488,17 +490,17 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="user-expiry" class="unfocused">
|
||||
<p class="support">{{ .strings.userExpiryDescription }}</p>
|
||||
<div class="mb-half">
|
||||
<label for="create-user-expiry-enabled" class="button ~neutral !normal">
|
||||
<p class="support mb-2">{{ .strings.userExpiryDescription }}</p>
|
||||
<div class="mb-2">
|
||||
<label for="create-user-expiry-enabled" class="button ~neutral @low">
|
||||
<input type="checkbox" id="create-user-expiry-enabled" aria-label="User duration enabled">
|
||||
<span class="ml-half">{{ .strings.enabled }} </span>
|
||||
<span class="ml-2">{{ .strings.enabled }} </span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label supra" for="user-months">{{ .strings.inviteMonths }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="user-months">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -506,7 +508,7 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="label supra" for="user-days">{{ .strings.inviteDays }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="user-days">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -516,7 +518,7 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label supra" for="user-hours">{{ .strings.inviteHours }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="user-hours">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -524,7 +526,7 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="label supra" for="user-minutes">{{ .strings.inviteMinutes }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="user-minutes">
|
||||
<option>0</option>
|
||||
</select>
|
||||
@ -534,92 +536,92 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="label supra" for="create-label"> {{ .strings.label }}</label>
|
||||
<input type="text" id="create-label" class="input ~neutral !normal mb-1 mt-half">
|
||||
<input type="text" id="create-label" class="input ~neutral @low mb-2 mt-4">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card ~neutral !normal col">
|
||||
<div class="card ~neutral @low col">
|
||||
<label class="label supra" for="create-uses">{{ .strings.inviteNumberOfUses }}</label>
|
||||
<div class="flex-expand mb-1 mt-half">
|
||||
<input type="number" min="0" id="create-uses" class="input ~neutral !normal mr-1" value=1>
|
||||
<label for="create-inf-uses" class="button ~neutral !normal" title="Set uses to infinite">
|
||||
<span>∞</span>
|
||||
<div class="flex-expand mb-2 mt-4">
|
||||
<input type="number" min="0" id="create-uses" class="input ~neutral @low mr-2" value=1>
|
||||
<label for="create-inf-uses" class="button ~neutral @low" title="Set uses to infinite">
|
||||
<span>∞</span>
|
||||
<input type="checkbox" class="unfocused" id="create-inf-uses" aria-label="Set uses to infinite">
|
||||
</label>
|
||||
</div>
|
||||
<p class="support unfocused" id="create-inf-uses-warning"><span class="badge ~critical">{{ .strings.warning }}</span> {{ .strings.inviteInfiniteUsesWarning }}</p>
|
||||
<p class="support unfocused my-2" id="create-inf-uses-warning"><span class="badge ~critical">{{ .strings.warning }}</span> {{ .strings.inviteInfiniteUsesWarning }}</p>
|
||||
<label class="label supra">{{ .strings.profile }}</label>
|
||||
<div class="select ~neutral !normal mb-1 mt-half">
|
||||
<div class="select ~neutral @low mb-2 mt-4">
|
||||
<select id="create-profile">
|
||||
</select>
|
||||
</div>
|
||||
<div id="create-send-to-container">
|
||||
<label class="label supra">{{ .strings.inviteSendToEmail }}</label>
|
||||
<div class="flex-expand mb-1 mt-half">
|
||||
<div class="flex-expand mb-2 mt-4">
|
||||
{{ if .discordEnabled }}
|
||||
<input type="text" id="create-send-to" class="input ~neutral !normal mr-1" placeholder="example@example.com | user#1234">
|
||||
<span id="create-send-to-search" class="button ~neutral !normal mr-1">
|
||||
<input type="text" id="create-send-to" class="input ~neutral @low mr-2" placeholder="example@example.com | user#1234">
|
||||
<span id="create-send-to-search" class="button ~neutral @low mr-2">
|
||||
<i class="icon ri-search-2-line" title="{{ .strings.search }}"></i>
|
||||
</span>
|
||||
{{ else }}
|
||||
<input type="email" id="create-send-to" class="input ~neutral !normal mr-1" placeholder="example@example.com">
|
||||
<input type="email" id="create-send-to" class="input ~neutral @low mr-2" placeholder="example@example.com">
|
||||
{{ end }}
|
||||
<label for="create-send-to-enabled" class="button ~neutral !normal">
|
||||
<label for="create-send-to-enabled" class="button ~neutral @low">
|
||||
<input type="checkbox" id="create-send-to-enabled" aria-label="Send to address enabled">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<span class="button ~urge !normal supra full-width center lg" id="create-submit">{{ .strings.create }}</span>
|
||||
<span class="button ~urge @low supra full-width center lg" id="create-submit">{{ .strings.create }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab-accounts" class="unfocused">
|
||||
<div class="card ~neutral !low accounts mb-1">
|
||||
<div class="card @low dark:~d_neutral accounts mb-4">
|
||||
<div class="flex-expand row">
|
||||
<div class="row">
|
||||
<span class="heading mr-1 col sm">{{ .strings.accounts }}</span>
|
||||
<input type="search" class="col sm field ~neutral !normal input search ml-1 mr-1" id="accounts-search" placeholder="{{ .strings.search }}">
|
||||
<span class="text-3xl font-bold mr-2 col">{{ .strings.accounts }}</span>
|
||||
<input type="search" class="col sm field ~neutral @low input search ml-2 mr-2" id="accounts-search" placeholder="{{ .strings.search }}">
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col sm button ~neutral !normal center mb-half" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
||||
<div id="accounts-announce-dropdown" class="col sm dropdown" tabindex="0">
|
||||
<span class="h-100 sm button ~info !normal center mb-half" id="accounts-announce">{{ .strings.announce }}</span>
|
||||
<span class="col sm button ~neutral @low center mb-2" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
||||
<div id="accounts-announce-dropdown" class="col sm dropdown pb-0i" tabindex="0">
|
||||
<span class="h-100 sm button ~info @low center mb-2" id="accounts-announce">{{ .strings.announce }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral !low">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="supra sm">{{ .strings.templates }}</span>
|
||||
<div id="accounts-announce-templates"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col sm button ~urge !normal center mb-half" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
|
||||
<span class="col sm button ~warning !normal center mb-half" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
||||
<div id="accounts-disable-enable-dropdown" class="col sm dropdown manual" tabindex="0">
|
||||
<span class="h-100 sm button ~positive !normal center mb-half" id="accounts-disable-enable">{{ .strings.disable }}</span>
|
||||
<span class="col sm button ~urge @low center mb-2" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
|
||||
<span class="col sm button ~warning @low center mb-2" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
||||
<div id="accounts-disable-enable-dropdown" class="col sm dropdown manual pb-0i" tabindex="0">
|
||||
<span class="h-100 sm button ~positive @low center mb-2" id="accounts-disable-enable">{{ .strings.disable }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral !low">
|
||||
<span class="button ~neutral sm full-width accounts-announce-template-button" id="accounts-enable-expiry">{{ .strings.setExpiry }}</span>
|
||||
<div class="card ~neutral @low">
|
||||
<span class="button ~urge sm full-width accounts-announce-template-button" id="accounts-enable-expiry">{{ .strings.setExpiry }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col sm button ~info !normal center mb-half unfocused" id="accounts-send-pwr">{{ .strings.sendPWR }}</span>
|
||||
<span class="col sm button ~critical !normal center mb-half" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
|
||||
<span class="col sm button ~info @low center mb-2 unfocused" id="accounts-send-pwr">{{ .strings.sendPWR }}</span>
|
||||
<span class="col sm button ~critical @low center mb-2" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card ~neutral !normal accounts-header table-responsive mt-half">
|
||||
<table class="table">
|
||||
<div class="card @low accounts-header table-responsive mt-8">
|
||||
<table class="table text-base leading-4">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" value="" id="accounts-select-all"></th>
|
||||
<th>{{ .strings.username }}</th>
|
||||
<th class="table-inline my-2">{{ .strings.username }}</th>
|
||||
<th>{{ .strings.emailAddress }}</th>
|
||||
{{ if .telegramEnabled }}
|
||||
<th>Telegram</th>
|
||||
<th class="text-center-i">Telegram</th>
|
||||
{{ end }}
|
||||
{{ if .matrixEnabled }}
|
||||
<th>Matrix</th>
|
||||
<th class="text-center-i">Matrix</th>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<th>Discord</th>
|
||||
<th class="text-center-i">Discord</th>
|
||||
{{ end }}
|
||||
<th>{{ .strings.expiry }}</th>
|
||||
<th>{{ .strings.lastActiveTime }}</th>
|
||||
@ -631,28 +633,28 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab-settings" class="unfocused">
|
||||
<div class="card ~neutral !low settings overflow">
|
||||
<div class="card @low dark:~d_neutral settings overflow">
|
||||
<div class="flex-expand">
|
||||
<div class="flex-row">
|
||||
<span class="heading">{{ .strings.settings }}</span>
|
||||
<label for="settings-advanced-enabled" class="button ~neutral !normal ml-1">
|
||||
<label for="settings-advanced-enabled" class="button ~neutral @low ml-2">
|
||||
<input type="checkbox" id="settings-advanced-enabled" aria-label="Advanced settings enabled">
|
||||
<span class="ml-half">{{ .strings.advancedSettings }} </span>
|
||||
<span class="ml-2">{{ .strings.advancedSettings }} </span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<span class="button ~info !normal" id="settings-logs">{{ .strings.logs }}</span>
|
||||
<span class="button ~neutral !normal" id="settings-restart">{{ .strings.settingsRestart }}</span>
|
||||
<span class="button ~urge !normal unfocused" id="settings-save">{{ .strings.settingsSave }}</span>
|
||||
<span class="button ~info @low" id="settings-logs">{{ .strings.logs }}</span>
|
||||
<span class="button ~neutral @low" id="settings-restart">{{ .strings.settingsRestart }}</span>
|
||||
<span class="button ~urge @low unfocused" id="settings-save">{{ .strings.settingsSave }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="card ~neutral !normal col" id="settings-sidebar">
|
||||
<aside class="aside sm ~info mb-half" id="settings-message">Note: <span class="badge ~critical">*</span> indicates a required field, <span class="badge ~info">R</span> indicates changes require a restart.</aside>
|
||||
<span class="button ~neutral !low settings-section-button mb-half" id="setting-about"><span class="flex">{{ .strings.aboutProgram }} <i class="ri-information-line ml-half"></i></span></span>
|
||||
<span class="button ~neutral !low settings-section-button mb-half" id="setting-profiles"><span class="flex">{{ .strings.userProfiles }} <i class="ri-user-line ml-half"></i></span></span>
|
||||
<div class="card @low dark:~d_neutral col" id="settings-sidebar">
|
||||
<aside class="aside sm ~urge dark:~d_info mb-2 @low" id="settings-message">Note: <span class="badge ~critical">*</span> indicates a required field, <span class="badge ~info dark:~d_warning">R</span> indicates changes require a restart.</aside>
|
||||
<span class="button ~neutral @low settings-section-button justify-between mb-2" id="setting-about"><span class="flex">{{ .strings.aboutProgram }} <i class="ri-information-line ml-2"></i></span></span>
|
||||
<span class="button ~neutral @low settings-section-button justify-between mb-2" id="setting-profiles"><span class="flex">{{ .strings.userProfiles }} <i class="ri-user-line ml-2"></i></span></span>
|
||||
</div>
|
||||
<div class="card ~neutral !normal col overflow" id="settings-panel"></div>
|
||||
<div class="card ~neutral @low col overflow" id="settings-panel"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,41 +7,37 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card ~critical sectioned">
|
||||
<section class="section ~critical">
|
||||
<span class="heading">Crash report for jfa-go</span>
|
||||
{{ if .Err }}
|
||||
<div class="monospace pre-line mt-1 mb-1">
|
||||
Error: {{ .Err }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<a class="button ~critical mb-1" target="_blank" href="https://github.com/hrfee/jfa-go/issues/new/choose">Create an Issue</a>
|
||||
</section>
|
||||
<section class="section ~neutral !low">
|
||||
<div class="flex-expand">
|
||||
<span class="subheading">Full Log</span>
|
||||
<span class="button ~urge ml-half" id="copy-log">Copy</span>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col mr-1">
|
||||
<span class="button ~neutral !high supra full-width center" id="button-log-normal">Normal</span>
|
||||
</label>
|
||||
<label class="col mr-1">
|
||||
<span class="button ~neutral !normal supra full-width center" id="button-log-sanitized">Sanitized</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="log-normal">
|
||||
<pre class="monospace pre-line">{{ .Log }}</pre>
|
||||
</div>
|
||||
<div id="log-sanitized" class="unfocused">
|
||||
<p class="subheading">An attempt has been made to remove sensitive info, but make sure to check yourself.</p>
|
||||
<pre class="monospace pre-line">{{ .SanitizedLog }}</pre>
|
||||
</div>
|
||||
</section>
|
||||
<div class="card ~critical sectioned">
|
||||
<section class="section ~critical">
|
||||
<span class="heading">Crash report for jfa-go</span>
|
||||
{{ if .Err }}
|
||||
<div class="font-mono bg-inherit pre-line mt-4 mb-4">
|
||||
Error: {{ .Err }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<a class="button ~critical mb-4" target="_blank" href="https://github.com/hrfee/jfa-go/issues/new/choose">Create an Issue</a>
|
||||
</section>
|
||||
<section class="section ~neutral @low">
|
||||
<div class="flex-expand">
|
||||
<span class="subheading">Full Log</span>
|
||||
<span class="button ~urge ml-4" id="copy-log">Copy</span>
|
||||
</div>
|
||||
<div class="row mb-4">
|
||||
<label class="col mr-4">
|
||||
<span class="button ~neutral @high supra full-width center" id="button-log-normal">Normal</span>
|
||||
</label>
|
||||
<label class="col mr-4">
|
||||
<span class="button ~neutral @low supra full-width center" id="button-log-sanitized">Sanitized</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="log-normal">
|
||||
<pre class="font-mono bg-inherit pre-line">{{ .Log }}</pre>
|
||||
</div>
|
||||
<div id="log-sanitized" class="unfocused">
|
||||
<p class="subheading">An attempt has been made to remove sensitive info, but make sure to check yourself.</p>
|
||||
<pre class="font-mono bg-inherit pre-line">{{ .SanitizedLog }}</pre>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<script inline src="crash.js"></script>
|
||||
|
@ -3,14 +3,14 @@
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="css/bundle.css">
|
||||
{{ template "header.html" . }}
|
||||
<title>{{ .strings.successHeader }} - jfa-go</title>
|
||||
<title>{{ .strings.successHeader }} - jfa-go</title>
|
||||
</head>
|
||||
<body class="section">
|
||||
<div class="page-container">
|
||||
<div class="card ~neutral !normal mb-1">
|
||||
<span class="heading mb-1">{{ .strings.successHeader }}</span>
|
||||
<p class="content mb-1">{{ .successMessage }}</p>
|
||||
<a class="button ~urge !normal full-width center supra submit" href="{{ .jfLink }}" id="create-success-button">{{ .strings.successContinueButton }}</a>
|
||||
<div class="card ~neutral @low mb-4">
|
||||
<span class="heading mb-4">{{ .strings.successHeader }}</span>
|
||||
<p class="content my-4">{{ .successMessage }}</p>
|
||||
<a class="button ~urge @high full-width center supra submit" href="{{ .jfLink }}" id="create-success-button">{{ .strings.continue }}</a>
|
||||
</div>
|
||||
<i class="content">{{ .contactMessage }}</i>
|
||||
</div>
|
||||
|
@ -14,77 +14,79 @@
|
||||
<body class="max-w-full overflow-x-hidden section">
|
||||
<div id="modal-success" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1">{{ if .passwordReset }}{{ .strings.passwordReset }}{{ else }}{{ .strings.successHeader }}{{ end }}</span>
|
||||
<p class="content mb-1">{{ if .passwordReset }}{{ .strings.youCanLoginPassword }}{{ else }}{{ .successMessage }}{{ end }}</p>
|
||||
<a class="button ~urge !normal full-width center supra submit" href="{{ .jfLink }}" id="create-success-button">{{ .strings.continue }}</a>
|
||||
<span class="heading mb-4">{{ if .passwordReset }}{{ .strings.passwordReset }}{{ else }}{{ .strings.successHeader }}{{ end }}</span>
|
||||
<p class="content mb-4">{{ if .passwordReset }}{{ .strings.youCanLoginPassword }}{{ else }}{{ .successMessage }}{{ end }}</p>
|
||||
<a class="button ~urge @low full-width center supra submit" href="{{ .jfLink }}" id="create-success-button">{{ .strings.continue }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal-confirmation" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1">{{ .strings.confirmationRequired }}</span>
|
||||
<p class="content mb-1">{{ .strings.confirmationRequiredMessage }}</p>
|
||||
<span class="heading mb-4">{{ .strings.confirmationRequired }}</span>
|
||||
<p class="content mb-4">{{ .strings.confirmationRequiredMessage }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{{ if .telegramEnabled }}
|
||||
<div id="modal-telegram" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1">{{ .strings.linkTelegram }}</span>
|
||||
<p class="content mb-1">{{ .strings.sendPIN }}</p>
|
||||
<h1 class="ac">{{ .telegramPIN }}</h1>
|
||||
<span class="heading mb-4">{{ .strings.linkTelegram }}</span>
|
||||
<p class="content mb-4">{{ .strings.sendPIN }}</p>
|
||||
<p class="text-center text-2xl mb-2">{{ .telegramPIN }}</p>
|
||||
<a class="subheading link-center" href="{{ .telegramURL }}" target="_blank">
|
||||
<span class="shield ~info mr-1">
|
||||
<span class="shield ~info mr-4">
|
||||
<span class="icon">
|
||||
<i class="ri-telegram-line"></i>
|
||||
</span>
|
||||
</span>
|
||||
@{{ .telegramUsername }}
|
||||
</a>
|
||||
<span class="button ~info !normal full-width center mt-1" id="telegram-waiting">{{ .strings.success }}</span>
|
||||
<span class="button ~info @low full-width center mt-4" id="telegram-waiting">{{ .strings.success }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<div id="modal-discord" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1">{{ .strings.linkDiscord }}</span>
|
||||
<p class="content mb-1"> {{ .discordSendPINMessage }}</p>
|
||||
<h1 class="ac">{{ .discordPIN }}</h1>
|
||||
<span class="heading mb-4">{{ .strings.linkDiscord }}</span>
|
||||
<p class="content mb-4"> {{ .discordSendPINMessage }}</p>
|
||||
<h1 class="text-center text-2xl mb-2">{{ .discordPIN }}</h1>
|
||||
<a id="discord-invite"></a>
|
||||
<span class="button ~info !normal full-width center mt-1" id="discord-waiting">{{ .strings.success }}</span>
|
||||
<span class="button ~info @low full-width center mt-4" id="discord-waiting">{{ .strings.success }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .matrixEnabled }}
|
||||
<div id="modal-matrix" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1">{{ .strings.linkMatrix }}</span>
|
||||
<p class="content mb-1"> {{ .strings.matrixEnterUser }}</p>
|
||||
<input type="text" class="input ~neutral !high" placeholder="@user:riot.im" id="matrix-userid">
|
||||
<div class="subheading link-center mt-1">
|
||||
<span class="shield ~info mr-1">
|
||||
<span class="heading mb-4">{{ .strings.linkMatrix }}</span>
|
||||
<p class="content mb-4"> {{ .strings.matrixEnterUser }}</p>
|
||||
<input type="text" class="input ~neutral @high" placeholder="@user:riot.im" id="matrix-userid">
|
||||
<div class="subheading link-center mt-4">
|
||||
<span class="shield ~info mr-4">
|
||||
<span class="icon">
|
||||
<i class="ri-chat-3-line"></i>
|
||||
</span>
|
||||
</span>
|
||||
{{ .matrixUser }}
|
||||
</div>
|
||||
<span class="button ~info !normal full-width center mt-1" id="matrix-send">{{ .strings.submit }}</span>
|
||||
<span class="button ~info @low full-width center mt-4" id="matrix-send">{{ .strings.submit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
||||
<span class="button ~urge dropdown-button">
|
||||
<i class="ri-global-line"></i>
|
||||
<span class="ml-1 chev"></span>
|
||||
</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral !low" id="lang-list">
|
||||
<div class="top-4 left-4 absolute">
|
||||
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
||||
<span class="button ~urge dropdown-button">
|
||||
<i class="ri-global-line"></i>
|
||||
<span class="ml-2 chev"></span>
|
||||
</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low" id="lang-list">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div id="notification-box"></div>
|
||||
<div class="page-container">
|
||||
<div class="card ~neutral !low">
|
||||
<div class="card dark:~d_neutral @low">
|
||||
<div class="row baseline">
|
||||
<span class="col heading">
|
||||
{{ if .passwordReset }}
|
||||
@ -106,41 +108,41 @@
|
||||
{{ if .userExpiry }}
|
||||
<aside class="col aside sm ~warning" id="user-expiry-message"></aside>
|
||||
{{ end }}
|
||||
<form class="card ~neutral !normal" id="form-create" href="">
|
||||
<form class="card dark:~d_neutral @low" id="form-create" href="">
|
||||
{{ if not .passwordReset }}
|
||||
<label class="label supra">
|
||||
{{ .strings.username }}
|
||||
<input type="text" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="create-username" aria-label="{{ .strings.username }}">
|
||||
<input type="text" class="input ~neutral @high mt-2 mb-4" placeholder="{{ .strings.username }}" id="create-username" aria-label="{{ .strings.username }}">
|
||||
</label>
|
||||
|
||||
<label class="label supra" for="create-email">{{ .strings.emailAddress }}</label>
|
||||
<input type="email" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.emailAddress }}" id="create-email" aria-label="{{ .strings.emailAddress }}" value="{{ .email }}">
|
||||
<input type="email" class="input ~neutral @high mt-2 mb-4" placeholder="{{ .strings.emailAddress }}" id="create-email" aria-label="{{ .strings.emailAddress }}" value="{{ .email }}">
|
||||
{{ if .telegramEnabled }}
|
||||
<span class="button ~info !normal full-width center mb-1" id="link-telegram">{{ .strings.linkTelegram }}</span>
|
||||
<span class="button ~info @low full-width center mb-4" id="link-telegram">{{ .strings.linkTelegram }}</span>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<span class="button ~info !normal full-width center mb-1" id="link-discord">{{ .strings.linkDiscord }}</span>
|
||||
<span class="button ~info @low full-width center mb-4" id="link-discord">{{ .strings.linkDiscord }}</span>
|
||||
{{ end }}
|
||||
{{ if .matrixEnabled }}
|
||||
<span class="button ~info !normal full-width center mb-1" id="link-matrix">{{ .strings.linkMatrix }}</span>
|
||||
<span class="button ~info @low full-width center mb-4" id="link-matrix">{{ .strings.linkMatrix }}</span>
|
||||
{{ end }}
|
||||
{{ if or (.telegramEnabled) (or .discordEnabled .matrixEnabled) }}
|
||||
<div id="contact-via" class="unfocused">
|
||||
<label class="row switch pb-1">
|
||||
<label class="row switch pb-4">
|
||||
<input type="radio" name="contact-via" value="email"><span>Contact through Email</span>
|
||||
</label>
|
||||
{{ if .telegramEnabled }}
|
||||
<label class="row switch pb-1">
|
||||
<label class="row switch pb-4">
|
||||
<input type="radio" name="contact-via" value="telegram" id="contact-via-telegram"><span>Contact through Telegram</span>
|
||||
</label>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<label class="row switch pb-1">
|
||||
<label class="row switch pb-4">
|
||||
<input type="radio" name="contact-via" value="discord" id="contact-via-discord"><span>Contact through Discord</span>
|
||||
</label>
|
||||
{{ end }}
|
||||
{{ if .matrixEnabled }}
|
||||
<label class="row switch pb-1">
|
||||
<label class="row switch pb-4">
|
||||
<input type="radio" name="contact-via" value="matrix" id="contact-via-matrix"><span>Contact through Matrix</span>
|
||||
</label>
|
||||
{{ end }}
|
||||
@ -148,13 +150,13 @@
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<label class="label supra" for="create-password">{{ .strings.password }}</label>
|
||||
<input type="password" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.password }}" id="create-password" aria-label="{{ .strings.password }}">
|
||||
<input type="password" class="input ~neutral @high mt-2 mb-4" placeholder="{{ .strings.password }}" id="create-password" aria-label="{{ .strings.password }}">
|
||||
|
||||
<label class="label supra" for="create-reenter-password">{{ .strings.reEnterPassword }}</label>
|
||||
<input type="password" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.password }}" id="create-reenter-password" aria-label="{{ .strings.reEnterPassword }}">
|
||||
<input type="password" class="input ~neutral @high mt-2 mb-4" placeholder="{{ .strings.password }}" id="create-reenter-password" aria-label="{{ .strings.reEnterPassword }}">
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">
|
||||
<span class="button ~urge @low full-width center supra submit">
|
||||
{{ if .passwordReset }}
|
||||
{{ .strings.reset }}
|
||||
{{ else }}
|
||||
@ -165,7 +167,7 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card ~neutral !normal">
|
||||
<div class="card ~neutral @low mb-4">
|
||||
<span class="label supra" for="inv-uses">{{ .strings.passwordRequirementsHeader }}</span>
|
||||
<ul>
|
||||
{{ range $key, $value := .requirements }}
|
||||
@ -176,7 +178,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
{{ if .contactMessage }}
|
||||
<aside class="col aside sm ~info">{{ .contactMessage }}</aside>
|
||||
<aside class="col aside sm ~info mt-4">{{ .contactMessage }}</aside>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,11 +7,13 @@
|
||||
</head>
|
||||
<body class="section">
|
||||
<div class="page-container">
|
||||
<h1 class="heading">Invalid invite code.</h1>
|
||||
<p class="content">The code above was either incorrect, or has expired.</p>
|
||||
<p class="content">
|
||||
{{ .contactMessage }}
|
||||
</p>
|
||||
<div class="card">
|
||||
<h1 class="text-3xl font-semibold">Invalid invite code.</h1>
|
||||
<p class="content">The code above was either incorrect, or has expired.</p>
|
||||
<p class="content">
|
||||
{{ .contactMessage }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -12,15 +12,15 @@
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="page-container">
|
||||
<div class="card ~neutral !normal mb-1">
|
||||
<span class="heading mb-1">
|
||||
<div class="card ~neutral @low mb-4">
|
||||
<span class="heading mb-4">
|
||||
{{ if .success }}
|
||||
{{ .strings.passwordReset }}
|
||||
{{ else }}
|
||||
{{ .strings.resetFailed }}
|
||||
{{ end }}
|
||||
</span>
|
||||
<p class="content mb-1">
|
||||
<p class="content mb-4">
|
||||
{{ if .success }}
|
||||
{{ if .ombiEnabled }}
|
||||
{{ .strings.youCanLoginOmbi }}
|
||||
@ -35,7 +35,7 @@
|
||||
<aside class="aside ~warning">
|
||||
{{ .strings.changeYourPassword }}
|
||||
</aside>
|
||||
<span class="button ~urge !normal full-width center supra p-1 mt-1" id="pin" title="{{ .strings.copy }}">{{ .pin }}</span>
|
||||
<span class="button ~urge @low w-100 text-center text-xl p-1 mt-4" id="pin" title="{{ .strings.copy }}">{{ .pin }}</span>
|
||||
{{ end }}
|
||||
</div>
|
||||
<i class="content">{{ .contactMessage }}</i>
|
||||
|
406
html/setup.html
406
html/setup.html
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="light-theme">
|
||||
<html lang="en" class="light">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="css/bundle.css">
|
||||
{{ template "header.html" . }}
|
||||
@ -7,18 +7,20 @@
|
||||
</head>
|
||||
<body class="max-w-full overflow-x-hidden section">
|
||||
<div id="notification-box"></div>
|
||||
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
||||
<span class="button ~urge dropdown-button">
|
||||
<i class="ri-global-line"></i>
|
||||
<span class="ml-1 chev"></span>
|
||||
</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral !low" id="lang-list">
|
||||
<div class="top-4 left-4 absolute">
|
||||
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
||||
<span class="button ~urge dropdown-button">
|
||||
<i class="ri-global-line"></i>
|
||||
<span class="ml-2 chev"></span>
|
||||
</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low" id="lang-list">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="page-container" id="page-container">
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<div class="card ~neutral @low mb-2">
|
||||
<div class="row">
|
||||
<img class="banner header" src="banner.svg" alt="jfa-go" />
|
||||
</div>
|
||||
@ -26,70 +28,70 @@
|
||||
<span class="heading welcome">{{ .lang.StartPage.welcome }}</span>
|
||||
</div>
|
||||
<div class="row col flex center">
|
||||
<p class="content">{{ .lang.StartPage.pressStart }}</p>
|
||||
<p class="content my-2">{{ .lang.StartPage.pressStart }}</p>
|
||||
</div>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="support">{{ .lang.StartPage.httpsNotice }}</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.StartPage.start }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.StartPage.start }}</span>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused">
|
||||
<div class="card ~neutral @low mb-2 unfocused">
|
||||
<span class="heading">{{ .lang.Language.title }}</span>
|
||||
<p class="content" id="language-description"></p>
|
||||
<p class="content my-2" id="language-description"></p>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Language.defaultAdminLang }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<span class="mt-4">{{ .lang.Language.defaultAdminLang }}</span>
|
||||
<div class="select ~neutral @low mt-4 mb-2">
|
||||
<select id="ui-language-admin">
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Language.defaultFormLang }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<span class="mt-4">{{ .lang.Language.defaultFormLang }}</span>
|
||||
<div class="select ~neutral @low mt-4 mb-2">
|
||||
<select id="ui-language-form">
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Language.defaultEmailLang }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<span class="mt-4">{{ .lang.Language.defaultEmailLang }}</span>
|
||||
<div class="select ~neutral @low mt-4 mb-2">
|
||||
<select id="email-language">
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused">
|
||||
<div class="card ~neutral @low mb-2 unfocused">
|
||||
<span class="heading">{{ .lang.General.title }}</span>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.General.listenAddress }}</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half mb-1" id="ui-host" value="0.0.0.0">
|
||||
<span class="mt-4">{{ .lang.General.listenAddress }}</span>
|
||||
<input type="url" class="input ~neutral @low mt-4 mb-2" id="ui-host" value="0.0.0.0">
|
||||
</label>
|
||||
<label class="row switch">
|
||||
<input type="checkbox" id="advanced-tls"><span>{{ .lang.General.useHTTPS }}</span>
|
||||
<input type="checkbox" class="mr-2" id="advanced-tls"><span>{{ .lang.General.useHTTPS }}</span>
|
||||
</label>
|
||||
<p class="support mb-1">{{ .lang.General.useHTTPSNotice }}</p>
|
||||
<p class="support mb-2 mt-1">{{ .lang.General.useHTTPSNotice }}</p>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.General.pathToCertificate }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="advanced-tls_cert">
|
||||
<span class="mt-4">{{ .lang.General.pathToCertificate }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4 mb-2" id="advanced-tls_cert">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.General.pathToKeyFile }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="advanced-tls_key">
|
||||
<span class="mt-4">{{ .lang.General.pathToKeyFile }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4 mb-2" id="advanced-tls_key">
|
||||
</label>
|
||||
<span class="heading">{{ .lang.Updates.title }}</span>
|
||||
<p class="content" id="updates-description"></p>
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" id="updates-enabled" checked><span>{{ .lang.Strings.enabled }}</span>
|
||||
<p class="content my-2" id="updates-description"></p>
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" class="mr-2" id="updates-enabled" checked><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>{{ .lang.Updates.updateChannel }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<div class="select ~neutral @low mt-4 mb-2">
|
||||
<select id="updates-channel">
|
||||
<option value="stable">{{ .lang.Updates.stable }}</option>
|
||||
<option value="unstable">{{ .lang.Updates.unstable }}</option>
|
||||
@ -99,21 +101,21 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.port }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="ui-port" value="8056">
|
||||
<span class="mt-4">{{ .lang.Strings.port }}</span>
|
||||
<input type="number" class="input ~neutral @low mt-4 mb-2" id="ui-port" value="8056">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.General.httpsPort }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="advanced-tls_port" value="8057">
|
||||
<span class="mt-4">{{ .lang.General.httpsPort }}</span>
|
||||
<input type="number" class="input ~neutral @low mt-4 mb-2" id="advanced-tls_port" value="8057">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.General.urlBase }} ({{ .lang.Strings.optional }})</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half" id="ui-url_base">
|
||||
<p class="support mb-1">{{ .lang.General.urlBaseNotice }}</p>
|
||||
<span class="mt-4">{{ .lang.General.urlBase }} ({{ .lang.Strings.optional }})</span>
|
||||
<input type="url" class="input ~neutral @low mt-4" id="ui-url_base">
|
||||
<p class="support mb-2 mt-1">{{ .lang.General.urlBaseNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>{{ .lang.Strings.theme }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<div class="select ~neutral @low mt-4 mb-2">
|
||||
<select id="ui-theme">
|
||||
<option value="Jellyfin (Dark)">{{ .lang.General.darkTheme }}</option>
|
||||
<option value="Default (Light)">{{ .lang.General.lightTheme }}</option>
|
||||
@ -123,142 +125,142 @@
|
||||
</div>
|
||||
</div>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused">
|
||||
<div class="card ~neutral @low mb-2 unfocused">
|
||||
<span class="heading">{{ .lang.Login.title }}</span>
|
||||
<p class="content">{{ .lang.Login.description }}</p>
|
||||
<div class="pl-1">
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="ui-jellyfin_login" value="true" checked><span>{{ .lang.Login.authorizeWithJellyfin }}</span>
|
||||
<p class="content my-2">{{ .lang.Login.description }}</p>
|
||||
<div class="pl-4">
|
||||
<label class="row switch pb-4">
|
||||
<input type="radio" class="mr-2" name="ui-jellyfin_login" value="true" checked><span>{{ .lang.Login.authorizeWithJellyfin }}</span>
|
||||
</label>
|
||||
<label class="row switch pl-1 pb-1">
|
||||
<input type="checkbox" id="ui-admin_only"><span>{{ .lang.Login.adminOnly }}</span>
|
||||
<label class="row switch pl-4 pb-4">
|
||||
<input type="checkbox" class="mr-2" id="ui-admin_only"><span>{{ .lang.Login.adminOnly }}</span>
|
||||
</label>
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="ui-jellyfin_login" value="false"><span>{{ .lang.Login.authorizeManual }}</span>
|
||||
<label class="row switch pb-4">
|
||||
<input type="radio" class="mr-2" name="ui-jellyfin_login" value="false"><span>{{ .lang.Login.authorizeManual }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="login-manual">
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.username }}</span>
|
||||
<input type="text" id="ui-username" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.username }}">
|
||||
<span class="mt-4">{{ .lang.Strings.username }}</span>
|
||||
<input type="text" id="ui-username" class="input ~neutral @low mt-4 mb-2" placeholder="{{ .lang.Strings.username }}">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>{{ .lang.Strings.password }}</span>
|
||||
<input type="password" id="ui-password" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.password }}">
|
||||
<input type="password" id="ui-password" class="input ~neutral @low mt-4 mb-2" placeholder="{{ .lang.Strings.password }}">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>{{ .lang.Strings.emailAddress }} ({{ .lang.Strings.optional }})</span>
|
||||
<input type="email" id="ui-email" class="input ~neutral !normal mt-half" placeholder="email@address">
|
||||
<span class="support mb-1">{{ .lang.Login.emailNotice }}</span>
|
||||
<input type="email" id="ui-email" class="input ~neutral @low mt-4" placeholder="email@address">
|
||||
<span class="support mb-2 mt-1">{{ .lang.Login.emailNotice }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused">
|
||||
<div class="card ~neutral @low mb-2 unfocused">
|
||||
<span class="heading">{{ .lang.JellyfinEmby.title }}</span>
|
||||
<p class="content">{{ .lang.JellyfinEmby.description }}</p>
|
||||
<p class="content my-2">{{ .lang.JellyfinEmby.description }}</p>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label">
|
||||
<span>{{ .lang.Strings.serverType }}</span>
|
||||
<div class="select ~neutral !normal mt-half">
|
||||
<div class="select ~neutral @low mt-4">
|
||||
<select id="jellyfin-type">
|
||||
<option value="jellyfin">Jellyfin</option>
|
||||
<option value="emby">Emby</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="support mb-1">{{ .lang.JellyfinEmby.embyNotice }}</p>
|
||||
<p class="support mb-2 mt-1">{{ .lang.JellyfinEmby.embyNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.JellyfinEmby.replaceJellyfin }} ({{ .lang.Strings.optional }})</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="jellyfin-substitute_jellyfin_strings">
|
||||
<p class="support mb-1">{{ .lang.JellyfinEmby.replaceJellyfinNotice }}</p>
|
||||
<span class="mt-4">{{ .lang.JellyfinEmby.replaceJellyfin }} ({{ .lang.Strings.optional }})</span>
|
||||
<input type="text" class="input ~neutral @low mt-4" id="jellyfin-substitute_jellyfin_strings">
|
||||
<p class="support mb-2 mt-1">{{ .lang.JellyfinEmby.replaceJellyfinNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.username }}</span>
|
||||
<input type="text" id="jellyfin-username" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.username }}">
|
||||
<span class="mt-4">{{ .lang.Strings.username }}</span>
|
||||
<input type="text" id="jellyfin-username" class="input ~neutral @low mt-4 mb-2" placeholder="{{ .lang.Strings.username }}">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>{{ .lang.Strings.password }}</span>
|
||||
<input type="password" id="jellyfin-password" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.password }}">
|
||||
<input type="password" id="jellyfin-password" class="input ~neutral @low mt-4 mb-2" placeholder="{{ .lang.Strings.password }}">
|
||||
</label>
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.serverAddress }} ({{ .lang.JellyfinEmby.internal }})</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half mb-1" id="jellyfin-server" placeholder="http://jellyf.in:80">
|
||||
<span class="mt-4">{{ .lang.Strings.serverAddress }} ({{ .lang.JellyfinEmby.internal }})</span>
|
||||
<input type="url" class="input ~neutral @low mt-4 mb-2" id="jellyfin-server" placeholder="http://jellyf.in:80">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.serverAddress }} ({{ .lang.JellyfinEmby.external }})</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half" id="jellyfin-public_server" placeholder="https://jellyf.in">
|
||||
<p class="support mb-1">{{ .lang.JellyfinEmby.addressExternalNotice }}</p>
|
||||
<span class="mt-4">{{ .lang.Strings.serverAddress }} ({{ .lang.JellyfinEmby.external }})</span>
|
||||
<input type="url" class="input ~neutral @low mt-4" id="jellyfin-public_server" placeholder="https://jellyf.in">
|
||||
<p class="support mb-2 mt-1">{{ .lang.JellyfinEmby.addressExternalNotice }}</p>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal" id="jellyfin-test-connection">{{ .lang.JellyfinEmby.testConnection }}</span>
|
||||
<span class="button ~urge !normal next" disabled>{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~urge @low" id="jellyfin-test-connection">{{ .lang.JellyfinEmby.testConnection }}</span>
|
||||
<span class="button ~urge @low next" disabled>{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused">
|
||||
<div class="card ~neutral @low mb-2 unfocused">
|
||||
<span class="heading">{{ .lang.Ombi.title }}</span>
|
||||
<p class="content">{{ .lang.Ombi.description }}</p>
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" id="ombi-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
<p class="content my-2">{{ .lang.Ombi.description }}</p>
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" class="mr-2" id="ombi-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.serverAddress }}</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half mb-1" id="ombi-server" placeholder="ombi.jellyf.in">
|
||||
<span class="mt-4">{{ .lang.Strings.serverAddress }}</span>
|
||||
<input type="url" class="input ~neutral @low mt-4 mb-2" id="ombi-server" placeholder="ombi.jellyf.in">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.apiKey }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="ombi-api_key">
|
||||
<p class="support mb-1">{{ .lang.Ombi.apiKeyNotice }}</p>
|
||||
<span class="mt-4">{{ .lang.Strings.apiKey }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4" id="ombi-api_key">
|
||||
<p class="support mb-2 mt-1">{{ .lang.Ombi.apiKeyNotice }}</p>
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused">
|
||||
<div class="card ~neutral @low mb-2 unfocused">
|
||||
<span class="heading">{{ .lang.Messages.title }}</span>
|
||||
<p class="content" id="messages-description"></p>
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" id="messages-enabled" checked><span>{{ .lang.Strings.enabled }}</span>
|
||||
<p class="content my-2" id="messages-description"></p>
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" class="mr-2" id="messages-enabled" checked><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Email.dateFormat }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="email-date_format" value="%d/%m/%y">
|
||||
<p class="support mb-1" id="email-dateformat-notice"></p>
|
||||
<span class="mt-4">{{ .lang.Email.dateFormat }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4" id="email-date_format" value="%d/%m/%y">
|
||||
<p class="support mb-2 mt-1" id="email-dateformat-notice"></p>
|
||||
</label>
|
||||
<div>
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="email-24h" value="true" checked><span>{{ .lang.Strings.time24h }}</span>
|
||||
<label class="row switch pb-4">
|
||||
<input type="radio" class="mr-2" name="email-24h" value="true" checked><span>{{ .lang.Strings.time24h }}</span>
|
||||
</label>
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="email-24h" value="false"><span>{{ .lang.Strings.time12h }}</span>
|
||||
<label class="row switch pb-4">
|
||||
<input type="radio" class="mr-2" name="email-24h" value="false"><span>{{ .lang.Strings.time12h }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="email-sect">
|
||||
<span class="heading">{{ .lang.Email.title }}</span>
|
||||
<p class="content" id="email-description"></p>
|
||||
<p class="content my-2" id="email-description"></p>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label">
|
||||
<span>{{ .lang.Email.method }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<div class="select ~neutral @low mt-4 mb-2">
|
||||
<select id="email-method">
|
||||
<option value="">{{ .lang.Strings.disabled }}</option>
|
||||
<option value="smtp">SMTP</option>
|
||||
@ -267,24 +269,24 @@
|
||||
</div>
|
||||
</label>
|
||||
<label class="row switch">
|
||||
<input type="checkbox" id="email-no_username"><span>{{ .lang.Email.useEmailAsUsername }}</span>
|
||||
<p class="support mb-1">{{ .lang.Email.useEmailAsUsernameNotice }}</p>
|
||||
<input type="checkbox" class="mr-2" id="email-no_username"><span>{{ .lang.Email.useEmailAsUsername }}</span>
|
||||
<p class="support mb-2 mt-1">{{ .lang.Email.useEmailAsUsernameNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Email.fromAddress }}</span>
|
||||
<input type="email" class="input ~neutral !normal mt-half mb-1" id="email-address" placeholder="mail@jellyf.in">
|
||||
<span class="mt-4">{{ .lang.Email.fromAddress }}</span>
|
||||
<input type="email" class="input ~neutral @low mt-4 mb-2" id="email-address" placeholder="mail@jellyf.in">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Email.senderName }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="email-from" value="Jellyfin">
|
||||
<span class="mt-4">{{ .lang.Email.senderName }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4 mb-2" id="email-from" value="Jellyfin">
|
||||
</label>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div id="email-smtp">
|
||||
<p class="subheading">SMTP</p>
|
||||
<p class="text-2xl font-semibold mb-2">SMTP</p>
|
||||
<label class="label">
|
||||
<span>{{ .lang.Email.encryption }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<div class="select ~neutral @low mt-4 mb-2">
|
||||
<select id="smtp-encryption">
|
||||
<option value="starttls">STARTTLS ({{ .lang.Strings.port }} 587)</option>
|
||||
<option value="ssl_tls">SSL/TLS ({{ .lang.Strings.port }} 465)</option>
|
||||
@ -292,197 +294,197 @@
|
||||
</div>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.serverAddress }}</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half mb-1" id="smtp-server" placeholder="smtp.jellyf.in">
|
||||
<span class="mt-4">{{ .lang.Strings.serverAddress }}</span>
|
||||
<input type="url" class="input ~neutral @low mt-4 mb-2" id="smtp-server" placeholder="smtp.jellyf.in">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.port }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="smtp-port" placeholder="587">
|
||||
<span class="mt-4">{{ .lang.Strings.port }}</span>
|
||||
<input type="number" class="input ~neutral @low mt-4 mb-2" id="smtp-port" placeholder="587">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.username }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="smtp-username">
|
||||
<span class="mt-4">{{ .lang.Strings.username }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4 mb-2" id="smtp-username">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.password }}</span>
|
||||
<input type="password" class="input ~neutral !normal mt-half mb-1" id="smtp-password">
|
||||
<span class="mt-4">{{ .lang.Strings.password }}</span>
|
||||
<input type="password" class="input ~neutral @low mt-4 mb-2" id="smtp-password">
|
||||
</label>
|
||||
</div>
|
||||
<div id="email-mailgun">
|
||||
<p class="subheading">Mailgun</p>
|
||||
<p class="text-2xl font-semibold mb-2">Mailgun</p>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Email.mailgunApiURL }}</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half mb-1" id="mailgun-api_url" placeholder="https://api.eu.mailgun.net/v3/mail.jellyf.in/messages">
|
||||
<span class="mt-4">{{ .lang.Email.mailgunApiURL }}</span>
|
||||
<input type="url" class="input ~neutral @low mt-4 mb-2" id="mailgun-api_url" placeholder="https://api.eu.mailgun.net/v3/mail.jellyf.in/messages">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.apiKey }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="mailgun-api_key">
|
||||
<span class="mt-4">{{ .lang.Strings.apiKey }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4 mb-2" id="mailgun-api_key">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused related-to-email">
|
||||
<div class="card ~neutral @low mb-2 unfocused related-to-email">
|
||||
<span class="heading">{{ .lang.Notifications.title }}</span>
|
||||
<p class="content">{{ .lang.Notifications.description }}</p>
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" id="notifications-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
<p class="content my-2">{{ .lang.Notifications.description }}</p>
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" class="mr-2" id="notifications-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<span class="heading">{{ .lang.WelcomeEmails.title }}</span>
|
||||
<p class="content">{{ .lang.WelcomeEmails.description }}</p>
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" id="welcome_email-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
<p class="content my-2">{{ .lang.WelcomeEmails.description }}</p>
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" class="mr-2" id="welcome_email-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.emailSubject }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="welcome_email-subject" placeholder="{{ .emailLang.WelcomeEmail.title }}">
|
||||
<span class="mt-4">{{ .lang.Strings.emailSubject }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4 mb-2" id="welcome_email-subject" placeholder="{{ .emailLang.WelcomeEmail.title }}">
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused related-to-email">
|
||||
<div class="card ~neutral @low mb-2 unfocused related-to-email">
|
||||
<span class="heading">{{ .lang.InviteEmails.title }}</span>
|
||||
<p class="content">{{ .lang.InviteEmails.description }}</p>
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" id="invite_emails-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
<p class="content my-2">{{ .lang.InviteEmails.description }}</p>
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" class="mr-2" id="invite_emails-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.URL }}</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half mb-1" id="invite_emails-url_base" placeholder="https://accounts.jellyf.in/invite">
|
||||
<span class="mt-4">{{ .lang.Strings.URL }}</span>
|
||||
<input type="url" class="input ~neutral @low mt-4 mb-2" id="invite_emails-url_base" placeholder="https://accounts.jellyf.in/invite">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.emailSubject }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="invite_emails-subject" placeholder="{{ .emailLang.InviteEmail.title }}">
|
||||
<span class="mt-4">{{ .lang.Strings.emailSubject }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4 mb-2" id="invite_emails-subject" placeholder="{{ .emailLang.InviteEmail.title }}">
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div id="password-resets" class="card ~neutral !low mb-1 unfocused related-to-email">
|
||||
<div id="password-resets" class="card ~neutral @low mb-2 unfocused related-to-email">
|
||||
<span class="heading">{{ .lang.PasswordResets.title }}</span>
|
||||
<p class="content">{{ .lang.PasswordResets.description }}</p>
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" id="password_resets-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
<p class="content my-2">{{ .lang.PasswordResets.description }}</p>
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" class="mr-2" id="password_resets-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.PasswordResets.pathToJellyfin }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="password_resets-watch_directory" placeholder="/config/jellyfin">
|
||||
<p class="support mb-1">{{ .lang.PasswordResets.pathToJellyfinNotice }}</p>
|
||||
<span class="mt-4">{{ .lang.PasswordResets.pathToJellyfin }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4" id="password_resets-watch_directory" placeholder="/config/jellyfin">
|
||||
<p class="support mb-2 mt-1">{{ .lang.PasswordResets.pathToJellyfinNotice }}</p>
|
||||
</label>
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="password_resets-link_reset"><span>{{ .lang.PasswordResets.resetLinks }}</span>
|
||||
<p class="support mb-1">{{ .lang.PasswordResets.resetLinksNotice }}</p>
|
||||
<input type="checkbox" class="mr-2" id="password_resets-link_reset"><span>{{ .lang.PasswordResets.resetLinks }}</span>
|
||||
<p class="support mb-2 mt-1">{{ .lang.PasswordResets.resetLinksNotice }}</p>
|
||||
</label>
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="password_resets-set_password"><span>{{ .lang.PasswordResets.setPassword }}</span>
|
||||
<p class="support mb-1">{{ .lang.PasswordResets.setPasswordNotice }}</p>
|
||||
<input type="checkbox" class="mr-2" id="password_resets-set_password"><span>{{ .lang.PasswordResets.setPassword }}</span>
|
||||
<p class="support mb-2 mt-1">{{ .lang.PasswordResets.setPasswordNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<p class="mt-half">{{ .lang.PasswordResets.resetLinksLanguage }}</p>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<p class="mt-4">{{ .lang.PasswordResets.resetLinksLanguage }}</p>
|
||||
<div class="select ~neutral @low mt-4 mb-2">
|
||||
<select id="password_resets-language">
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="row label">
|
||||
<span class="mt-half">{{ .lang.Strings.emailSubject }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="password_resets-subject" placeholder="{{ .emailLang.PasswordReset.title }}">
|
||||
<span class="mt-4">{{ .lang.Strings.emailSubject }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4 mb-2" id="password_resets-subject" placeholder="{{ .emailLang.PasswordReset.title }}">
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused">
|
||||
<div class="card ~neutral @low mb-2 unfocused">
|
||||
<span class="heading">{{ .lang.PasswordValidation.title }}</span>
|
||||
<p class="content">{{ .lang.PasswordValidation.description }}</p>
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" id="password_validation-enabled" checked><span>{{ .lang.Strings.enabled }}</span>
|
||||
<p class="content my-2">{{ .lang.PasswordValidation.description }}</p>
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" class="mr-2" id="password_validation-enabled" checked><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.PasswordValidation.length }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="password_validation-min_length" value="8">
|
||||
<span class="mt-4">{{ .lang.PasswordValidation.length }}</span>
|
||||
<input type="number" class="input ~neutral @low mt-4 mb-2" id="password_validation-min_length" value="8">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.PasswordValidation.uppercase }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="password_validation-upper" value="1">
|
||||
<span class="mt-4">{{ .lang.PasswordValidation.uppercase }}</span>
|
||||
<input type="number" class="input ~neutral @low mt-4 mb-2" id="password_validation-upper" value="1">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.PasswordValidation.lowercase }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="password_validation-lower" value="0">
|
||||
<span class="mt-4">{{ .lang.PasswordValidation.lowercase }}</span>
|
||||
<input type="number" class="input ~neutral @low mt-4 mb-2" id="password_validation-lower" value="0">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.PasswordValidation.numbers }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="password_validation-number" value="0">
|
||||
<span class="mt-4">{{ .lang.PasswordValidation.numbers }}</span>
|
||||
<input type="number" class="input ~neutral @low mt-4 mb-2" id="password_validation-number" value="0">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.PasswordValidation.special }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="password_validation-special" value="0">
|
||||
<span class="mt-4">{{ .lang.PasswordValidation.special }}</span>
|
||||
<input type="number" class="input ~neutral @low mt-4 mb-2" id="password_validation-special" value="0">
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused">
|
||||
<div class="card ~neutral @low mb-2 unfocused">
|
||||
<span class="heading">{{ .lang.HelpMessages.title }}</span>
|
||||
<p class="content">{{ .lang.HelpMessages.description }}</p>
|
||||
<p class="content my-2">{{ .lang.HelpMessages.description }}</p>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.HelpMessages.contactMessage }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="ui-contact_message">
|
||||
<p class="support mb-1">{{ .lang.HelpMessages.contactMessageNotice }}</p>
|
||||
<span class="mt-4">{{ .lang.HelpMessages.contactMessage }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4" id="ui-contact_message">
|
||||
<p class="support mb-2 mt-1">{{ .lang.HelpMessages.contactMessageNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.HelpMessages.helpMessage }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="ui-help_message">
|
||||
<p class="support mb-1">{{ .lang.HelpMessages.helpMessageNotice }}</p>
|
||||
<span class="mt-4">{{ .lang.HelpMessages.helpMessage }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4" id="ui-help_message">
|
||||
<p class="support mb-2 mt-1">{{ .lang.HelpMessages.helpMessageNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.HelpMessages.successMessage }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="ui-success_message">
|
||||
<p class="support mb-1">{{ .lang.HelpMessages.successMessageNotice }}</p>
|
||||
<span class="mt-4">{{ .lang.HelpMessages.successMessage }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4" id="ui-success_message">
|
||||
<p class="support mb-2 mt-1">{{ .lang.HelpMessages.successMessageNotice }}</p>
|
||||
</label>
|
||||
<label class="label related-to-email">
|
||||
<span class="mt-half">{{ .lang.HelpMessages.emailMessage }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="email-message">
|
||||
<p class="support mb-1">{{ .lang.HelpMessages.emailMessageNotice }}</p>
|
||||
<span class="mt-4">{{ .lang.HelpMessages.emailMessage }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4" id="email-message">
|
||||
<p class="support mb-2 mt-1">{{ .lang.HelpMessages.emailMessageNotice }}</p>
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused">
|
||||
<div class="card ~neutral @low mb-2 unfocused">
|
||||
<div class="row col flex center">
|
||||
<span class="heading">{{ .lang.EndPage.finished }}</span>
|
||||
</div>
|
||||
<div class="row col flex center">
|
||||
<p class="content">{{ .lang.EndPage.restartMessage }}</p>
|
||||
<p class="content my-2">{{ .lang.EndPage.restartMessage }}</p>
|
||||
</div>
|
||||
<div class="row col flex center">
|
||||
<span class="button ~neutral !normal back mr-1">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~urge !normal" id="restart">{{ .lang.Strings.submit }}</span>
|
||||
<span class="button ~urge !normal unfocused" id="refresh">{{ .lang.EndPage.refreshPage }}</span>
|
||||
<span class="button ~neutral @low back mr-4">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~urge @low" id="restart">{{ .lang.Strings.submit }}</span>
|
||||
<span class="button ~urge @low unfocused" id="refresh">{{ .lang.EndPage.refreshPage }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,13 +1,5 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": ""
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "",
|
||||
"resetFailed": "",
|
||||
"tryAgain": "",
|
||||
"youCanLogin": "",
|
||||
"youCanLoginOmbi": "",
|
||||
"changeYourPassword": ""
|
||||
"name": "English (GB)"
|
||||
}
|
||||
}
|
||||
|
2
main.go
2
main.go
@ -82,7 +82,7 @@ type appContext struct {
|
||||
configBase settings
|
||||
dataPath string
|
||||
webFS httpFS
|
||||
cssClass string // Default theme, "light-theme"|"dark-theme".
|
||||
cssClass string // Default theme, "light"|"dark".
|
||||
jellyfinLogin bool
|
||||
users []User
|
||||
invalidTokens []string
|
||||
|
@ -40,8 +40,8 @@ func migrateProfiles(app *appContext) {
|
||||
// Migrate pre-0.2.5 bootstrap theme choice to a17t version.
|
||||
func migrateBootstrap(app *appContext) {
|
||||
themes := map[string]string{
|
||||
"Jellyfin (Dark)": "dark-theme",
|
||||
"Default (Light)": "light-theme",
|
||||
"Jellyfin (Dark)": "dark",
|
||||
"Default (Light)": "light",
|
||||
}
|
||||
|
||||
if app.config.Section("ui").Key("theme").String() == "Bootstrap (Light)" {
|
||||
|
3361
package-lock.json
generated
3361
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -19,18 +19,21 @@
|
||||
"dependencies": {
|
||||
"@ts-stack/markdown": "^1.3.0",
|
||||
"@types/node": "^15.0.1",
|
||||
"a17t": "^0.4.0",
|
||||
"a17t": "^0.10.1",
|
||||
"browserslist": "^4.16.6",
|
||||
"esbuild": "^0.8.57",
|
||||
"inline-source": "^7.2.0",
|
||||
"jsdom": "^19.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"mjml": "^4.8.0",
|
||||
"nightwind": "github:yonson2/nightwind",
|
||||
"remixicon": "^2.5.0",
|
||||
"remove-markdown": "^0.3.0",
|
||||
"typescript": "^4.0.3",
|
||||
"uncss": "^0.17.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"live-server": "^1.2.1"
|
||||
"live-server": "^1.2.1",
|
||||
"tailwindcss": "^3.0.8"
|
||||
}
|
||||
}
|
||||
|
50
scripts/dark-variant.sh
Executable file
50
scripts/dark-variant.sh
Executable file
@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
# scan all typescript and automatically add dark variants to color tags if they're not already present.
|
||||
|
||||
for f in $1/*.ts; do
|
||||
# FIXME: inline html
|
||||
for l in $(grep -n "~neutral\|~positive\|~urge\|~warning\|~info\|~critical" $f | sed -e 's/:.*//g'); do
|
||||
# for l in $(sed -n '/classList/=' $f); do
|
||||
line=$(sed -n "${l}p" $f)
|
||||
echo $line | grep "classList" &> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo $line | sed 's/.*classList//; s/).*//' | grep "~neutral\|~positive\|~urge\|~warning\|~info\|~critical" &> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# echo "found classList @ " $l
|
||||
echo $line | grep "dark:" &>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
for color in neutral positive urge warning info critical; do
|
||||
sed -i "${l},${l}s/\"~${color}\"/\"~${color}\", \"dark:~d_${color}\"/g" $f
|
||||
done
|
||||
fi
|
||||
else
|
||||
echo "FIX: classList found, but color tag wasn't in it"
|
||||
fi
|
||||
else
|
||||
echo $line | grep "querySelector" &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
# echo "found inline in " $f " @ " $l ", " $(sed -n "${l}p" $f)
|
||||
echo $line | grep "dark:" &>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
for color in neutral positive urge warning info critical; do
|
||||
sed -i "${l},${l}s/~${color}/~${color} dark:~d_${color}/g" $f
|
||||
done
|
||||
fi
|
||||
else
|
||||
echo $line | sed 's/.*querySelector//; s/).*//' | grep "~neutral\|~positive\|~urge\|~warning\|~info\|~critical" &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo $line | grep "dark:" &>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
# echo "found inline in " $f " @ " $l ", " $(sed -n "${l}p" $f)
|
||||
for color in neutral positive urge warning info critical; do
|
||||
sed -i "${l},${l}s/~${color}/~${color} dark:~d_${color}/g" $f
|
||||
done
|
||||
fi
|
||||
#else
|
||||
#echo "FIX: querySelector found, but color tag wasn't in it: " $line
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
60
scripts/missing-colors.js
Normal file
60
scripts/missing-colors.js
Normal file
@ -0,0 +1,60 @@
|
||||
let parser = require("jsdom");
|
||||
let fs = require("fs");
|
||||
let path = require("path");
|
||||
|
||||
const hasDark = (item) => {
|
||||
for (let i = 0; i < item.classList.length; i++) {
|
||||
if (item.classList[i].substring(0,5) == "dark:") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
const fixHTML = (infile, outfile) => {
|
||||
console.log(infile, outfile)
|
||||
let doc = new parser.JSDOM(fs.readFileSync(infile));
|
||||
for (let item of ["badge", "chip", "shield", "input", "table", "button", "portal", "select", "aside", "card", "field", "textarea"]) {
|
||||
let items = doc.window.document.body.querySelectorAll("."+item);
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let hasColor = false;
|
||||
for (let color of ["neutral", "positive", "urge", "warning", "info", "critical"]) {
|
||||
//console.log(color);
|
||||
if (items[i].classList.contains("~"+color)) {
|
||||
hasColor = true;
|
||||
// console.log("adding to", items[i].classList)
|
||||
if (!hasDark(items[i])) {
|
||||
items[i].classList.add("dark:~d_"+color);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasColor) {
|
||||
if (!hasDark(items[i])) {
|
||||
// card without ~neutral look different than with.
|
||||
if (item != "card") items[i].classList.add("~neutral");
|
||||
items[i].classList.add("dark:~d_neutral");
|
||||
}
|
||||
}
|
||||
if (!items[i].classList.contains("@low") && !items[i].classList.contains("@high")) {
|
||||
items[i].classList.add("@low");
|
||||
}
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(outfile, doc.window.document.documentElement.outerHTML);
|
||||
};
|
||||
|
||||
let inpath = process.argv[process.argv.length-2];
|
||||
let outpath = process.argv[process.argv.length-1];
|
||||
|
||||
if (fs.statSync(inpath).isDirectory()) {
|
||||
let files = fs.readdirSync(inpath);
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
if (files[i].indexOf(".html")>=0) {
|
||||
fixHTML(path.join(inpath, files[i]), path.join(outpath, files[i]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fixHTML(inpath, outpath);
|
||||
}
|
1
setup.go
1
setup.go
@ -143,6 +143,7 @@ func (st *Storage) loadLangSetup(filesystems ...fs.FS) error {
|
||||
patchLang(&lang.Login, &english.Login)
|
||||
patchLang(&lang.JellyfinEmby, &english.JellyfinEmby)
|
||||
patchLang(&lang.Email, &english.Email)
|
||||
patchLang(&lang.Messages, &english.Messages)
|
||||
patchLang(&lang.Notifications, &english.Notifications)
|
||||
patchLang(&lang.PasswordResets, &english.PasswordResets)
|
||||
patchLang(&lang.InviteEmails, &english.InviteEmails)
|
||||
|
@ -1,9 +1,14 @@
|
||||
all:
|
||||
-mkdir -p out
|
||||
cp index.html ../css/modal.css out/
|
||||
cp ../css/modal.css out/
|
||||
node ../scripts/missing-colors.js index.html out/index.html
|
||||
cp -r node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 out/
|
||||
npx esbuild --bundle ts/main.ts --outfile=out/main.js --minify
|
||||
-rm -r tempts
|
||||
cp -r ts tempts
|
||||
../scripts/dark-variant.sh tempts
|
||||
npx esbuild --bundle tempts/main.ts --outfile=out/main.js --minify
|
||||
npx esbuild --bundle base.css --outfile=out/bundle.css --external:remixicon.css --external:modal.css --minify
|
||||
npx tailwindcss -i out/bundle.css -o out/bundle.css
|
||||
cd out && npx uncss index.html --stylesheets bundle.css > _bundle.css; cd ..
|
||||
mv out/_bundle.css out/bundle.css
|
||||
cd out && npx uncss index.html --stylesheets remixicon.css > _remixicon.css; cd ..
|
||||
@ -13,10 +18,15 @@ all:
|
||||
|
||||
debug:
|
||||
-mkdir -p out
|
||||
cp index.html out/
|
||||
cp ../css/modal.css out/
|
||||
node ../scripts/missing-colors.js index.html out/index.html
|
||||
cp -r node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 out/
|
||||
-rm -r tempts
|
||||
cp -r ts tempts
|
||||
../scripts/dark-variant.sh tempts
|
||||
npx esbuild --bundle base.css --outfile=out/bundle.css --external:remixicon.css --minify
|
||||
npx esbuild --bundle ts/main.ts --sourcemap --outfile=out/main.js --minify
|
||||
npx tailwindcss -i out/bundle.css -o out/bundle.css
|
||||
cp ../static/* out/
|
||||
|
||||
monitor:
|
||||
|
@ -11,7 +11,3 @@ body {
|
||||
background: #AA5CC3;
|
||||
background: linear-gradient(90deg, #AA5CC3 0%, #00A4DC 100%) !important;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
</head>
|
||||
<body class="max-w-full overflow-x-hidden section">
|
||||
<div id="modal-deb" class="modal">
|
||||
<div class="modal-content wide card ~neutral">
|
||||
<div class="modal-content wide card">
|
||||
<span class="heading"> Debian/Ubuntu (apt)</span>
|
||||
<div class="mt-1">
|
||||
<pre style="margin: 0; line-height: 125%">curl https://apt.hrfee.dev/hrfee.pubkey.gpg | sudo apt-key add -
|
||||
@ -38,7 +38,7 @@ sudo apt-get install jfa-go-tray
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal-docker" class="modal">
|
||||
<div class="modal-content wide card ~neutral">
|
||||
<div class="modal-content wide card">
|
||||
<span class="heading"> Docker</span>
|
||||
<div class="mt-1">
|
||||
<pre style="margin: 0; line-height: 125%">docker create <span style="color: #BB6622; font-weight: bold">\</span>
|
||||
@ -53,7 +53,7 @@ sudo apt-get install jfa-go-tray
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-container" id="page-container">
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<div class="card ~neutral @low mb-1">
|
||||
<div class="row col flex center">
|
||||
<span class="heading welcome">jellyfin-accounts (go)</span>
|
||||
</div>
|
||||
@ -61,7 +61,7 @@ sudo apt-get install jfa-go-tray
|
||||
<p class="content">a better way to manage your Jellyfin users.</p>
|
||||
</div>
|
||||
<div class="row col flex center">
|
||||
<ul class="support">
|
||||
<ul class="support list-disc">
|
||||
<li>Send invite links to your users, let them sign up themselves</li>
|
||||
<li>Create setting profiles to restrict permissions of new users</li>
|
||||
<li>Handles password resets without your intervention</li>
|
||||
@ -74,47 +74,47 @@ sudo apt-get install jfa-go-tray
|
||||
</div>
|
||||
<span class="row col flex center supra">links</span>
|
||||
<div class="row col flex center">
|
||||
<a class="button ~neutral mr-half mt-1 mb-1" href="https://github.com/hrfee/jfa-go">github</a>
|
||||
<a class="button ~urge mt-1 mb-1 mr-half" href="https://wiki.jfa-go.com">wiki/docs</a>
|
||||
<a class="button ~positive mt-1 mb-1 mr-half" href="https://weblate.jfa-go.com">translation</a>
|
||||
<div class="dropdown mr-half" tabindex="0">
|
||||
<a class="button ~neutral mr-2 mt-1 mb-1" href="https://github.com/hrfee/jfa-go">github</a>
|
||||
<a class="button ~urge mt-1 mb-1 mr-2" href="https://wiki.jfa-go.com">wiki/docs</a>
|
||||
<a class="button ~positive mt-1 mb-1 mr-2" href="https://weblate.jfa-go.com">translation</a>
|
||||
<div class="dropdown mr-2" tabindex="0">
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button ~info mt-1 mb-1 dropdown-button">
|
||||
<i class="ri-hand-heart-line mr-half"></i>
|
||||
<i class="ri-hand-heart-line mr-2"></i>
|
||||
donate
|
||||
<span class="ml-1 chev"></span>
|
||||
<span class="ml-2 chev"></span>
|
||||
</a>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~info !low">
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button input ~neutral field mb-half lang-link">GitHub</a>
|
||||
<a href="https://ko-fi.com/hrfee" target="_blank" class="button input ~neutral field mb-half lang-link">Ko-fi</a>
|
||||
<div class="card @low">
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button input ~neutral field mb-2 lang-link">GitHub</a>
|
||||
<a href="https://ko-fi.com/hrfee" target="_blank" class="button input ~neutral field mb-2 lang-link">Ko-fi</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="button ~urge mt-1 mb-1 !normal discord" href="https://discord.com/invite/MrtvuQmyhP" target="_blank"><i class="ri-discord-line mr-half"></i>discord</a>
|
||||
<a class="button ~urge mt-1 mb-1 @low discord" href="https://discord.com/invite/MrtvuQmyhP" target="_blank"><i class="ri-discord-line mr-2"></i>discord</a>
|
||||
</div>
|
||||
<p class="row col flex center supra">downloads</p>
|
||||
<p class="row col flex center support">instructions can be found <a target="_blank" href="https://github.com/hrfee/jfa-go#install">here</a></p>
|
||||
<p class="row col flex center text-center support">note: tray icon builds should only be used on systems with a Desktop Interface, and require extra dependencies on linux, see the github README for more info.</p>
|
||||
<div class="row col flex center">
|
||||
<span class="button ~neutral !high mr-1 mt-1" id="download-stable">Stable</span>
|
||||
<span class="button ~neutral @high mr-1 mt-1" id="download-stable">Stable</span>
|
||||
<span class="button ~neutral mt-1 mr-1" id="download-unstable">Unstable</span>
|
||||
</div>
|
||||
<div class="mt-1" id="sect-stable">
|
||||
<p class="row center">Usually released once/twice every month, and aren't necessarily super stable.</p>
|
||||
<div class="row col flex center">
|
||||
<a class="button ~info mr-half mb-half lang-link" target="_blank" href="https://github.com/hrfee/jfa-go/releases">windows/mac/linux</a>
|
||||
<a class="button ~info mr-half mb-half lang-link" id="download-docker">docker</a>
|
||||
<a class="button ~info mr-half mb-half lang-link" id="download-deb">debian/ubuntu</a>
|
||||
<a class="button ~info mr-half mb-half lang-link" target="_blank" href="https://aur.archlinux.org/packages/jfa-go">arch (aur)</a>
|
||||
<a class="button ~info mr-half mb-half lang-link" target="_blank" href="https://aur.archlinux.org/packages/jfa-go-bin">arch (aur binary)</a>
|
||||
<a class="button ~info mr-2 mb-2 lang-link" target="_blank" href="https://github.com/hrfee/jfa-go/releases">windows/mac/linux</a>
|
||||
<a class="button ~info mr-2 mb-2 lang-link" id="download-docker">docker</a>
|
||||
<a class="button ~info mr-2 mb-2 lang-link" id="download-deb">debian/ubuntu</a>
|
||||
<a class="button ~info mr-2 mb-2 lang-link" target="_blank" href="https://aur.archlinux.org/packages/jfa-go">arch (aur)</a>
|
||||
<a class="button ~info mr-2 mb-2 lang-link" target="_blank" href="https://aur.archlinux.org/packages/jfa-go-bin">arch (aur binary)</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-1 unfocused" id="sect-unstable">
|
||||
<p class="row center">These are built on every commit, so may include incomplete/broken features. Take care.</p>
|
||||
<div class="row col flex center">
|
||||
<a class="button ~info mr-half mb-half lang-link" id="download-docker-unstable">docker</a>
|
||||
<a class="button ~info mr-half mb-half lang-link" id="download-deb-unstable">debian/ubuntu</a>
|
||||
<a class="button ~info mr-half mb-half lang-link" target="_blank" href="https://aur.archlinux.org/packages/jfa-go-git">arch (aur git)</a>
|
||||
<a class="button ~info mr-2 mb-2 lang-link" id="download-docker-unstable">docker</a>
|
||||
<a class="button ~info mr-2 mb-2 lang-link" id="download-deb-unstable">debian/ubuntu</a>
|
||||
<a class="button ~info mr-2 mb-2 lang-link" target="_blank" href="https://aur.archlinux.org/packages/jfa-go-git">arch (aur git)</a>
|
||||
</div>
|
||||
</div>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
|
1806
site/package-lock.json
generated
1806
site/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -9,9 +9,10 @@
|
||||
"author": "Harvey Tindall <hrfee@hrfee.dev>",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"a17t": "^0.5.1",
|
||||
"a17t": "^0.10.1",
|
||||
"esbuild": "^0.12.12",
|
||||
"remixicon": "^2.5.0",
|
||||
"tailwindcss": "^3.0.10",
|
||||
"uncss": "^0.17.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
26
site/tailwind.config.js
Normal file
26
site/tailwind.config.js
Normal file
@ -0,0 +1,26 @@
|
||||
let colors = require("tailwindcss/colors")
|
||||
let dark = require("../css/dark");
|
||||
|
||||
module.exports = {
|
||||
content: ["./index.html", "./out/main.js"],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
neutral: colors.slate,
|
||||
positive: colors.green,
|
||||
urge: colors.violet,
|
||||
warning: colors.yellow,
|
||||
info: colors.blue,
|
||||
critical: colors.red,
|
||||
d_neutral: dark.d_neutral,
|
||||
d_positive: dark.d_positive,
|
||||
d_urge: dark.d_urge,
|
||||
d_warning: dark.d_warning,
|
||||
d_info: dark.d_info,
|
||||
d_critical: dark.d_critical
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [require("a17t")],
|
||||
}
|
@ -29,8 +29,9 @@ const dockerUnstable = document.getElementById("docker-unstable");
|
||||
stableButton.onclick = () => {
|
||||
debUnstable.classList.add("unfocused");
|
||||
dockerUnstable.classList.add("unfocused");
|
||||
stableButton.classList.add("!high");
|
||||
unstableButton.classList.remove("!high");
|
||||
stableButton.classList.add("@high");
|
||||
stableButton.classList.remove("@low");
|
||||
unstableButton.classList.remove("@high");
|
||||
stableSect.classList.remove("unfocused");
|
||||
unstableSect.classList.add("unfocused");
|
||||
|
||||
@ -39,8 +40,9 @@ stableButton.onclick = () => {
|
||||
unstableButton.onclick = () => {
|
||||
debUnstable.classList.remove("unfocused");
|
||||
dockerUnstable.classList.remove("unfocused");
|
||||
unstableButton.classList.add("!high");
|
||||
stableButton.classList.remove("!high");
|
||||
unstableButton.classList.add("@high");
|
||||
unstableButton.classList.remove("@low");
|
||||
stableButton.classList.remove("@high");
|
||||
stableSect.classList.add("unfocused");
|
||||
unstableSect.classList.remove("unfocused");
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ export const loadBuilds = () => {
|
||||
for (let buildName in categories) {
|
||||
if (Object.keys(categories[buildName]).length == 1) {
|
||||
const button = document.createElement("a") as HTMLAnchorElement;
|
||||
button.classList.add("button", "~info", "mr-half", "mb-half", "lang-link");
|
||||
button.classList.add("button", "~info", "mr-2", "mb-2", "lang-link");
|
||||
button.target = "_blank";
|
||||
button.textContent = buildName.toLowerCase();
|
||||
button.href = urlBase + categories[buildName][Object.keys(categories[buildName])[0]];
|
||||
@ -34,16 +34,16 @@ export const loadBuilds = () => {
|
||||
dropdown.tabIndex = 0;
|
||||
dropdown.classList.add("dropdown");
|
||||
let innerHTML = `
|
||||
<span class="button ~info mr-half mb-half lang-link">
|
||||
<span class="button ~info mr-2 mb-2 lang-link">
|
||||
${buildName.toLowerCase()}
|
||||
<span class="ml-half chev"></span>
|
||||
<span class="ml-2 chev"></span>
|
||||
</span>
|
||||
<div class="dropdown-display above">
|
||||
<div class="card ~info !low">
|
||||
<div class="card @low">
|
||||
`;
|
||||
for (let arch in categories[buildName]) {
|
||||
innerHTML += `
|
||||
<a href="${urlBase + categories[buildName][arch]}" target="_blank" class="button input ~neutral field mb-half lang-link">${arch}</a>
|
||||
<a href="${urlBase + categories[buildName][arch]}" target="_blank" class="button input ~neutral field mb-2 lang-link">${arch}</a>
|
||||
`;
|
||||
}
|
||||
innerHTML += `
|
||||
|
26
tailwind.config.js
Normal file
26
tailwind.config.js
Normal file
@ -0,0 +1,26 @@
|
||||
let colors = require("tailwindcss/colors")
|
||||
let dark = require("./css/dark");
|
||||
|
||||
module.exports = {
|
||||
content: ["./data/html/*.html", "./build/data/html/*.html", "./ts/*.ts", "./ts/modules/*.ts"],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
neutral: colors.slate,
|
||||
positive: colors.green,
|
||||
urge: colors.violet,
|
||||
warning: colors.yellow,
|
||||
info: colors.blue,
|
||||
critical: colors.red,
|
||||
d_neutral: dark.d_neutral,
|
||||
d_positive: dark.d_positive,
|
||||
d_urge: dark.d_urge,
|
||||
d_warning: dark.d_warning,
|
||||
d_info: dark.d_info,
|
||||
d_critical: dark.d_critical
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [require("a17t")],
|
||||
}
|
21
ts/admin.ts
21
ts/admin.ts
@ -1,4 +1,4 @@
|
||||
import { toggleTheme, loadTheme } from "./modules/theme.js";
|
||||
import { nightwind } from "./modules/theme.js";
|
||||
import { lang, LangFile, loadLangSelector } from "./modules/lang.js";
|
||||
import { Modal } from "./modules/modal.js";
|
||||
import { Tabs } from "./modules/tabs.js";
|
||||
@ -9,26 +9,27 @@ import { ProfileEditor } from "./modules/profiles.js";
|
||||
import { _get, _post, notificationBox, whichAnimationEvent, toggleLoader } from "./modules/common.js";
|
||||
import { Updater } from "./modules/update.js";
|
||||
|
||||
loadTheme();
|
||||
let theme = new nightwind();
|
||||
|
||||
const themeButton = document.getElementById('button-theme') as HTMLSpanElement;
|
||||
const switchThemeIcon = () => {
|
||||
const icon = themeButton.childNodes[0] as HTMLElement;
|
||||
if (document.documentElement.classList.contains("dark-theme")) {
|
||||
if (document.documentElement.classList.contains("dark")) {
|
||||
icon.classList.add("ri-sun-line");
|
||||
icon.classList.remove("ri-moon-line");
|
||||
themeButton.classList.add("~warning");
|
||||
themeButton.classList.remove("~neutral");
|
||||
themeButton.classList.remove("!high");
|
||||
themeButton.classList.remove("@high");
|
||||
} else {
|
||||
icon.classList.add("ri-moon-line");
|
||||
icon.classList.remove("ri-sun-line");
|
||||
themeButton.classList.add("!high");
|
||||
themeButton.classList.add("@high");
|
||||
themeButton.classList.add("~neutral");
|
||||
themeButton.classList.remove("~warning");
|
||||
}
|
||||
};
|
||||
themeButton.onclick = () => {
|
||||
toggleTheme();
|
||||
theme.toggle();
|
||||
switchThemeIcon();
|
||||
}
|
||||
switchThemeIcon();
|
||||
@ -119,10 +120,10 @@ window.notifications = new notificationBox(document.getElementById('notification
|
||||
const user = document.getElementById('radio-use-user') as HTMLInputElement;
|
||||
const profileSelect = document.getElementById('modify-user-profiles') as HTMLDivElement;
|
||||
const userSelect = document.getElementById('modify-user-users') as HTMLDivElement;
|
||||
(user.nextElementSibling as HTMLSpanElement).classList.toggle('!normal');
|
||||
(user.nextElementSibling as HTMLSpanElement).classList.toggle('!high');
|
||||
(profile.nextElementSibling as HTMLSpanElement).classList.toggle('!normal');
|
||||
(profile.nextElementSibling as HTMLSpanElement).classList.toggle('!high');
|
||||
(user.nextElementSibling as HTMLSpanElement).classList.toggle('@low');
|
||||
(user.nextElementSibling as HTMLSpanElement).classList.toggle('@high');
|
||||
(profile.nextElementSibling as HTMLSpanElement).classList.toggle('@low');
|
||||
(profile.nextElementSibling as HTMLSpanElement).classList.toggle('@high');
|
||||
profileSelect.classList.toggle('unfocused');
|
||||
userSelect.classList.toggle('unfocused');
|
||||
}*/
|
||||
|
16
ts/crash.ts
16
ts/crash.ts
@ -11,17 +11,17 @@ const buttonChange = (type: string) => {
|
||||
if (type == "normal") {
|
||||
logSanitized.classList.add("unfocused");
|
||||
logNormal.classList.remove("unfocused");
|
||||
buttonNormal.classList.add("!high");
|
||||
buttonNormal.classList.remove("!normal");
|
||||
buttonSanitized.classList.add("!normal");
|
||||
buttonSanitized.classList.remove("!high");
|
||||
buttonNormal.classList.add("@high");
|
||||
buttonNormal.classList.remove("@low");
|
||||
buttonSanitized.classList.add("@low");
|
||||
buttonSanitized.classList.remove("@high");
|
||||
} else {
|
||||
logNormal.classList.add("unfocused");
|
||||
logSanitized.classList.remove("unfocused");
|
||||
buttonSanitized.classList.add("!high");
|
||||
buttonSanitized.classList.remove("!normal");
|
||||
buttonNormal.classList.add("!normal");
|
||||
buttonNormal.classList.remove("!high");
|
||||
buttonSanitized.classList.add("@high");
|
||||
buttonSanitized.classList.remove("@low");
|
||||
buttonNormal.classList.add("@low");
|
||||
buttonNormal.classList.remove("@high");
|
||||
}
|
||||
}
|
||||
buttonNormal.onclick = () => buttonChange("normal");
|
||||
|
@ -101,7 +101,7 @@ if (window.discordEnabled) {
|
||||
link.classList.add("subheading", "link-center");
|
||||
link.href = inv.invite;
|
||||
link.target = "_blank";
|
||||
link.innerHTML = `<span class="img-circle lg mr-1"><img class="img-circle" src="${inv.icon}" width="64" height="64"></span>${window.discordServerName}`;
|
||||
link.innerHTML = `<span class="img-circle lg mr-4"><img class="img-circle" src="${inv.icon}" width="64" height="64"></span>${window.discordServerName}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -86,10 +86,10 @@ class user implements User {
|
||||
get admin(): boolean { return this._admin.classList.contains("chip"); }
|
||||
set admin(state: boolean) {
|
||||
if (state) {
|
||||
this._admin.classList.add("chip", "~info", "ml-1");
|
||||
this._admin.classList.add("chip", "~info", "ml-4");
|
||||
this._admin.textContent = window.lang.strings("admin");
|
||||
} else {
|
||||
this._admin.classList.remove("chip", "~info", "ml-1");
|
||||
this._admin.classList.remove("chip", "~info", "ml-4");
|
||||
this._admin.textContent = "";
|
||||
}
|
||||
}
|
||||
@ -97,10 +97,10 @@ class user implements User {
|
||||
get disabled(): boolean { return this._disabled.classList.contains("chip"); }
|
||||
set disabled(state: boolean) {
|
||||
if (state) {
|
||||
this._disabled.classList.add("chip", "~warning", "ml-1");
|
||||
this._disabled.classList.add("chip", "~warning", "ml-4");
|
||||
this._disabled.textContent = window.lang.strings("disabled");
|
||||
} else {
|
||||
this._disabled.classList.remove("chip", "~warning", "ml-1");
|
||||
this._disabled.classList.remove("chip", "~warning", "ml-4");
|
||||
this._disabled.textContent = "";
|
||||
}
|
||||
}
|
||||
@ -130,30 +130,30 @@ class user implements User {
|
||||
const matrix = this._matrixID != "";
|
||||
if (!telegram && !discord && !matrix) return;
|
||||
let innerHTML = `
|
||||
<i class="icon ri-settings-2-line ml-half dropdown-button"></i>
|
||||
<i class="icon ri-settings-2-line ml-2 dropdown-button"></i>
|
||||
<div class="dropdown manual">
|
||||
<div class="dropdown-display lg">
|
||||
<div class="card ~neutral !low">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="supra sm">${window.lang.strings("contactThrough")}</span>
|
||||
<label class="row switch pb-1 mt-half">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-email">
|
||||
<label class="row switch pb-4 mt-2">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-email mr-2">
|
||||
</span>Email</span>
|
||||
</label>
|
||||
<div class="accounts-area-telegram">
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-telegram">
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-telegram mr-2">
|
||||
<span>Telegram</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="accounts-area-discord">
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-discord">
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-discord mr-2">
|
||||
<span>Discord</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="accounts-area-matrix">
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-matrix">
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-matrix mr-2">
|
||||
<span>Matrix</span>
|
||||
</label>
|
||||
</div>
|
||||
@ -193,8 +193,10 @@ class user implements User {
|
||||
if (!u) {
|
||||
this._notifyDropdown.querySelector(".accounts-area-matrix").classList.add("unfocused");
|
||||
this._matrix.innerHTML = `
|
||||
<span class="chip btn !low">${window.lang.strings("add")}</span>
|
||||
<input type="text" class="input ~neutral !normal stealth-input unfocused" placeholder="@user:riot.im">
|
||||
<div class="table-inline justify-center">
|
||||
<span class="chip btn @low"><i class="ri-link" alt="${window.lang.strings("add")}"></i></span>
|
||||
<input type="text" class="input ~neutral @low stealth-input unfocused" placeholder="@user:riot.im">
|
||||
</div>
|
||||
`;
|
||||
(this._matrix.querySelector("span") as HTMLSpanElement).onclick = this._addMatrix;
|
||||
} else {
|
||||
@ -212,15 +214,20 @@ class user implements User {
|
||||
|
||||
private _addMatrix = () => {
|
||||
const addButton = this._matrix.querySelector(".btn") as HTMLSpanElement;
|
||||
const icon = this._matrix.querySelector("i");
|
||||
const input = this._matrix.querySelector("input.stealth-input") as HTMLInputElement;
|
||||
const addIcon = addButton.querySelector("i");
|
||||
if (addButton.classList.contains("chip")) {
|
||||
input.classList.remove("unfocused");
|
||||
addButton.innerHTML = `<i class="ri-check-line"></i>`;
|
||||
addIcon.classList.add("ri-check-line");
|
||||
addIcon.classList.remove("ri-link");
|
||||
addButton.classList.remove("chip")
|
||||
if (icon) {
|
||||
icon.classList.add("unfocused");
|
||||
}
|
||||
const outerClickListener = (event: Event) => {
|
||||
if (!(event.target instanceof HTMLElement && (this._matrix.contains(event.target) || addButton.contains(event.target)))) {
|
||||
document.dispatchEvent(new CustomEvent("accounts-reload"));
|
||||
document.removeEventListener("click", outerClickListener);
|
||||
}
|
||||
};
|
||||
document.addEventListener("click", outerClickListener);
|
||||
} else {
|
||||
if (input.value.charAt(0) != "@" || !input.value.includes(":")) return;
|
||||
const send = {
|
||||
@ -257,7 +264,7 @@ class user implements User {
|
||||
this._telegramUsername = u;
|
||||
if (!u) {
|
||||
this._notifyDropdown.querySelector(".accounts-area-telegram").classList.add("unfocused");
|
||||
this._telegram.innerHTML = `<span class="chip btn !low">${window.lang.strings("add")}</span>`;
|
||||
this._telegram.innerHTML = `<div class="table-inline justify-center"><span class="chip btn @low"><i class="ri-link" alt="${window.lang.strings("add")}"></i></span></div>`;
|
||||
(this._telegram.querySelector("span") as HTMLSpanElement).onclick = this._addTelegram;
|
||||
} else {
|
||||
this._notifyDropdown.querySelector(".accounts-area-telegram").classList.remove("unfocused");
|
||||
@ -322,7 +329,7 @@ class user implements User {
|
||||
const lastNotifyMethod = this.lastNotifyMethod() == "discord";
|
||||
this._discordUsername = u;
|
||||
if (!u) {
|
||||
this._discord.innerHTML = `<span class="chip btn !low">Add</span>`;
|
||||
this._discord.innerHTML = `<div class="table-inline justify-center"><span class="chip btn @low"><i class="ri-link" alt="${window.lang.strings("add")}"></i></span></div>`;
|
||||
(this._discord.querySelector("span") as HTMLSpanElement).onclick = () => addDiscord(this.id);
|
||||
this._notifyDropdown.querySelector(".accounts-area-discord").classList.add("unfocused");
|
||||
} else {
|
||||
@ -380,8 +387,8 @@ class user implements User {
|
||||
this._row = document.createElement("tr") as HTMLTableRowElement;
|
||||
let innerHTML = `
|
||||
<td><input type="checkbox" value=""></td>
|
||||
<td><div class="table-inline"><span class="accounts-username"></span> <span class="accounts-admin"></span> <span class="accounts-disabled"></span></span></td>
|
||||
<td><div class="table-inline"><i class="icon ri-edit-line accounts-email-edit"></i><span class="accounts-email-container ml-half"></span></div></td>
|
||||
<td><div class="table-inline"><span class="accounts-username py-2"></span> <span class="accounts-admin"></span> <span class="accounts-disabled"></span></span></td>
|
||||
<td><div class="table-inline"><i class="icon ri-edit-line accounts-email-edit"></i><span class="accounts-email-container ml-2"></span></div></td>
|
||||
`;
|
||||
if (window.telegramEnabled) {
|
||||
innerHTML += `
|
||||
@ -400,10 +407,10 @@ class user implements User {
|
||||
}
|
||||
innerHTML += `
|
||||
<td class="accounts-expiry"></td>
|
||||
<td class="accounts-last-active"></td>
|
||||
<td class="accounts-last-active whitespace-nowrap"></td>
|
||||
`;
|
||||
this._row.innerHTML = innerHTML;
|
||||
const emailEditor = `<input type="email" class="input ~neutral !normal stealth-input">`;
|
||||
const emailEditor = `<input type="email" class="input ~neutral @low stealth-input">`;
|
||||
this._check = this._row.querySelector("input[type=checkbox]") as HTMLInputElement;
|
||||
this._username = this._row.querySelector(".accounts-username") as HTMLSpanElement;
|
||||
this._admin = this._row.querySelector(".accounts-admin") as HTMLSpanElement;
|
||||
@ -423,10 +430,10 @@ class user implements User {
|
||||
if (this._emailEditButton.classList.contains("ri-edit-line")) {
|
||||
this._email.innerHTML = emailEditor;
|
||||
this._email.querySelector("input").value = this._emailAddress;
|
||||
this._email.classList.remove("ml-half");
|
||||
this._email.classList.remove("ml-2");
|
||||
} else {
|
||||
this._email.textContent = this._emailAddress;
|
||||
this._email.classList.add("ml-half");
|
||||
this._email.classList.add("ml-2");
|
||||
}
|
||||
this._emailEditButton.classList.toggle("ri-check-line");
|
||||
this._emailEditButton.classList.toggle("ri-edit-line");
|
||||
@ -902,7 +909,7 @@ export class accountsList {
|
||||
if (req.readyState == 4) {
|
||||
const preview = document.getElementById("announce-preview") as HTMLDivElement;
|
||||
if (req.status != 200) {
|
||||
preview.innerHTML = `<pre class="preview-content" class="monospace"></pre>`;
|
||||
preview.innerHTML = `<pre class="preview-content" class="font-mono bg-inherit"></pre>`;
|
||||
window.modals.announce.show();
|
||||
this._previewLoaded = false;
|
||||
return;
|
||||
@ -910,7 +917,7 @@ export class accountsList {
|
||||
|
||||
let templ = req.response as templateEmail;
|
||||
if (!templ.html) {
|
||||
preview.innerHTML = `<pre class="preview-content" class="monospace"></pre>`;
|
||||
preview.innerHTML = `<pre class="preview-content" class="font-mono bg-inherit"></pre>`;
|
||||
this._previewLoaded = false;
|
||||
} else {
|
||||
preview.innerHTML = templ.html;
|
||||
@ -938,9 +945,9 @@ export class accountsList {
|
||||
dList.textContent = '';
|
||||
for (let name of list) {
|
||||
const el = document.createElement("div") as HTMLDivElement;
|
||||
el.classList.add("flex-expand", "ellipsis", "mt-half");
|
||||
el.classList.add("flex-expand", "ellipsis", "mt-2");
|
||||
el.innerHTML = `
|
||||
<span class="button ~neutral sm full-width accounts-announce-template-button">${name}</span><span class="button ~critical fr ml-1 accounts-announce-template-delete">×</span>
|
||||
<span class="button ~neutral sm full-width accounts-announce-template-button">${name}</span><span class="button ~critical fr ml-4 accounts-announce-template-delete">×</span>
|
||||
`;
|
||||
(el.querySelector("span.accounts-announce-template-button") as HTMLSpanElement).onclick = () => {
|
||||
_get("/users/announce/" + name, null, (req: XMLHttpRequest) => {
|
||||
@ -1281,17 +1288,17 @@ export class accountsList {
|
||||
if (this._modifySettingsProfile.checked) {
|
||||
this._userSelect.parentElement.classList.add("unfocused");
|
||||
this._profileSelect.parentElement.classList.remove("unfocused")
|
||||
profileSpan.classList.add("!high");
|
||||
profileSpan.classList.remove("!normal");
|
||||
userSpan.classList.remove("!high");
|
||||
userSpan.classList.add("!normal");
|
||||
profileSpan.classList.add("@high");
|
||||
profileSpan.classList.remove("@low");
|
||||
userSpan.classList.remove("@high");
|
||||
userSpan.classList.add("@low");
|
||||
} else {
|
||||
this._userSelect.parentElement.classList.remove("unfocused");
|
||||
this._profileSelect.parentElement.classList.add("unfocused");
|
||||
userSpan.classList.add("!high");
|
||||
userSpan.classList.remove("!normal");
|
||||
profileSpan.classList.remove("!high");
|
||||
profileSpan.classList.add("!normal");
|
||||
userSpan.classList.add("@high");
|
||||
userSpan.classList.remove("@low");
|
||||
profileSpan.classList.remove("@high");
|
||||
profileSpan.classList.add("@low");
|
||||
}
|
||||
};
|
||||
this._modifySettingsProfile.onchange = checkSource;
|
||||
|
@ -104,14 +104,14 @@ export class notificationBox implements NotificationBox {
|
||||
|
||||
private _error = (message: string): HTMLElement => {
|
||||
const noti = document.createElement('aside');
|
||||
noti.classList.add("aside", "~critical", "!normal", "mt-half", "notification-error");
|
||||
noti.classList.add("aside", "~critical", "@low", "mt-2", "notification-error");
|
||||
let error = "";
|
||||
if (window.lang) {
|
||||
error = window.lang.strings("error") + ":"
|
||||
}
|
||||
noti.innerHTML = `<strong>${error}</strong> ${message}`;
|
||||
const closeButton = document.createElement('span') as HTMLSpanElement;
|
||||
closeButton.classList.add("button", "~critical", "!low", "ml-1");
|
||||
closeButton.classList.add("button", "~critical", "@low", "ml-4");
|
||||
closeButton.innerHTML = `<i class="icon ri-close-line"></i>`;
|
||||
closeButton.onclick = () => { this._box.removeChild(noti); };
|
||||
noti.appendChild(closeButton);
|
||||
@ -120,10 +120,10 @@ export class notificationBox implements NotificationBox {
|
||||
|
||||
private _positive = (bold: string, message: string): HTMLElement => {
|
||||
const noti = document.createElement('aside');
|
||||
noti.classList.add("aside", "~positive", "!normal", "mt-half", "notification-positive");
|
||||
noti.classList.add("aside", "~positive", "@low", "mt-2", "notification-positive");
|
||||
noti.innerHTML = `<strong>${bold}</strong> ${message}`;
|
||||
const closeButton = document.createElement('span') as HTMLSpanElement;
|
||||
closeButton.classList.add("button", "~positive", "!low", "ml-1");
|
||||
closeButton.classList.add("button", "~positive", "@low", "ml-4");
|
||||
closeButton.innerHTML = `<i class="icon ri-close-line"></i>`;
|
||||
closeButton.onclick = () => { this._box.removeChild(noti); };
|
||||
noti.appendChild(closeButton);
|
||||
|
@ -22,13 +22,13 @@ export function newDiscordSearch(title: string, description: string, buttonText:
|
||||
}
|
||||
list.innerHTML = ``;
|
||||
addLoader(list);
|
||||
list.parentElement.classList.add("mb-1", "mt-1");
|
||||
list.parentElement.classList.add("mb-4", "mt-4");
|
||||
timer = setTimeout(() => {
|
||||
_get("/users/discord/" + input.value, null, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4) {
|
||||
if (req.status != 200) {
|
||||
removeLoader(list);
|
||||
list.parentElement.classList.remove("mb-1", "mt-1");
|
||||
list.parentElement.classList.remove("mb-4", "mt-4");
|
||||
return;
|
||||
}
|
||||
const users = req.response["users"] as Array<DiscordUser>;
|
||||
@ -39,18 +39,18 @@ export function newDiscordSearch(title: string, description: string, buttonText:
|
||||
<td class="img-circle sm">
|
||||
<img class="img-circle" src="${users[i].avatar_url}" width="32" height="32">
|
||||
</td>
|
||||
<td class="w-100 sm">
|
||||
<td class="sm">
|
||||
<p class="content">${users[i].name}</p>
|
||||
</td>
|
||||
<td class="sm">
|
||||
<span id="discord-user-${users[i].id}" class="button ~info !high">${buttonText}</span>
|
||||
<td class="sm float-right">
|
||||
<span id="discord-user-${users[i].id}" class="button ~info @high">${buttonText}</span>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
list.innerHTML = innerHTML;
|
||||
removeLoader(list);
|
||||
list.parentElement.classList.remove("mb-1", "mt-1");
|
||||
list.parentElement.classList.remove("mb-4", "mt-4");
|
||||
for (let i = 0; i < users.length; i++) {
|
||||
const button = document.getElementById(`discord-user-${users[i].id}`) as HTMLInputElement;
|
||||
button.onclick = () => buttonFunction(users[i], event.detail);
|
||||
|
@ -93,14 +93,14 @@ class DOMInvite implements Invite {
|
||||
const chip = container.querySelector("span.inv-email-chip");
|
||||
const tooltip = container.querySelector("span.content") as HTMLSpanElement;
|
||||
if (address == "") {
|
||||
container.classList.remove("mr-1");
|
||||
container.classList.remove("mr-4");
|
||||
icon.classList.remove("ri-mail-line");
|
||||
icon.classList.remove("ri-mail-close-line");
|
||||
chip.classList.remove("~neutral");
|
||||
chip.classList.remove("~critical");
|
||||
chip.classList.remove("chip");
|
||||
} else {
|
||||
container.classList.add("mr-1");
|
||||
container.classList.add("mr-4");
|
||||
chip.classList.add("chip");
|
||||
if (address.includes("Failed")) {
|
||||
icon.classList.remove("ri-mail-line");
|
||||
@ -251,14 +251,14 @@ class DOMInvite implements Invite {
|
||||
|
||||
this._header = document.createElement('div') as HTMLDivElement;
|
||||
this._container.appendChild(this._header);
|
||||
this._header.classList.add("card", "~neutral", "!normal", "inv-header", "elem-pad", "no-pad", "flex-expand", "row", "mt-half", "overflow-y");
|
||||
this._header.classList.add("card", "dark:~d_neutral", "@low", "inv-header", "elem-pad", "no-pad", "flex-expand", "row", "mt-2", "overflow-y");
|
||||
|
||||
this._codeArea = document.createElement('div') as HTMLDivElement;
|
||||
this._header.appendChild(this._codeArea);
|
||||
this._codeArea.classList.add("inv-codearea");
|
||||
this._codeArea.innerHTML = `
|
||||
<a class="invite-link code monospace mr-1" href=""></a>
|
||||
<span class="button ~info !normal" title="${window.lang.strings("copy")}"><i class="ri-file-copy-line"></i></span>
|
||||
<a class="invite-link code font-mono bg-inherit mr-4" href=""></a>
|
||||
<span class="button ~info @low" title="${window.lang.strings("copy")}"><i class="ri-file-copy-line"></i></span>
|
||||
`;
|
||||
const copyButton = this._codeArea.querySelector("span.button") as HTMLSpanElement;
|
||||
copyButton.onclick = () => {
|
||||
@ -284,8 +284,8 @@ class DOMInvite implements Invite {
|
||||
<span class="inv-email-chip"><i></i></span>
|
||||
<span class="content sm"></span>
|
||||
</div>
|
||||
<span class="inv-duration mr-1"></span>
|
||||
<span class="button ~critical !normal inv-delete">${window.lang.strings("delete")}</span>
|
||||
<span class="inv-duration mr-4"></span>
|
||||
<span class="button ~critical @low inv-delete">${window.lang.strings("delete")}</span>
|
||||
<label>
|
||||
<i class="icon clickable ri-arrow-down-s-line not-rotated"></i>
|
||||
<input class="inv-toggle-details unfocused" type="checkbox">
|
||||
@ -304,7 +304,7 @@ class DOMInvite implements Invite {
|
||||
|
||||
this._details = document.createElement('div') as HTMLDivElement;
|
||||
this._container.appendChild(this._details);
|
||||
this._details.classList.add("card", "~neutral", "!normal", "mt-half", "no-pad", "inv-details");
|
||||
this._details.classList.add("card", "~neutral", "@low", "mt-2", "no-pad", "inv-details");
|
||||
const detailsInner = document.createElement('div') as HTMLDivElement;
|
||||
this._details.appendChild(detailsInner);
|
||||
detailsInner.classList.add("inv-row", "flex-expand", "row", "elem-pad", "align-top");
|
||||
@ -313,8 +313,8 @@ class DOMInvite implements Invite {
|
||||
detailsInner.appendChild(this._left);
|
||||
this._left.classList.add("inv-profilearea");
|
||||
let innerHTML = `
|
||||
<p class="supra mb-1 top">${window.lang.strings("profile")}</p>
|
||||
<div class="select ~neutral !normal inv-profileselect inline-block">
|
||||
<p class="supra mb-2 top">${window.lang.strings("profile")}</p>
|
||||
<div class="select ~neutral @low inv-profileselect inline-block mb-2">
|
||||
<select>
|
||||
<option value="noProfile" selected>${window.lang.strings("inviteNoProfile")}</option>
|
||||
</select>
|
||||
@ -322,7 +322,7 @@ class DOMInvite implements Invite {
|
||||
`;
|
||||
if (window.notificationsEnabled) {
|
||||
innerHTML += `
|
||||
<p class="label supra">${window.lang.strings("notifyEvent")}</p>
|
||||
<p class="label supra mb-2">${window.lang.strings("notifyEvent")}</p>
|
||||
<label class="switch block">
|
||||
<input class="inv-notify-expiry" type="checkbox">
|
||||
<span>${window.lang.strings("notifyInviteExpiry")}</span>
|
||||
@ -348,14 +348,14 @@ class DOMInvite implements Invite {
|
||||
detailsInner.appendChild(this._middle);
|
||||
this._middle.classList.add("block");
|
||||
this._middle.innerHTML = `
|
||||
<p class="supra mb-1 top">${window.lang.strings("inviteDateCreated")} <strong class="inv-created"></strong></p>
|
||||
<p class="supra mb-1">${window.lang.strings("inviteRemainingUses")} <strong class="inv-remaining"></strong></p>
|
||||
<p class="supra mb-1"><span class="user-expiry"></span> <strong class="user-expiry-time"></strong></p>
|
||||
<p class="supra mb-4 top">${window.lang.strings("inviteDateCreated")} <strong class="inv-created"></strong></p>
|
||||
<p class="supra mb-4">${window.lang.strings("inviteRemainingUses")} <strong class="inv-remaining"></strong></p>
|
||||
<p class="supra mb-4"><span class="user-expiry"></span> <strong class="user-expiry-time"></strong></p>
|
||||
`;
|
||||
|
||||
this._right = document.createElement('div') as HTMLDivElement;
|
||||
detailsInner.appendChild(this._right);
|
||||
this._right.classList.add("card", "~neutral", "!low", "inv-created-users");
|
||||
this._right.classList.add("card", "~neutral", "@low", "inv-created-users");
|
||||
this._right.innerHTML = `<strong class="supra table-header">${window.lang.strings("inviteUsersCreated")}</strong>`;
|
||||
this._userTable = document.createElement('div') as HTMLDivElement;
|
||||
this._right.appendChild(this._userTable);
|
||||
@ -425,9 +425,9 @@ export class inviteList implements inviteList {
|
||||
this._list.classList.add("empty");
|
||||
this._list.innerHTML = `
|
||||
<div class="inv inv-empty">
|
||||
<div class="card ~neutral !normal inv-header flex-expand mt-half">
|
||||
<div class="card dark:~d_neutral @low inv-header flex-expand mt-2">
|
||||
<div class="inv-codearea">
|
||||
<span class="code monospace">${window.lang.strings("inviteNoInvites")}</span>
|
||||
<span class="code font-mono bg-inherit">${window.lang.strings("inviteNoInvites")}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -787,17 +787,17 @@ export class createInvite {
|
||||
if (this._invDurationButton.checked) {
|
||||
this._invDuration.classList.remove("unfocused");
|
||||
this._userExpiry.classList.add("unfocused");
|
||||
invSpan.classList.add("!high");
|
||||
invSpan.classList.remove("!normal");
|
||||
userSpan.classList.add("!normal");
|
||||
userSpan.classList.remove("!high");
|
||||
invSpan.classList.add("@high");
|
||||
invSpan.classList.remove("@low");
|
||||
userSpan.classList.add("@low");
|
||||
userSpan.classList.remove("@high");
|
||||
} else if (this._userExpiryButton.checked) {
|
||||
this._userExpiry.classList.remove("unfocused");
|
||||
this._invDuration.classList.add("unfocused");
|
||||
invSpan.classList.add("!normal");
|
||||
invSpan.classList.remove("!high");
|
||||
userSpan.classList.add("!high");
|
||||
userSpan.classList.remove("!normal");
|
||||
invSpan.classList.add("@low");
|
||||
invSpan.classList.remove("@high");
|
||||
userSpan.classList.add("@high");
|
||||
userSpan.classList.remove("@low");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -68,6 +68,8 @@ export const loadLangSelector = (page: string) => {
|
||||
t12.checked = false;
|
||||
}
|
||||
}
|
||||
let queryString = new URLSearchParams(window.location.search);
|
||||
if (queryString.has("lang")) queryString.delete("lang");
|
||||
_get("/lang/" + page, null, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4) {
|
||||
if (req.status != 200) {
|
||||
@ -77,7 +79,9 @@ export const loadLangSelector = (page: string) => {
|
||||
const list = document.getElementById("lang-list") as HTMLDivElement;
|
||||
let innerHTML = '';
|
||||
for (let code in req.response) {
|
||||
innerHTML += `<a href="?lang=${code}" class="button input ~neutral field mb-half lang-link">${req.response[code]}</a>`;
|
||||
queryString.set("lang", code);
|
||||
innerHTML += `<a href="?${queryString.toString()}" class="button w-100 al justify-start ~neutral mb-2 lang-link">${req.response[code]}</a>`;
|
||||
queryString.delete("lang");
|
||||
}
|
||||
list.innerHTML = innerHTML;
|
||||
}
|
||||
|
@ -23,10 +23,10 @@ class profile implements Profile {
|
||||
get admin(): boolean { return this._adminChip.classList.contains("chip"); }
|
||||
set admin(state: boolean) {
|
||||
if (state) {
|
||||
this._adminChip.classList.add("chip", "~info", "ml-half");
|
||||
this._adminChip.classList.add("chip", "~info", "ml-2");
|
||||
this._adminChip.textContent = "Admin";
|
||||
} else {
|
||||
this._adminChip.classList.remove("chip", "~info", "ml-half");
|
||||
this._adminChip.classList.remove("chip", "~info", "ml-2");
|
||||
this._adminChip.textContent = "";
|
||||
}
|
||||
}
|
||||
@ -62,12 +62,12 @@ class profile implements Profile {
|
||||
<td><input type="radio" name="profile-default"></td>
|
||||
`;
|
||||
if (window.ombiEnabled) innerHTML += `
|
||||
<td><span class="button !normal profile-ombi"></span></td>
|
||||
<td><span class="button @low profile-ombi"></span></td>
|
||||
`;
|
||||
innerHTML += `
|
||||
<td class="profile-from ellipsis"></td>
|
||||
<td class="profile-libraries"></td>
|
||||
<td><span class="button ~critical !normal">${window.lang.strings("delete")}</span></td>
|
||||
<td><span class="button ~critical @low">${window.lang.strings("delete")}</span></td>
|
||||
`;
|
||||
this._row.innerHTML = innerHTML;
|
||||
this._name = this._row.querySelector("b.profile-name");
|
||||
|
@ -91,10 +91,10 @@ class DOMInput {
|
||||
get requires_restart(): boolean { return this._restart.classList.contains("badge"); }
|
||||
set requires_restart(state: boolean) {
|
||||
if (state) {
|
||||
this._restart.classList.add("badge", "~info");
|
||||
this._restart.classList.add("badge", "~info", "dark:~d_warning");
|
||||
this._restart.textContent = "R";
|
||||
} else {
|
||||
this._restart.classList.remove("badge", "~info");
|
||||
this._restart.classList.remove("badge", "~info", "dark:~d_warning");
|
||||
this._restart.textContent = "";
|
||||
}
|
||||
}
|
||||
@ -109,7 +109,7 @@ class DOMInput {
|
||||
<i class="icon ri-information-line"></i>
|
||||
<span class="content sm"></span>
|
||||
</div>
|
||||
<input type="${inputType}" class="input ~neutral !normal mt-half mb-half">
|
||||
<input type="${inputType}" class="input ~neutral @low mt-2 mb-2">
|
||||
</label>
|
||||
`;
|
||||
this._tooltip = this._container.querySelector("div.setting-tooltip") as HTMLDivElement;
|
||||
@ -250,10 +250,10 @@ class DOMBool implements SBool {
|
||||
get requires_restart(): boolean { return this._restart.classList.contains("badge"); }
|
||||
set requires_restart(state: boolean) {
|
||||
if (state) {
|
||||
this._restart.classList.add("badge", "~info");
|
||||
this._restart.classList.add("badge", "~info", "dark:~d_warning");
|
||||
this._restart.textContent = "R";
|
||||
} else {
|
||||
this._restart.classList.remove("badge", "~info");
|
||||
this._restart.classList.remove("badge", "~info", "dark:~d_warning");
|
||||
this._restart.textContent = "";
|
||||
}
|
||||
}
|
||||
@ -263,7 +263,7 @@ class DOMBool implements SBool {
|
||||
this._container = document.createElement("div");
|
||||
this._container.classList.add("setting");
|
||||
this._container.innerHTML = `
|
||||
<label class="switch mb-half">
|
||||
<label class="switch mb-2">
|
||||
<input type="checkbox">
|
||||
<span class="setting-label"></span> <span class="setting-required"></span> <span class="setting-restart"></span>
|
||||
<div class="setting-tooltip tooltip right unfocused">
|
||||
@ -372,10 +372,10 @@ class DOMSelect implements SSelect {
|
||||
get requires_restart(): boolean { return this._restart.classList.contains("badge"); }
|
||||
set requires_restart(state: boolean) {
|
||||
if (state) {
|
||||
this._restart.classList.add("badge", "~info");
|
||||
this._restart.classList.add("badge", "~info", "dark:~d_warning");
|
||||
this._restart.textContent = "R";
|
||||
} else {
|
||||
this._restart.classList.remove("badge", "~info");
|
||||
this._restart.classList.remove("badge", "~info", "dark:~d_warning");
|
||||
this._restart.textContent = "";
|
||||
}
|
||||
}
|
||||
@ -403,7 +403,7 @@ class DOMSelect implements SSelect {
|
||||
<i class="icon ri-information-line"></i>
|
||||
<span class="content sm"></span>
|
||||
</div>
|
||||
<div class="select ~neutral !normal mt-half mb-half">
|
||||
<div class="select ~neutral @low mt-2 mb-2">
|
||||
<select class="settings-select"></select>
|
||||
</div>
|
||||
</label>
|
||||
@ -436,7 +436,7 @@ class DOMSelect implements SSelect {
|
||||
message.innerHTML = window.lang.var("strings",
|
||||
"settingsRequiredOrRestartMessage",
|
||||
`<span class="badge ~critical">*</span>`,
|
||||
`<span class="badge ~info">R</span>`
|
||||
`<span class="badge ~info dark:~d_warning">R</span>`
|
||||
);
|
||||
|
||||
this.update(setting);
|
||||
@ -472,7 +472,7 @@ class sectionPanel {
|
||||
this._section.classList.add("settings-section", "unfocused");
|
||||
this._section.innerHTML = `
|
||||
<span class="heading">${s.meta.name}</span>
|
||||
<p class="support lg">${s.meta.description}</p>
|
||||
<p class="support lg my-2">${s.meta.description}</p>
|
||||
`;
|
||||
|
||||
this.update(s);
|
||||
@ -549,7 +549,7 @@ export class settingsList {
|
||||
this._sections[name] = section;
|
||||
this._panel.appendChild(this._sections[name].asElement());
|
||||
const button = document.createElement("span") as HTMLSpanElement;
|
||||
button.classList.add("button", "~neutral", "!low", "settings-section-button", "mb-half");
|
||||
button.classList.add("button", "~neutral", "@low", "settings-section-button", "justify-between", "mb-2");
|
||||
button.textContent = s.meta.name;
|
||||
if (subButton) { button.appendChild(subButton); }
|
||||
button.onclick = () => { this._showPanel(name); };
|
||||
@ -717,7 +717,7 @@ export class settingsList {
|
||||
const editButton = document.createElement("div");
|
||||
editButton.classList.add("tooltip", "left");
|
||||
editButton.innerHTML = `
|
||||
<span class="button ~neutral !normal">
|
||||
<span class="button ~neutral @low">
|
||||
<i class="icon ri-edit-line"></i>
|
||||
</span>
|
||||
<span class="content sm">
|
||||
@ -738,7 +738,7 @@ export class settingsList {
|
||||
const addButton = document.createElement("div");
|
||||
addButton.classList.add("tooltip", "left");
|
||||
addButton.innerHTML = `
|
||||
<span class="button ~neutral !normal">+</span>
|
||||
<span class="button ~neutral @low">+</span>
|
||||
<span class="content sm">
|
||||
${window.lang.strings("linkMatrix")}
|
||||
</span>
|
||||
@ -804,7 +804,7 @@ class EmailEditor {
|
||||
this._templ = req.response as templateEmail;
|
||||
this._textArea.value = this._templ.content;
|
||||
if (this._templ.html == "") {
|
||||
this._preview.innerHTML = `<pre class="preview-content" class="monospace"></pre>`;
|
||||
this._preview.innerHTML = `<pre class="preview-content" class="font-mono bg-inherit"></pre>`;
|
||||
} else {
|
||||
this._preview.innerHTML = this._templ.html;
|
||||
}
|
||||
@ -815,7 +815,7 @@ class EmailEditor {
|
||||
let innerHTML = '';
|
||||
for (let i = 0; i < this._templ.variables.length; i++) {
|
||||
let ci = i % colors.length;
|
||||
innerHTML += '<span class="button ~' + colors[ci] +' !normal mb-1" style="margin-left: 0.25rem; margin-right: 0.25rem;"></span>'
|
||||
innerHTML += '<span class="button ~' + colors[ci] +' @low mb-4" style="margin-left: 0.25rem; margin-right: 0.25rem;"></span>'
|
||||
}
|
||||
if (this._templ.variables.length == 0) {
|
||||
this._variablesLabel.classList.add("unfocused");
|
||||
@ -825,7 +825,7 @@ class EmailEditor {
|
||||
this._variables.innerHTML = innerHTML
|
||||
let buttons = this._variables.querySelectorAll("span.button") as NodeListOf<HTMLSpanElement>;
|
||||
for (let i = 0; i < this._templ.variables.length; i++) {
|
||||
buttons[i].innerHTML = `<span class="monospace">` + this._templ.variables[i] + `</span>`;
|
||||
buttons[i].innerHTML = `<span class="font-mono bg-inherit">` + this._templ.variables[i] + `</span>`;
|
||||
buttons[i].onclick = () => {
|
||||
insertText(this._textArea, this._templ.variables[i]);
|
||||
this.loadPreview();
|
||||
@ -839,13 +839,13 @@ class EmailEditor {
|
||||
} else {
|
||||
for (let i = this._templ.conditionals.length-1; i >= 0; i--) {
|
||||
let ci = i % colors.length;
|
||||
innerHTML += '<span class="button ~' + colors[ci] +' !normal mb-1" style="margin-left: 0.25rem; margin-right: 0.25rem;"></span>'
|
||||
innerHTML += '<span class="button ~' + colors[ci] +' @low mb-4" style="margin-left: 0.25rem; margin-right: 0.25rem;"></span>'
|
||||
}
|
||||
this._conditionalsLabel.classList.remove("unfocused");
|
||||
this._conditionals.innerHTML = innerHTML
|
||||
buttons = this._conditionals.querySelectorAll("span.button") as NodeListOf<HTMLSpanElement>;
|
||||
for (let i = 0; i < this._templ.conditionals.length; i++) {
|
||||
buttons[i].innerHTML = `<span class="monospace">{if ` + this._templ.conditionals[i].slice(1) + `</span>`;
|
||||
buttons[i].innerHTML = `<span class="font-mono bg-inherit">{if ` + this._templ.conditionals[i].slice(1) + `</span>`;
|
||||
buttons[i].onclick = () => {
|
||||
insertText(this._textArea, "{if " + this._templ.conditionals[i].slice(1) + "{endif}");
|
||||
this.loadPreview();
|
||||
@ -902,15 +902,16 @@ class EmailEditor {
|
||||
}
|
||||
tr.innerHTML = `
|
||||
<td>${this._names[id].name}</td>
|
||||
<td>${resetButton}</td>
|
||||
<td><span class="button ~info !normal" title="${window.lang.get("strings", "edit")}"><i class="icon ri-edit-line"></i></span></td>
|
||||
<td class="table-inline justify-center"><span class="customize-reset">${resetButton}</span></td>
|
||||
<td><span class="button ~info @low" title="${window.lang.get("strings", "edit")}"><i class="icon ri-edit-line"></i></span></td>
|
||||
`;
|
||||
(tr.querySelector("span.button") as HTMLSpanElement).onclick = () => {
|
||||
window.modals.customizeEmails.close()
|
||||
this.loadEditor(id);
|
||||
};
|
||||
if (this._names[id].enabled) {
|
||||
const rb = tr.querySelector("i.ri-restart-line") as HTMLElement;
|
||||
const rb = tr.querySelector("span.customize-reset") as HTMLElement;
|
||||
rb.classList.add("button");
|
||||
rb.onclick = () => _post("/config/emails/" + id + "/state/disable", null, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4) {
|
||||
if (req.status != 200 && req.status != 204) {
|
||||
|
@ -1,19 +1,67 @@
|
||||
export function toggleTheme() {
|
||||
document.documentElement.classList.toggle('dark-theme');
|
||||
document.documentElement.classList.toggle('light-theme');
|
||||
localStorage.setItem('theme', document.documentElement.classList.contains('dark-theme') ? "dark" : "light");
|
||||
document.documentElement.classList.toggle('dark');
|
||||
document.documentElement.classList.toggle('light');
|
||||
localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? "dark" : "light");
|
||||
}
|
||||
|
||||
export function loadTheme() {
|
||||
const theme = localStorage.getItem("theme");
|
||||
if (theme == "dark") {
|
||||
document.documentElement.classList.add('dark-theme');
|
||||
document.documentElement.classList.remove('light-theme');
|
||||
document.documentElement.classList.add('dark');
|
||||
document.documentElement.classList.remove('light');
|
||||
} else if (theme == "light") {
|
||||
document.documentElement.classList.add('light-theme');
|
||||
document.documentElement.classList.remove('dark-theme');
|
||||
document.documentElement.classList.add('light');
|
||||
document.documentElement.classList.remove('dark');
|
||||
} else if (window.matchMedia('(prefers-color-scheme: dark)').media !== 'not all') {
|
||||
document.documentElement.classList.add('dark-theme');
|
||||
document.documentElement.classList.remove('light-theme');
|
||||
document.documentElement.classList.add('dark');
|
||||
document.documentElement.classList.remove('light');
|
||||
}
|
||||
}
|
||||
|
||||
export class nightwind {
|
||||
beforeTransition = () => {
|
||||
const doc = document.documentElement;
|
||||
const onTransitionDone = () => {
|
||||
doc.classList.remove('nightwind');
|
||||
doc.removeEventListener('transitionend', onTransitionDone);
|
||||
}
|
||||
doc.addEventListener('transitionend', onTransitionDone);
|
||||
if (!doc.classList.contains('nightwind')) {
|
||||
doc.classList.add('nightwind');
|
||||
}
|
||||
};
|
||||
constructor() {
|
||||
const theme = localStorage.getItem("theme");
|
||||
if (theme == "dark") {
|
||||
this.enable(true);
|
||||
} else if (theme == "light") {
|
||||
this.enable(false);
|
||||
} else if (window.matchMedia('(prefers-color-scheme: dark)').media !== 'not all') {
|
||||
this.enable(true);
|
||||
}
|
||||
}
|
||||
|
||||
toggle = () => {
|
||||
this.beforeTransition();
|
||||
if (!document.documentElement.classList.contains('dark')) {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? "dark" : "light");
|
||||
};
|
||||
|
||||
enable = (dark: boolean) => {
|
||||
const mode = dark ? "dark" : "light";
|
||||
const opposite = dark ? "light" : "dark";
|
||||
|
||||
localStorage.setItem('theme', dark ? "dark" : "light");
|
||||
|
||||
this.beforeTransition();
|
||||
|
||||
if (document.documentElement.classList.contains(opposite)) {
|
||||
document.documentElement.classList.remove(opposite);
|
||||
}
|
||||
document.documentElement.classList.add(mode);
|
||||
};
|
||||
}
|
||||
|
@ -38,9 +38,9 @@ export class Updater implements updater {
|
||||
const el = document.getElementById("update-description") as HTMLParagraphElement;
|
||||
el.textContent = description;
|
||||
if (this.version == "git") {
|
||||
el.classList.add("monospace");
|
||||
el.classList.add("font-mono", "bg-inherit");
|
||||
} else {
|
||||
el.classList.remove("monospace");
|
||||
el.classList.remove("font-mono", "bg-inherit");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Modal } from "./modules/modal.js";
|
||||
import { initValidator } from "./modules/validator.js";
|
||||
import { _post, addLoader, removeLoader } from "./modules/common.js";
|
||||
import { loadLangSelector } from "./modules/lang.js";
|
||||
|
||||
interface formWindow extends Window {
|
||||
invalidPassword: string;
|
||||
@ -29,6 +30,8 @@ interface formWindow extends Window {
|
||||
userExpiryMessage: string;
|
||||
}
|
||||
|
||||
loadLangSelector("pwr");
|
||||
|
||||
declare var window: formWindow;
|
||||
|
||||
const form = document.getElementById("form-create") as HTMLFormElement;
|
||||
|
Loading…
Reference in New Issue
Block a user