mirror of
https://github.com/hrfee/jfa-go.git
synced 2025-01-01 14:00:12 +00:00
Compare commits
61 Commits
1f9dce1870
...
c3fb00a307
Author | SHA1 | Date | |
---|---|---|---|
c3fb00a307 | |||
988829a6db | |||
a6a7710a79 | |||
873afb47cd | |||
ea99966057 | |||
aaed272bf2 | |||
e6775cd2d1 | |||
98a9e20cc0 | |||
ee37588959 | |||
cb12c6f441 | |||
72cf3e2240 | |||
815bdc35ac | |||
0330540f87 | |||
fefe2d82a4 | |||
1af8d1f77d | |||
4c653fea36 | |||
2ee0ed55f6 | |||
94981f4891 | |||
f72def0399 | |||
81fb0fc69f | |||
c3af0f4380 | |||
3a9e4950d4 | |||
06dada297b | |||
2b55a1873c | |||
c2e68bdc77 | |||
e1c3b312ff | |||
e235ed9fda | |||
5cda12dd3b | |||
a9d48083fd | |||
e28c50401e | |||
4a3b015a40 | |||
1a6727312c | |||
91d3d2596e | |||
192c9a4764 | |||
173c38563e | |||
d061721f56 | |||
218882b7c6 | |||
fed3ee4c4f | |||
8eed4b0127 | |||
c09ffb49e7 | |||
|
f331f4eb92 | ||
|
629b669c64 | ||
|
2dab900748 | ||
|
f864097f2e | ||
2c8be42bbc | |||
6691ae27f4 | |||
23fecb16b2 | |||
b037b08152 | |||
|
46fe3a7f5d | ||
|
61bd62403f | ||
|
5893d4b855 | ||
|
8016e6f211 | ||
|
a5560b04bd | ||
|
b9e171b1fd | ||
|
a633425baa | ||
|
e29e89c618 | ||
|
62c986161c | ||
|
6279c73402 | ||
|
22e103837f | ||
|
feba6e7bae | ||
95a6b48c3e |
274
.drone.yml
274
.drone.yml
@ -9,7 +9,7 @@ steps:
|
||||
commands:
|
||||
- git fetch --tags
|
||||
- name: release
|
||||
image: golang:latest
|
||||
image: golang:1.16rc1-buster
|
||||
environment:
|
||||
GITHUB_TOKEN:
|
||||
from_secret: github_token
|
||||
@ -19,11 +19,139 @@ steps:
|
||||
- (curl -sL https://deb.nodesource.com/setup_14.x | bash -)
|
||||
- apt install nodejs
|
||||
- curl -sL https://git.io/goreleaser | bash
|
||||
when:
|
||||
event: tag
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
branch:
|
||||
- main
|
||||
---
|
||||
name: jfa-go-1.16-git
|
||||
name: amd64-docker
|
||||
kind: pipeline
|
||||
type: docker
|
||||
steps:
|
||||
- name: fetch
|
||||
image: docker:git
|
||||
commands:
|
||||
- git fetch --tags
|
||||
- name: build
|
||||
image: plugins/docker
|
||||
settings:
|
||||
username: hrfee
|
||||
password:
|
||||
from_secret: docker_key
|
||||
repo: hrfee/jfa-go
|
||||
tags: manifest-latest-amd64
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
branch:
|
||||
- main
|
||||
---
|
||||
name: arm64-docker
|
||||
kind: pipeline
|
||||
type: docker
|
||||
|
||||
steps:
|
||||
- name: arm64-ssh
|
||||
image: appleboy/drone-ssh
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
path: /root/drone_rsa
|
||||
settings:
|
||||
host:
|
||||
from_secret: ssh_host
|
||||
username:
|
||||
from_secret: ssh_username
|
||||
port:
|
||||
from_secret: ssh_port
|
||||
volumes:
|
||||
- /root/.ssh/docker-build:/root/drone_rsa
|
||||
key_path: /root/drone_rsa
|
||||
command_timeout: 50m
|
||||
script:
|
||||
- /home/rock64/jfa-go-build/build-stable.sh
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
branch:
|
||||
- main
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
host:
|
||||
path: /root/.ssh/docker-build
|
||||
---
|
||||
name: armhf-docker
|
||||
kind: pipeline
|
||||
type: docker
|
||||
|
||||
steps:
|
||||
- name: armhf-ssh
|
||||
image: appleboy/drone-ssh
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
path: /root/drone_rsa
|
||||
settings:
|
||||
host:
|
||||
from_secret: ssh_host
|
||||
username:
|
||||
from_secret: ssh_username
|
||||
port:
|
||||
from_secret: ssh_port
|
||||
volumes:
|
||||
- /root/.ssh/docker-build:/root/drone_rsa
|
||||
key_path: /root/drone_rsa
|
||||
command_timeout: 50m
|
||||
script:
|
||||
- ssh pi /home/pi/jfa-go-build/build-stable.sh
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
branch:
|
||||
- main
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
host:
|
||||
path: /root/.ssh/docker-build
|
||||
---
|
||||
name: docker-manifest
|
||||
kind: pipeline
|
||||
type: docker
|
||||
|
||||
steps:
|
||||
- name: manifest
|
||||
image: appleboy/drone-ssh
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
path: /root/drone_rsa
|
||||
settings:
|
||||
host:
|
||||
from_secret: ssh_host
|
||||
username:
|
||||
from_secret: ssh_username
|
||||
port:
|
||||
from_secret: ssh_port
|
||||
volumes:
|
||||
- /root/.ssh/docker-build:/root/drone_rsa
|
||||
key_path: /root/drone_rsa
|
||||
command_timeout: 50m
|
||||
script:
|
||||
- env DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create hrfee/jfa-go:latest --amend hrfee/jfa-go:manifest-latest-amd64 --amend hrfee/jfa-go:manifest-latest-arm64 --amend hrfee/jfa-go:manifest-latest-armhf
|
||||
- env DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push hrfee/jfa-go:latest
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
branch:
|
||||
- main
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
host:
|
||||
path: /root/.ssh/docker-build
|
||||
depends_on:
|
||||
- amd64-docker
|
||||
- arm64-docker
|
||||
- armhf-docker
|
||||
---
|
||||
name: jfa-go-git
|
||||
kind: pipeline
|
||||
type: docker
|
||||
|
||||
@ -54,13 +182,146 @@ trigger:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
name: amd64-docker-git
|
||||
kind: pipeline
|
||||
type: docker
|
||||
steps:
|
||||
- name: build
|
||||
image: plugins/docker
|
||||
settings:
|
||||
username: hrfee
|
||||
password:
|
||||
from_secret: docker_key
|
||||
repo: hrfee/jfa-go
|
||||
tags: manifest-unstable-amd64
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
name: arm64-docker-git
|
||||
kind: pipeline
|
||||
type: docker
|
||||
|
||||
steps:
|
||||
- name: arm64-ssh
|
||||
image: appleboy/drone-ssh
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
path: /root/drone_rsa
|
||||
settings:
|
||||
host:
|
||||
from_secret: ssh_host
|
||||
username:
|
||||
from_secret: ssh_username
|
||||
port:
|
||||
from_secret: ssh_port
|
||||
volumes:
|
||||
- /root/.ssh/docker-build:/root/drone_rsa
|
||||
key_path: /root/drone_rsa
|
||||
command_timeout: 50m
|
||||
script:
|
||||
- /home/rock64/jfa-go-build/build.sh
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
host:
|
||||
path: /root/.ssh/docker-build
|
||||
---
|
||||
name: armhf-docker-git
|
||||
kind: pipeline
|
||||
type: docker
|
||||
|
||||
steps:
|
||||
- name: armhf-ssh
|
||||
image: appleboy/drone-ssh
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
path: /root/drone_rsa
|
||||
settings:
|
||||
host:
|
||||
from_secret: ssh_host
|
||||
username:
|
||||
from_secret: ssh_username
|
||||
port:
|
||||
from_secret: ssh_port
|
||||
volumes:
|
||||
- /root/.ssh/docker-build:/root/drone_rsa
|
||||
key_path: /root/drone_rsa
|
||||
command_timeout: 50m
|
||||
script:
|
||||
- ssh pi /home/pi/jfa-go-build/build.sh
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
host:
|
||||
path: /root/.ssh/docker-build
|
||||
---
|
||||
name: docker-manifest-unstable
|
||||
kind: pipeline
|
||||
type: docker
|
||||
|
||||
steps:
|
||||
- name: manifest
|
||||
image: appleboy/drone-ssh
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
path: /root/drone_rsa
|
||||
settings:
|
||||
host:
|
||||
from_secret: ssh_host
|
||||
username:
|
||||
from_secret: ssh_username
|
||||
port:
|
||||
from_secret: ssh_port
|
||||
volumes:
|
||||
- /root/.ssh/docker-build:/root/drone_rsa
|
||||
key_path: /root/drone_rsa
|
||||
command_timeout: 50m
|
||||
script:
|
||||
- env DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create hrfee/jfa-go:unstable --amend hrfee/jfa-go:manifest-unstable-amd64 --amend hrfee/jfa-go:manifest-unstable-arm64 --amend hrfee/jfa-go:manifest-unstable-armhf
|
||||
- env DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push hrfee/jfa-go:unstable
|
||||
depends_on:
|
||||
- amd64-docker-git
|
||||
- arm64-docker-git
|
||||
- armhf-docker-git
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
host:
|
||||
path: /root/.ssh/docker-build
|
||||
---
|
||||
name: jfa-go-pr
|
||||
kind: pipeline
|
||||
type: docker
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: golang:latest
|
||||
image: golang:1.16rc1-buster
|
||||
commands:
|
||||
- apt update -y
|
||||
- apt install build-essential python3-pip curl software-properties-common sed upx -y
|
||||
@ -74,3 +335,4 @@ trigger:
|
||||
event:
|
||||
include:
|
||||
- pull_request
|
||||
|
||||
|
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: hrfee
|
@ -11,6 +11,7 @@ before:
|
||||
- mkdir -p data
|
||||
- cp -r static data/web
|
||||
- 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/
|
||||
|
@ -6,7 +6,7 @@ RUN apt update -y \
|
||||
&& apt install build-essential python3-pip curl software-properties-common sed upx -y \
|
||||
&& (curl -sL https://deb.nodesource.com/setup_14.x | bash -) \
|
||||
&& apt install nodejs \
|
||||
&& (cd /opt/build; make all-external; make compress) \
|
||||
&& (cd /opt/build; make all-external GOESBUILD=on; make compress) \
|
||||
&& 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
|
||||
|
||||
FROM golang:1.16rc1-buster
|
||||
|
25
Makefile
25
Makefile
@ -1,8 +1,19 @@
|
||||
GOESBUILD ?= off
|
||||
ifeq ($(GOESBUILD), on)
|
||||
ESBUILD := esbuild
|
||||
else
|
||||
ESBUILD := npx esbuild
|
||||
endif
|
||||
GOBINARY ?= go
|
||||
|
||||
npm:
|
||||
$(info installing npm dependencies)
|
||||
npm install
|
||||
@if [ "$(GOESBUILD)" = "off" ]; then\
|
||||
npm install esbuild;\
|
||||
else\
|
||||
go get -u github.com/evanw/esbuild/cmd/esbuild;\
|
||||
fi
|
||||
|
||||
configuration:
|
||||
$(info Fixing config-base)
|
||||
@ -18,16 +29,16 @@ email:
|
||||
typescript:
|
||||
$(info compiling typescript)
|
||||
-mkdir -p data/web/js
|
||||
-npx esbuild --bundle ts/admin.ts --outfile=./data/web/js/admin.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
|
||||
-$(ESBUILD) --bundle ts/admin.ts --outfile=./data/web/js/admin.js --minify
|
||||
-$(ESBUILD) --bundle ts/form.ts --outfile=./data/web/js/form.js --minify
|
||||
-$(ESBUILD) --bundle ts/setup.ts --outfile=./data/web/js/setup.js --minify
|
||||
|
||||
ts-debug:
|
||||
$(info compiling typescript w/ sourcemaps)
|
||||
-mkdir -p data/web/js
|
||||
-npx esbuild --bundle ts/admin.ts --sourcemap --outfile=./data/web/js/admin.js
|
||||
-npx esbuild --bundle ts/form.ts --sourcemap --outfile=./data/web/js/form.js
|
||||
-npx esbuild --bundle ts/setup.ts --sourcemap --outfile=./data/web/js/setup.js
|
||||
-$(ESBUILD) --bundle ts/admin.ts --sourcemap --outfile=./data/web/js/admin.js
|
||||
-$(ESBUILD) --bundle ts/form.ts --sourcemap --outfile=./data/web/js/form.js
|
||||
-$(ESBUILD) --bundle ts/setup.ts --sourcemap --outfile=./data/web/js/setup.js
|
||||
-rm -r data/web/js/ts
|
||||
$(info copying typescript)
|
||||
cp -r ts data/web/js
|
||||
@ -59,7 +70,7 @@ compress:
|
||||
bundle-css:
|
||||
-mkdir -p data/web/css
|
||||
$(info bundling css)
|
||||
npx esbuild --bundle css/base.css --outfile=data/web/css/bundle.css --external:remixicon.css --minify
|
||||
$(ESBUILD) --bundle css/base.css --outfile=data/web/css/bundle.css --external:remixicon.css --minify
|
||||
|
||||
copy:
|
||||
$(info copying fonts)
|
||||
|
1
go.mod
1
go.mod
@ -13,6 +13,7 @@ replace github.com/hrfee/jfa-go/ombi => ./ombi
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/evanw/esbuild v0.8.44 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/gin-contrib/pprof v1.3.0
|
||||
github.com/gin-contrib/static v0.0.0-20200916080430-d45d9a37d28e
|
||||
|
3
go.sum
3
go.sum
@ -34,6 +34,8 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanw/esbuild v0.8.44 h1:9svHk3MxC3T8ThKkUJ71GcPXYGMhxhO5iCfg2hrU0PU=
|
||||
github.com/evanw/esbuild v0.8.44/go.mod h1:y2AFBAGVelPqPodpdtxWWqe6n2jYf5FrsJbligmRmuw=
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
|
||||
@ -420,6 +422,7 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 h1:sIky/MyNRSHTrdxfsiUSS4WIAMvInbeXljJz+jDjeYE=
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed h1:J22ig1FUekjjkmZUM7pTKixYm8DvrYsvrBZdunYeIuQ=
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="{{ .cssClass }}">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="css/bundle.css">
|
||||
<link rel="stylesheet" type="text/css" href="{{ .urlBase }}/css/bundle.css">
|
||||
<script>
|
||||
window.URLBase = "{{ .urlBase }}";
|
||||
window.notificationsEnabled = {{ .notifications }};
|
||||
@ -40,7 +40,7 @@
|
||||
<div id="modal-about" class="modal">
|
||||
<div class="modal-content content card">
|
||||
<span class="heading">{{ .strings.aboutProgram }} <span class="modal-close">×</span></span>
|
||||
<img src="/banner.svg" class="mt-1" alt="jfa-go banner">
|
||||
<img src="{{ .urlBase }}/banner.svg" class="mt-1" alt="jfa-go banner">
|
||||
<p><i class="icon ri-github-fill"></i><a href="https://github.com/hrfee/jfa-go">jfa-go</a></p>
|
||||
<p>{{ .strings.version }} <span class="code monospace">{{ .version }}</span></p>
|
||||
<p>{{ .strings.commitNoun }} <span class="code monospace">{{ .commit }}</span></p>
|
||||
@ -292,6 +292,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/admin.js" type="module"></script>
|
||||
<script src="{{ .urlBase }}/js/admin.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -36,7 +36,7 @@
|
||||
"sendDeleteNotificationEmail": "Send notification email",
|
||||
"sendDeleteNotifiationExample": "Your account has been deleted.",
|
||||
"settingsRestart": "Restart",
|
||||
"settingsRestarting": "Restarting...",
|
||||
"settingsRestarting": "Restarting…",
|
||||
"settingsRestartRequired": "Restart needed",
|
||||
"settingsRestartRequiredDescription": "A restart is necessary to apply some settings you changed. Restart now or later?",
|
||||
"settingsApplyRestartLater": "Apply, restart later",
|
||||
@ -55,7 +55,6 @@
|
||||
"addProfileDescription": "Create a Jellyfin user and configure it, then select it below. When this profile is applied to an invite, new users will be created with the settings.",
|
||||
"addProfileNameOf": "Profile Name",
|
||||
"addProfileStoreHomescreenLayout": "Store homescreen layout",
|
||||
|
||||
"inviteNoUsersCreated": "None yet!",
|
||||
"inviteUsersCreated": "Created users",
|
||||
"inviteNoProfile": "No Profile",
|
||||
@ -64,7 +63,6 @@
|
||||
"inviteRemainingUses": "Remaining uses",
|
||||
"inviteNoInvites": "None",
|
||||
"inviteExpiresInTime": "Expires in {n}",
|
||||
|
||||
"notifyEvent": "Notify on:",
|
||||
"notifyInviteExpiry": "On expiry",
|
||||
"notifyUserCreation": "On user creation"
|
||||
@ -98,7 +96,6 @@
|
||||
"errorUserCreated": "Failed to create user {n}.",
|
||||
"errorSendWelcomeEmail": "Failed to send welcome email (check console/logs)"
|
||||
},
|
||||
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
"singular": "Modify Settings for {n} user",
|
||||
|
@ -40,7 +40,7 @@
|
||||
"settingsApplyRestartLater": "Appliquer, redémarrer plus tard",
|
||||
"settingsApplyRestartNow": "Appliquer et redémarrer",
|
||||
"settingsApplied": "Paramètres appliqués.",
|
||||
"settingsRefreshPage": "Actualisez la page dans quelques secondes",
|
||||
"settingsRefreshPage": "Actualisez la page dans quelques secondes.",
|
||||
"settingsRequiredOrRestartMessage": "Remarque : {n} indique un champ obligatoire, {n} indique que les modifications nécessitent un redémarrage.",
|
||||
"settingsSave": "Sauver",
|
||||
"ombiUserDefaults": "Paramètres par défaut de l'utilisateur Ombi",
|
||||
@ -64,7 +64,9 @@
|
||||
"notifyEvent": "Notifier sur :",
|
||||
"notifyInviteExpiry": "À l'expiration",
|
||||
"notifyUserCreation": "à la création de l'utilisateur",
|
||||
"label": "Etiquette"
|
||||
"label": "Etiquette",
|
||||
"settingsRestarting": "Redémarrage…",
|
||||
"settingsRestart": "Redémarrer"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Adresse e-mail modifiée de {n}.",
|
||||
|
@ -39,7 +39,7 @@
|
||||
"settingsApplyRestartLater": "Sla op, herstart later",
|
||||
"settingsApplyRestartNow": "Sla op & herstart",
|
||||
"settingsApplied": "Wijzigingen doorgevoerd.",
|
||||
"settingsRefreshPage": "Ververs de pagina over enkele seconden",
|
||||
"settingsRefreshPage": "Ververs de pagina over enkele seconden.",
|
||||
"settingsRequiredOrRestartMessage": "Opmerking: {n} is een verplicht veld, {n} geeft aan dat na wijzigen een herstart nodig is.",
|
||||
"settingsSave": "Opslaan",
|
||||
"ombiUserDefaults": "Ombi gebruiker standaardinstellingen",
|
||||
@ -63,7 +63,9 @@
|
||||
"notifyEvent": "Meldingen:",
|
||||
"notifyInviteExpiry": "Bij verloop",
|
||||
"notifyUserCreation": "Bij aanmaken gebruiker",
|
||||
"label": "Label"
|
||||
"label": "Label",
|
||||
"settingsRestart": "Herstart",
|
||||
"settingsRestarting": "Aan het herstarten…"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "E-mailadres van {n} gewijzigd.",
|
||||
|
@ -29,7 +29,7 @@
|
||||
"newUser": "Novo Usuário",
|
||||
"profile": "Perfil",
|
||||
"unknown": "Desconhecido",
|
||||
"label": "",
|
||||
"label": "Rótulo",
|
||||
"modifySettings": "Modificar configurações",
|
||||
"modifySettingsDescription": "Aplique as configurações de um perfil existente ou obtenha-as diretamente de um usuário.",
|
||||
"applyHomescreenLayout": "Aplicar layout na tela inicial",
|
||||
@ -40,7 +40,7 @@
|
||||
"settingsApplyRestartLater": "Aplicar, reiniciar mais tarde",
|
||||
"settingsApplyRestartNow": "Aplicar e reiniciar",
|
||||
"settingsApplied": "Configurações aplicada.",
|
||||
"settingsRefreshPage": "Atualize a página em alguns segundos",
|
||||
"settingsRefreshPage": "Atualize a página em alguns segundos.",
|
||||
"settingsRequiredOrRestartMessage": "Nota: {n} indica campo obrigatório, {n} indica que as alterações requer um reinício.",
|
||||
"settingsSave": "Salve",
|
||||
"ombiUserDefaults": "Padrões do usuário Ombi",
|
||||
@ -63,7 +63,9 @@
|
||||
"inviteExpiresInTime": "Expira em {n}",
|
||||
"notifyEvent": "Notificar em:",
|
||||
"notifyInviteExpiry": "No vencimento",
|
||||
"notifyUserCreation": "Na criação do usuário"
|
||||
"notifyUserCreation": "Na criação do usuário",
|
||||
"settingsRestart": "Reiniciar",
|
||||
"settingsRestarting": "Reiniciando…"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Endereço de e-mail alterado de {n}.",
|
||||
@ -86,7 +88,7 @@
|
||||
"errorLoadUsers": "Falha ao carregar usuários.",
|
||||
"errorSaveSettings": "Não foi possível salvar as configurações.",
|
||||
"errorLoadSettings": "Falha ao carregar as configurações.",
|
||||
"errorSetOmbiDefaults": "Falha ao armazenar padrões de ombi.",
|
||||
"errorSetOmbiDefaults": "Falha em armazenar os padrões ombi.",
|
||||
"errorLoadOmbiUsers": "Falha ao carregar usuários ombi.",
|
||||
"errorChangedEmailAddress": "Não foi possível alterar o endereço de e-mail de {n}.",
|
||||
"errorFailureCheckLogs": "Falha (verificar console/logs)",
|
||||
|
@ -43,5 +43,10 @@
|
||||
"welcome": "Willkommen bei Jellyfin!",
|
||||
"youCanLoginWith": "Du kannst dich mit den mit den untenstehenden Zugangsdaten anmelden",
|
||||
"jellyfinURL": "URL"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"title": "Bestätige deine E-Mail - Jellyfin",
|
||||
"clickBelow": "Klicke den untenstehenden Link, um deine E-Mail-Adresse zu bestätigen, und fange an, Jellyfin zu benutzen.",
|
||||
"confirmEmail": "E-Mail bestätigen"
|
||||
}
|
||||
}
|
||||
|
@ -44,5 +44,10 @@
|
||||
"title": "Bienvenue sur Jellyfin",
|
||||
"welcome": "Bienvenue sur Jellyfin !",
|
||||
"jellyfinURL": "URL"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"title": "Confirmez votre adresse e-mail - Jellyfin",
|
||||
"clickBelow": "Clique sur le lien ci-dessous pour confirmer ton adresse e-mail et commencer à utiliser Jellyfin.",
|
||||
"confirmEmail": "Confirmer l'adresse e-mail"
|
||||
}
|
||||
}
|
||||
|
@ -43,5 +43,10 @@
|
||||
"welcome": "Welkom bij Jellyfin!",
|
||||
"youCanLoginWith": "Je kunt inloggen met onderstaande gegevens",
|
||||
"jellyfinURL": "URL"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"title": "Bevestig je e-mailadres - Jellyfin",
|
||||
"clickBelow": "Klik op onderstaande link om je e-mailadres te bevestigen en te beginnen met Jellyfin.",
|
||||
"confirmEmail": "Bevestig e-mailadres"
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
"inviteEmail": {
|
||||
"title": "Convite - Jellyfin",
|
||||
"hello": "Ola",
|
||||
"youHaveBeenInvited": "Você um convite para o Jellyfin.",
|
||||
"youHaveBeenInvited": "Você recebeu um convite para o Jellyfin.",
|
||||
"toJoin": "Para participar, clique no link abaixo.",
|
||||
"inviteExpiry": "Este convite expira em {n} às {n}, que é em {n}, então seja rápido.",
|
||||
"linkButton": "Crie sua conta"
|
||||
@ -43,5 +43,10 @@
|
||||
"welcome": "Bem vindo ao Jellyfin!",
|
||||
"youCanLoginWith": "Você pode fazer o login com os detalhes abaixo",
|
||||
"jellyfinURL": "URL"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"title": "Confirme seu email - Jellyfin",
|
||||
"clickBelow": "Clique no link abaixo para confirmar seu endereço de e-mail e começar a usar o Jellyfin.",
|
||||
"confirmEmail": "Confirmar Email"
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,9 @@
|
||||
"createAccountButton": "Konto erstellen",
|
||||
"passwordRequirementsHeader": "Passwortanforderungen",
|
||||
"successHeader": "Erfolg!",
|
||||
"successContinueButton": "Weiter"
|
||||
"successContinueButton": "Weiter",
|
||||
"confirmationRequired": "E-Mail-Bestätigung erforderlich",
|
||||
"confirmationRequiredMessage": "Bitte überprüfe dein Posteingang und bestätige deine E-Mail-Adresse."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
@ -15,7 +15,9 @@
|
||||
"createAccountButton": "Créer le compte",
|
||||
"passwordRequirementsHeader": "Mot de passe requis",
|
||||
"successHeader": "Succes!",
|
||||
"successContinueButton": "Continuer"
|
||||
"successContinueButton": "Continuer",
|
||||
"confirmationRequired": "Confirmation de l'adresse e-mail requise",
|
||||
"confirmationRequiredMessage": "Veuillez vérifier votre boite de réception pour confirmer votre adresse e-mail."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
@ -14,7 +14,9 @@
|
||||
"createAccountButton": "Maak account aan",
|
||||
"passwordRequirementsHeader": "Wachtwoordvereisten",
|
||||
"successHeader": "Succes!",
|
||||
"successContinueButton": "Doorgaan"
|
||||
"successContinueButton": "Doorgaan",
|
||||
"confirmationRequired": "Bevestiging van e-mailadres verplicht",
|
||||
"confirmationRequiredMessage": "Controleer je e-mail inbox om je adres te bevestigen."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
@ -14,7 +14,9 @@
|
||||
"createAccountButton": "Criar Conta",
|
||||
"passwordRequirementsHeader": "Requisitos da Senha",
|
||||
"successHeader": "Sucesso!",
|
||||
"successContinueButton": "Continuar"
|
||||
"successContinueButton": "Continuar",
|
||||
"confirmationRequired": "Necessária confirmação de e-mail",
|
||||
"confirmationRequiredMessage": "Verifique sua caixa de entrada no e-mail para verificar seu endereço."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "Esse usuário já existe.",
|
||||
|
@ -25,7 +25,7 @@
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "Fertig!",
|
||||
"restartMessage": "Es gibt weitere Einstellungen, die du auf der Admin-Seite konfigurieren kannst. Drücke unten, um neu zu starten, dann aktualisiere die Seite.",
|
||||
"restartMessage": "Es gibt weitere Einstellungen, die du auf der Admin-Seite konfigurieren kannst. Klicke unten, um neu zu starten, dann aktualisiere die Seite.",
|
||||
"refreshPage": "Aktualisieren"
|
||||
},
|
||||
"language": {
|
||||
@ -42,7 +42,7 @@
|
||||
"urlBaseNotice": "Nur erforderlich, wenn ein Reverse-Proxy auf einer Subdomain verwendet wird (z. B. 'jellyf.in/accounts').",
|
||||
"lightTheme": "Hell",
|
||||
"darkTheme": "Dunkel",
|
||||
"useHTTPS": "Verwende HTTPS",
|
||||
"useHTTPS": "HTTPS verwenden",
|
||||
"httpsPort": "HTTPS Port",
|
||||
"useHTTPSNotice": "Nur empfohlen, wenn du keinen Reverse-Proxy verwendest.",
|
||||
"pathToCertificate": "Pfad zum Zertifikat",
|
||||
@ -51,10 +51,10 @@
|
||||
"login": {
|
||||
"title": "Anmelden",
|
||||
"description": "Um auf die Admin-Seite zuzugreifen, musst du dich mit einer untenstehenden Methode anmelden:",
|
||||
"authorizeWithJellyfin": "Autorisiere mit Jellyfin/Emby: Anmeldedaten werden mit Jellyfin geteilt, was mehrere Benutzer ermöglicht.",
|
||||
"authorizeWithJellyfin": "Mit Jellyfin/Emby autorisieren: Anmeldedaten werden mit Jellyfin geteilt, was mehrere Benutzer ermöglicht.",
|
||||
"authorizeManual": "Benutzername und Passwort: Lege Benutzername und Passwort manuell fest.",
|
||||
"adminOnly": "Nur Admin-Benutzer (empfohlen)",
|
||||
"emailNotice": "Eine E-Mail-Adresse kann verwendet werden, um Benachrichtigungen zu erhalten."
|
||||
"emailNotice": "Deine E-Mail-Adresse kann verwendet werden, um Benachrichtigungen zu erhalten."
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
@ -69,8 +69,8 @@
|
||||
},
|
||||
"ombi": {
|
||||
"title": "Ombi",
|
||||
"description": "Durch den Anschluss an Ombi wird sowohl ein Jellyfin-Konto als auch ein Ombi-Konto erstellt, wenn ein Benutzer durch jfa-go beitritt. Nachdem das Setup abgeschlossen ist, gehe zu den Einstellungen um ein Standardprofil für neue Ombi-Benutzer festzulegen.",
|
||||
"apiKeyNotice": "Finde das in der ersten Registerkarte der Ombi-Einstellungen."
|
||||
"description": "Durch den Anschluss an Ombi wird sowohl ein Jellyfin-Konto als auch ein Ombi-Konto erstellt, wenn ein Benutzer durch jfa-go beitritt. Nachdem das Setup abgeschlossen ist, gehe zu den Einstellungen, um ein Standardprofil für neue Ombi-Benutzer festzulegen.",
|
||||
"apiKeyNotice": "Finde dies in der ersten Registerkarte der Ombi-Einstellungen."
|
||||
},
|
||||
"email": {
|
||||
"title": "E-Mail",
|
||||
@ -89,7 +89,7 @@
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Benachrichtigungen",
|
||||
"description": "Wenn aktiviert, kannst du (per Invite) wählen, eine E-Mail zu erhalten, wenn ein Invite abläuft oder ein Benutzer erstellt wird. Wenn du nicht die Jellyfin-Login-Methode gewählt hast, stelle sicher, dass du deine E-Mail-Adresse angegeben hast."
|
||||
"description": "Wenn aktiviert, kannst du (pro Invite) wählen, eine E-Mail zu erhalten, wenn ein Invite abläuft oder ein Benutzer erstellt wird. Wenn du nicht die Jellyfin-Login-Methode gewählt hast, stelle sicher, dass du deine E-Mail-Adresse angegeben hast."
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "Willkommens-E-Mails",
|
||||
|
@ -37,7 +37,7 @@
|
||||
},
|
||||
"general": {
|
||||
"title": "Geral",
|
||||
"listenAddress": "",
|
||||
"listenAddress": "Endereço de Escuta",
|
||||
"urlBase": "URL Base",
|
||||
"urlBaseNotice": "Necessário apenas se estiver usando um proxy reverso em um subdomínio (por exemplo, 'jellyf.in/accounts').",
|
||||
"lightTheme": "Claro",
|
||||
|
7
main.go
7
main.go
@ -10,6 +10,7 @@ import (
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"mime"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -521,13 +522,15 @@ func start(asDaemon, firstCall bool) {
|
||||
app.info.Fatalf("Failed to load language files: %+v\n", err)
|
||||
}
|
||||
}
|
||||
cssHeader = app.loadCSSHeader()
|
||||
// workaround for potentially broken windows mime types
|
||||
mime.AddExtensionType(".js", "application/javascript")
|
||||
|
||||
app.info.Println("Initializing router")
|
||||
router := app.loadRouter(address, debugMode)
|
||||
app.info.Println("Loading routes")
|
||||
router.GET("/lang/:page", app.GetLanguages)
|
||||
if !firstRun {
|
||||
app.loadRoutes(router)
|
||||
app.info.Printf("Starting router @ %s", address)
|
||||
} else {
|
||||
app.loadSetup(router)
|
||||
app.info.Printf("Loading setup @ %s", address)
|
||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -228,9 +228,9 @@
|
||||
"integrity": "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY="
|
||||
},
|
||||
"esbuild": {
|
||||
"version": "0.7.22",
|
||||
"resolved": "https://registry.npm.taobao.org/esbuild/download/esbuild-0.7.22.tgz",
|
||||
"integrity": "sha1-kUm5A/gSi3xFp1QEbCQZnXa74I4="
|
||||
"version": "0.8.44",
|
||||
"resolved": "https://registry.npm.taobao.org/esbuild/download/esbuild-0.8.44.tgz",
|
||||
"integrity": "sha1-KnT0j+IFeQgcnY/pm+b7jShIyIc="
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.1.1",
|
||||
|
@ -18,7 +18,7 @@
|
||||
"homepage": "https://github.com/hrfee/jfa-go#readme",
|
||||
"dependencies": {
|
||||
"a17t": "^0.4.0",
|
||||
"esbuild": "^0.7.8",
|
||||
"esbuild": "^0.8.44",
|
||||
"lodash": "^4.17.19",
|
||||
"mjml": "^4.8.0",
|
||||
"remixicon": "^2.5.0",
|
||||
|
76
router.go
76
router.go
@ -97,45 +97,59 @@ func (app *appContext) loadRouter(address string, debug bool) *gin.Engine {
|
||||
}
|
||||
|
||||
func (app *appContext) loadRoutes(router *gin.Engine) {
|
||||
router.GET("/", app.AdminPage)
|
||||
router.GET("/accounts", app.AdminPage)
|
||||
router.GET("/settings", app.AdminPage)
|
||||
router.GET("/lang/:page/:file", app.ServeLang)
|
||||
router.GET("/token/login", app.getTokenLogin)
|
||||
router.GET("/token/refresh", app.getTokenRefresh)
|
||||
router.POST("/newUser", app.NewUser)
|
||||
router.Use(static.Serve("/invite/", app.webFS))
|
||||
router.GET("/invite/:invCode", app.InviteProxy)
|
||||
routePrefixes := []string{app.URLBase}
|
||||
if app.URLBase != "" {
|
||||
routePrefixes = append(routePrefixes, "")
|
||||
}
|
||||
for _, p := range routePrefixes {
|
||||
router.GET(p+"/lang/:page", app.GetLanguages)
|
||||
router.Use(static.Serve(p+"/", app.webFS))
|
||||
router.GET(p+"/", app.AdminPage)
|
||||
router.GET(p+"/accounts", app.AdminPage)
|
||||
router.GET(p+"/settings", app.AdminPage)
|
||||
router.GET(p+"/lang/:page/:file", app.ServeLang)
|
||||
router.GET(p+"/token/login", app.getTokenLogin)
|
||||
router.GET(p+"/token/refresh", app.getTokenRefresh)
|
||||
router.POST(p+"/newUser", app.NewUser)
|
||||
router.Use(static.Serve(p+"/invite/", app.webFS))
|
||||
router.GET(p+"/invite/:invCode", app.InviteProxy)
|
||||
}
|
||||
if *SWAGGER {
|
||||
app.info.Print(aurora.Magenta("\n\nWARNING: Swagger should not be used on a public instance.\n\n"))
|
||||
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
for _, p := range routePrefixes {
|
||||
router.GET(p+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
}
|
||||
}
|
||||
api := router.Group("/", app.webAuth())
|
||||
router.POST("/logout", app.Logout)
|
||||
api.DELETE("/users", app.DeleteUser)
|
||||
api.GET("/users", app.GetUsers)
|
||||
api.POST("/users", app.NewUserAdmin)
|
||||
api.POST("/invites", app.GenerateInvite)
|
||||
api.GET("/invites", app.GetInvites)
|
||||
api.DELETE("/invites", app.DeleteInvite)
|
||||
api.POST("/invites/profile", app.SetProfile)
|
||||
api.GET("/profiles", app.GetProfiles)
|
||||
api.POST("/profiles/default", app.SetDefaultProfile)
|
||||
api.POST("/profiles", app.CreateProfile)
|
||||
api.DELETE("/profiles", app.DeleteProfile)
|
||||
api.POST("/invites/notify", app.SetNotify)
|
||||
api.POST("/users/emails", app.ModifyEmails)
|
||||
api.POST("/users/settings", app.ApplySettings)
|
||||
api.GET("/config", app.GetConfig)
|
||||
api.POST("/config", app.ModifyConfig)
|
||||
api.POST("/restart", app.restart)
|
||||
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
||||
api.GET("/ombi/users", app.OmbiUsers)
|
||||
api.POST("/ombi/defaults", app.SetOmbiDefaults)
|
||||
for _, p := range routePrefixes {
|
||||
router.POST(p+"/logout", app.Logout)
|
||||
api.DELETE(p+"/users", app.DeleteUser)
|
||||
api.GET(p+"/users", app.GetUsers)
|
||||
api.POST(p+"/users", app.NewUserAdmin)
|
||||
api.POST(p+"/invites", app.GenerateInvite)
|
||||
api.GET(p+"/invites", app.GetInvites)
|
||||
api.DELETE(p+"/invites", app.DeleteInvite)
|
||||
api.POST(p+"/invites/profile", app.SetProfile)
|
||||
api.GET(p+"/profiles", app.GetProfiles)
|
||||
api.POST(p+"/profiles/default", app.SetDefaultProfile)
|
||||
api.POST(p+"/profiles", app.CreateProfile)
|
||||
api.DELETE(p+"/profiles", app.DeleteProfile)
|
||||
api.POST(p+"/invites/notify", app.SetNotify)
|
||||
api.POST(p+"/users/emails", app.ModifyEmails)
|
||||
// api.POST(p + "/setDefaults", app.SetDefaults)
|
||||
api.POST(p+"/users/settings", app.ApplySettings)
|
||||
api.GET(p+"/config", app.GetConfig)
|
||||
api.POST(p+"/config", app.ModifyConfig)
|
||||
api.POST(p+"/restart", app.restart)
|
||||
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
||||
api.GET(p+"/ombi/users", app.OmbiUsers)
|
||||
api.POST(p+"/ombi/defaults", app.SetOmbiDefaults)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (app *appContext) loadSetup(router *gin.Engine) {
|
||||
router.GET("/lang/:page", app.GetLanguages)
|
||||
router.GET("/", app.ServeSetup)
|
||||
router.POST("/jellyfin/test", app.TestJF)
|
||||
router.POST("/config", app.ModifyConfig)
|
||||
|
15
ts/admin.ts
15
ts/admin.ts
@ -84,23 +84,24 @@ window.tabs.addTab("accounts", null, accounts.reload);
|
||||
window.tabs.addTab("settings", null, settings.reload);
|
||||
|
||||
for (let tab of ["invites", "accounts", "settings"]) {
|
||||
if (window.location.pathname == "/" + tab) {
|
||||
if (window.location.pathname == window.URLBase + "/" + tab) {
|
||||
window.tabs.switch(tab, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (window.location.pathname == "/") {
|
||||
if ((window.URLBase + "/").includes(window.location.pathname)) {
|
||||
window.tabs.switch("invites", true);
|
||||
}
|
||||
|
||||
document.addEventListener("tab-change", (event: CustomEvent) => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const lang = urlParams.get('lang');
|
||||
let tab = "/" + event.detail;
|
||||
if (tab == "/invites") {
|
||||
if (window.location.pathname == "/") {
|
||||
tab = "/";
|
||||
} else { tab = "../"; }
|
||||
let tab = window.URLBase + "/" + event.detail;
|
||||
if (tab == window.URLBase + "/invites") {
|
||||
if (window.location.pathname == window.URLBase + "/") {
|
||||
tab = window.URLBase + "/";
|
||||
} else if (window.URLBase) { tab = window.URLBase; }
|
||||
else { tab = "../"; }
|
||||
}
|
||||
if (lang) {
|
||||
tab += "?lang=" + lang
|
||||
|
@ -42,7 +42,15 @@ class user implements User {
|
||||
}
|
||||
|
||||
get email(): string { return this._emailAddress; }
|
||||
set email(value: string) { this._email.value = value; this._emailAddress = value; }
|
||||
set email(value: string) {
|
||||
this._emailAddress = value;
|
||||
const input = this._email.querySelector("input");
|
||||
if (input) {
|
||||
input.value = value;
|
||||
} else {
|
||||
this._email.textContent = value;
|
||||
}
|
||||
}
|
||||
|
||||
get last_active(): string { return this._lastActive.textContent; }
|
||||
set last_active(value: string) { this._lastActive.textContent = value; }
|
||||
@ -55,20 +63,27 @@ class user implements User {
|
||||
this._row.innerHTML = `
|
||||
<td><input type="checkbox" value=""></td>
|
||||
<td><span class="accounts-username"></span> <span class="accounts-admin"></span></td>
|
||||
<td><i class="icon ri-edit-line accounts-email-edit"></i><input type="email" class="input ~neutral !normal stealth-input stealth-input-hidden accounts-email" readonly></td>
|
||||
<td><i class="icon ri-edit-line accounts-email-edit"></i><span class="accounts-email-container ml-half"></span></td>
|
||||
<td class="accounts-last-active"></td>
|
||||
`;
|
||||
const emailEditor = `<input type="email" class="input ~neutral !normal 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;
|
||||
this._email = this._row.querySelector(".accounts-email") as HTMLInputElement;
|
||||
this._email = this._row.querySelector(".accounts-email-container") as HTMLInputElement;
|
||||
this._emailEditButton = this._row.querySelector(".accounts-email-edit") as HTMLElement;
|
||||
this._lastActive = this._row.querySelector(".accounts-last-active") as HTMLTableDataCellElement;
|
||||
this._check.onchange = () => { this.selected = this._check.checked; }
|
||||
|
||||
const toggleStealthInput = () => {
|
||||
this._email.classList.toggle("stealth-input-hidden");
|
||||
this._email.readOnly = !this._email.readOnly;
|
||||
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");
|
||||
} else {
|
||||
this._email.textContent = this._emailAddress;
|
||||
this._email.classList.add("ml-half");
|
||||
}
|
||||
this._emailEditButton.classList.toggle("ri-check-line");
|
||||
this._emailEditButton.classList.toggle("ri-edit-line");
|
||||
};
|
||||
@ -80,7 +95,7 @@ class user implements User {
|
||||
}
|
||||
};
|
||||
this._emailEditButton.onclick = () => {
|
||||
if (this._email.classList.contains("stealth-input-hidden")) {
|
||||
if (this._emailEditButton.classList.contains("ri-edit-line")) {
|
||||
document.addEventListener('click', outerClickListener);
|
||||
} else {
|
||||
this._updateEmail();
|
||||
@ -94,7 +109,7 @@ class user implements User {
|
||||
|
||||
private _updateEmail = () => {
|
||||
let oldEmail = this.email;
|
||||
this.email = this._email.value;
|
||||
this.email = this._email.querySelector("input").value;
|
||||
let send = {};
|
||||
send[this.id] = this.email;
|
||||
_post("/users/emails", send, (req: XMLHttpRequest) => {
|
||||
|
@ -45,6 +45,7 @@ export class DOMInvite implements Invite {
|
||||
for (let split of ["#", "?"]) {
|
||||
codeLink = codeLink.split(split)[0];
|
||||
}
|
||||
if (codeLink.slice(-1) != "/") { codeLink += "/"; }
|
||||
this._codeLink = codeLink + "invite/" + code;
|
||||
const linkEl = this._codeArea.querySelector("a") as HTMLAnchorElement;
|
||||
if (this.label == "") {
|
||||
|
@ -400,7 +400,6 @@ window.onpopstate = (event: PopStateEvent) => {
|
||||
const card = cards[i];
|
||||
const back = card.getElementsByClassName("back")[0] as HTMLSpanElement;
|
||||
const next = card.getElementsByClassName("next")[0] as HTMLSpanElement;
|
||||
console.log(cards[i]);
|
||||
const titleEl = cards[i].querySelector("span.heading") as HTMLElement;
|
||||
let title = titleEl.textContent.replace("/", "_").replace(" ", "-");
|
||||
if (titleEl.classList.contains("welcome")) {
|
||||
|
25
views.go
25
views.go
@ -11,17 +11,26 @@ import (
|
||||
)
|
||||
|
||||
var css = []string{"bundle.css", "remixicon.css"}
|
||||
var cssHeader = func() string {
|
||||
var cssHeader string
|
||||
|
||||
func (app *appContext) loadCSSHeader() string {
|
||||
l := len(css)
|
||||
h := ""
|
||||
for i, f := range css {
|
||||
h += "</css/" + f + ">; rel=preload; as=style"
|
||||
h += "<" + app.URLBase + "/css/" + f + ">; rel=preload; as=style"
|
||||
if l > 1 && i != (l-1) {
|
||||
h += ", "
|
||||
}
|
||||
}
|
||||
return h
|
||||
}()
|
||||
}
|
||||
|
||||
func (app *appContext) getURLBase(gc *gin.Context) string {
|
||||
if strings.HasPrefix(gc.Request.URL.String(), app.URLBase) {
|
||||
return app.URLBase
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func gcHTML(gc *gin.Context, code int, file string, templ gin.H) {
|
||||
gc.Header("Cache-Control", "no-cache")
|
||||
@ -34,7 +43,7 @@ func (app *appContext) pushResources(gc *gin.Context, admin bool) {
|
||||
if admin {
|
||||
toPush := []string{"/js/admin.js", "/js/theme.js", "/js/lang.js", "/js/modal.js", "/js/tabs.js", "/js/invites.js", "/js/accounts.js", "/js/settings.js", "/js/profiles.js", "/js/common.js"}
|
||||
for _, f := range toPush {
|
||||
if err := pusher.Push(f, nil); err != nil {
|
||||
if err := pusher.Push(app.URLBase+f, nil); err != nil {
|
||||
app.debug.Printf("Failed HTTP2 ServerPush of \"%s\": %+v", f, err)
|
||||
}
|
||||
}
|
||||
@ -60,7 +69,7 @@ func (app *appContext) AdminPage(gc *gin.Context) {
|
||||
notificationsEnabled, _ := app.config.Section("notifications").Key("enabled").Bool()
|
||||
ombiEnabled := app.config.Section("ombi").Key("enabled").MustBool(false)
|
||||
gcHTML(gc, http.StatusOK, "admin.html", gin.H{
|
||||
"urlBase": app.URLBase,
|
||||
"urlBase": app.getURLBase(gc),
|
||||
"cssClass": app.cssClass,
|
||||
"contactMessage": "",
|
||||
"email_enabled": emailEnabled,
|
||||
@ -134,9 +143,8 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
||||
Password: claims["password"].(string),
|
||||
Code: claims["invite"].(string),
|
||||
}
|
||||
f, success := app.newUser(req, true)
|
||||
_, success := app.newUser(req, true)
|
||||
if !success {
|
||||
f(gc)
|
||||
fail()
|
||||
return
|
||||
}
|
||||
@ -144,6 +152,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
||||
"strings": app.storage.lang.Form[lang].Strings,
|
||||
"successMessage": app.config.Section("ui").Key("success_message").String(),
|
||||
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||
"jfLink": app.config.Section("jellyfin").Key("public_server").String(),
|
||||
})
|
||||
inv, ok := app.storage.invites[code]
|
||||
if ok {
|
||||
@ -158,7 +167,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
||||
email = ""
|
||||
}
|
||||
gcHTML(gc, http.StatusOK, "form-loader.html", gin.H{
|
||||
"urlBase": app.URLBase,
|
||||
"urlBase": app.getURLBase(gc),
|
||||
"cssClass": app.cssClass,
|
||||
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||
"helpMessage": app.config.Section("ui").Key("help_message").String(),
|
||||
|
Loading…
Reference in New Issue
Block a user