1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-10-18 09:00:11 +00:00

Compare commits

...

10 Commits

Author SHA1 Message Date
8eed4b0127
merge language again 2021-02-05 18:25:56 +00:00
c09ffb49e7
switch emails to normal text when not editing
fixes padding on small screens.
2021-02-05 18:24:27 +00:00
ClankJake
f331f4eb92 translation from Weblate (Portuguese (Brazil))
Currently translated at 100.0% (103 of 103 strings)

Translation: jfa-go/Admin Page
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/admin/pt_BR/
2021-02-05 15:55:38 +01:00
Richard de Boer
629b669c64 translation from Weblate (Dutch)
Currently translated at 100.0% (103 of 103 strings)

Translation: jfa-go/Admin Page
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/admin/nl/
2021-02-05 15:55:38 +01:00
Cornichon420
2dab900748 translation from Weblate (French)
Currently translated at 100.0% (103 of 103 strings)

Translation: jfa-go/Admin Page
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/admin/fr/
2021-02-05 15:55:38 +01:00
hrfee
f864097f2e translation from Weblate (English)
Currently translated at 100.0% (103 of 103 strings)

Translation: jfa-go/Admin Page
Translate-URL: https://weblate.hrfee.pw/projects/jfa-go/admin/en/
2021-02-05 15:55:38 +01:00
2c8be42bbc
fix invite links with URL base 2021-02-05 13:33:34 +00:00
6691ae27f4
fix navigation with URL base set 2021-02-05 13:31:56 +00:00
23fecb16b2
merge language changes 2021-02-05 13:11:00 +00:00
b037b08152
respect URL Base in http preloads and inline html links 2021-02-05 13:10:47 +00:00
9 changed files with 54 additions and 31 deletions

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" class="{{ .cssClass }}"> <html lang="en" class="{{ .cssClass }}">
<head> <head>
<link rel="stylesheet" type="text/css" href="css/bundle.css"> <link rel="stylesheet" type="text/css" href="{{ .urlBase }}/css/bundle.css">
<script> <script>
window.URLBase = "{{ .urlBase }}"; window.URLBase = "{{ .urlBase }}";
window.notificationsEnabled = {{ .notifications }}; window.notificationsEnabled = {{ .notifications }};
@ -40,7 +40,7 @@
<div id="modal-about" class="modal"> <div id="modal-about" class="modal">
<div class="modal-content content card"> <div class="modal-content content card">
<span class="heading">{{ .strings.aboutProgram }} <span class="modal-close">&times;</span></span> <span class="heading">{{ .strings.aboutProgram }} <span class="modal-close">&times;</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><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.version }} <span class="code monospace">{{ .version }}</span></p>
<p>{{ .strings.commitNoun }} <span class="code monospace">{{ .commit }}</span></p> <p>{{ .strings.commitNoun }} <span class="code monospace">{{ .commit }}</span></p>
@ -292,6 +292,6 @@
</div> </div>
</div> </div>
</div> </div>
<script src="js/admin.js" type="module"></script> <script src="{{ .urlBase }}/js/admin.js" type="module"></script>
</body> </body>
</html> </html>

View File

@ -36,7 +36,7 @@
"sendDeleteNotificationEmail": "Send notification email", "sendDeleteNotificationEmail": "Send notification email",
"sendDeleteNotifiationExample": "Your account has been deleted.", "sendDeleteNotifiationExample": "Your account has been deleted.",
"settingsRestart": "Restart", "settingsRestart": "Restart",
"settingsRestarting": "Restarting...", "settingsRestarting": "Restarting",
"settingsRestartRequired": "Restart needed", "settingsRestartRequired": "Restart needed",
"settingsRestartRequiredDescription": "A restart is necessary to apply some settings you changed. Restart now or later?", "settingsRestartRequiredDescription": "A restart is necessary to apply some settings you changed. Restart now or later?",
"settingsApplyRestartLater": "Apply, restart 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.", "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", "addProfileNameOf": "Profile Name",
"addProfileStoreHomescreenLayout": "Store homescreen layout", "addProfileStoreHomescreenLayout": "Store homescreen layout",
"inviteNoUsersCreated": "None yet!", "inviteNoUsersCreated": "None yet!",
"inviteUsersCreated": "Created users", "inviteUsersCreated": "Created users",
"inviteNoProfile": "No Profile", "inviteNoProfile": "No Profile",
@ -64,7 +63,6 @@
"inviteRemainingUses": "Remaining uses", "inviteRemainingUses": "Remaining uses",
"inviteNoInvites": "None", "inviteNoInvites": "None",
"inviteExpiresInTime": "Expires in {n}", "inviteExpiresInTime": "Expires in {n}",
"notifyEvent": "Notify on:", "notifyEvent": "Notify on:",
"notifyInviteExpiry": "On expiry", "notifyInviteExpiry": "On expiry",
"notifyUserCreation": "On user creation" "notifyUserCreation": "On user creation"
@ -98,7 +96,6 @@
"errorUserCreated": "Failed to create user {n}.", "errorUserCreated": "Failed to create user {n}.",
"errorSendWelcomeEmail": "Failed to send welcome email (check console/logs)" "errorSendWelcomeEmail": "Failed to send welcome email (check console/logs)"
}, },
"quantityStrings": { "quantityStrings": {
"modifySettingsFor": { "modifySettingsFor": {
"singular": "Modify Settings for {n} user", "singular": "Modify Settings for {n} user",

View File

@ -40,7 +40,7 @@
"settingsApplyRestartLater": "Appliquer, redémarrer plus tard", "settingsApplyRestartLater": "Appliquer, redémarrer plus tard",
"settingsApplyRestartNow": "Appliquer et redémarrer", "settingsApplyRestartNow": "Appliquer et redémarrer",
"settingsApplied": "Paramètres appliqués.", "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.", "settingsRequiredOrRestartMessage": "Remarque: {n} indique un champ obligatoire, {n} indique que les modifications nécessitent un redémarrage.",
"settingsSave": "Sauver", "settingsSave": "Sauver",
"ombiUserDefaults": "Paramètres par défaut de l'utilisateur Ombi", "ombiUserDefaults": "Paramètres par défaut de l'utilisateur Ombi",
@ -64,7 +64,9 @@
"notifyEvent": "Notifier sur :", "notifyEvent": "Notifier sur :",
"notifyInviteExpiry": "À l'expiration", "notifyInviteExpiry": "À l'expiration",
"notifyUserCreation": "à la création de l'utilisateur", "notifyUserCreation": "à la création de l'utilisateur",
"label": "Etiquette" "label": "Etiquette",
"settingsRestarting": "Redémarrage…",
"settingsRestart": "Redémarrer"
}, },
"notifications": { "notifications": {
"changedEmailAddress": "Adresse e-mail modifiée de {n}.", "changedEmailAddress": "Adresse e-mail modifiée de {n}.",

View File

@ -39,7 +39,7 @@
"settingsApplyRestartLater": "Sla op, herstart later", "settingsApplyRestartLater": "Sla op, herstart later",
"settingsApplyRestartNow": "Sla op & herstart", "settingsApplyRestartNow": "Sla op & herstart",
"settingsApplied": "Wijzigingen doorgevoerd.", "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.", "settingsRequiredOrRestartMessage": "Opmerking: {n} is een verplicht veld, {n} geeft aan dat na wijzigen een herstart nodig is.",
"settingsSave": "Opslaan", "settingsSave": "Opslaan",
"ombiUserDefaults": "Ombi gebruiker standaardinstellingen", "ombiUserDefaults": "Ombi gebruiker standaardinstellingen",
@ -63,7 +63,9 @@
"notifyEvent": "Meldingen:", "notifyEvent": "Meldingen:",
"notifyInviteExpiry": "Bij verloop", "notifyInviteExpiry": "Bij verloop",
"notifyUserCreation": "Bij aanmaken gebruiker", "notifyUserCreation": "Bij aanmaken gebruiker",
"label": "Label" "label": "Label",
"settingsRestart": "Herstart",
"settingsRestarting": "Aan het herstarten…"
}, },
"notifications": { "notifications": {
"changedEmailAddress": "E-mailadres van {n} gewijzigd.", "changedEmailAddress": "E-mailadres van {n} gewijzigd.",

View File

@ -40,7 +40,7 @@
"settingsApplyRestartLater": "Aplicar, reiniciar mais tarde", "settingsApplyRestartLater": "Aplicar, reiniciar mais tarde",
"settingsApplyRestartNow": "Aplicar e reiniciar", "settingsApplyRestartNow": "Aplicar e reiniciar",
"settingsApplied": "Configurações aplicada.", "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.", "settingsRequiredOrRestartMessage": "Nota: {n} indica campo obrigatório, {n} indica que as alterações requer um reinício.",
"settingsSave": "Salve", "settingsSave": "Salve",
"ombiUserDefaults": "Padrões do usuário Ombi", "ombiUserDefaults": "Padrões do usuário Ombi",
@ -63,7 +63,9 @@
"inviteExpiresInTime": "Expira em {n}", "inviteExpiresInTime": "Expira em {n}",
"notifyEvent": "Notificar em:", "notifyEvent": "Notificar em:",
"notifyInviteExpiry": "No vencimento", "notifyInviteExpiry": "No vencimento",
"notifyUserCreation": "Na criação do usuário" "notifyUserCreation": "Na criação do usuário",
"settingsRestart": "Reiniciar",
"settingsRestarting": "Reiniciando…"
}, },
"notifications": { "notifications": {
"changedEmailAddress": "Endereço de e-mail alterado de {n}.", "changedEmailAddress": "Endereço de e-mail alterado de {n}.",

View File

@ -567,6 +567,8 @@ func start(asDaemon, firstCall bool) {
app.info.Fatalf("Failed to load language files: %+v\n", err) app.info.Fatalf("Failed to load language files: %+v\n", err)
} }
} }
cssHeader = app.loadCSSHeader()
app.info.Println("Loading routes") app.info.Println("Loading routes")
if debugMode { if debugMode {
gin.SetMode(gin.DebugMode) gin.SetMode(gin.DebugMode)

View File

@ -84,23 +84,24 @@ window.tabs.addTab("accounts", null, accounts.reload);
window.tabs.addTab("settings", null, settings.reload); window.tabs.addTab("settings", null, settings.reload);
for (let tab of ["invites", "accounts", "settings"]) { for (let tab of ["invites", "accounts", "settings"]) {
if (window.location.pathname == "/" + tab) { if (window.location.pathname == window.URLBase + "/" + tab) {
window.tabs.switch(tab, true); window.tabs.switch(tab, true);
} }
} }
if (window.location.pathname == "/") { if (window.location.pathname == window.URLBase + "/") {
window.tabs.switch("invites", true); window.tabs.switch("invites", true);
} }
document.addEventListener("tab-change", (event: CustomEvent) => { document.addEventListener("tab-change", (event: CustomEvent) => {
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
const lang = urlParams.get('lang'); const lang = urlParams.get('lang');
let tab = "/" + event.detail; let tab = window.URLBase + "/" + event.detail;
if (tab == "/invites") { if (tab == window.URLBase + "/invites") {
if (window.location.pathname == "/") { if (window.location.pathname == window.URLBase + "/") {
tab = "/"; tab = window.URLBase + "/";
} else { tab = "../"; } } else if (window.URLBase) { tab = window.URLBase; }
else { tab = "../"; }
} }
if (lang) { if (lang) {
tab += "?lang=" + lang tab += "?lang=" + lang

View File

@ -42,7 +42,15 @@ class user implements User {
} }
get email(): string { return this._emailAddress; } 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; } get last_active(): string { return this._lastActive.textContent; }
set last_active(value: string) { this._lastActive.textContent = value; } set last_active(value: string) { this._lastActive.textContent = value; }
@ -55,20 +63,27 @@ class user implements User {
this._row.innerHTML = ` this._row.innerHTML = `
<td><input type="checkbox" value=""></td> <td><input type="checkbox" value=""></td>
<td><span class="accounts-username"></span> <span class="accounts-admin"></span></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> <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._check = this._row.querySelector("input[type=checkbox]") as HTMLInputElement;
this._username = this._row.querySelector(".accounts-username") as HTMLSpanElement; this._username = this._row.querySelector(".accounts-username") as HTMLSpanElement;
this._admin = this._row.querySelector(".accounts-admin") 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._emailEditButton = this._row.querySelector(".accounts-email-edit") as HTMLElement;
this._lastActive = this._row.querySelector(".accounts-last-active") as HTMLTableDataCellElement; this._lastActive = this._row.querySelector(".accounts-last-active") as HTMLTableDataCellElement;
this._check.onchange = () => { this.selected = this._check.checked; } this._check.onchange = () => { this.selected = this._check.checked; }
const toggleStealthInput = () => { const toggleStealthInput = () => {
this._email.classList.toggle("stealth-input-hidden"); if (this._emailEditButton.classList.contains("ri-edit-line")) {
this._email.readOnly = !this._email.readOnly; 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-check-line");
this._emailEditButton.classList.toggle("ri-edit-line"); this._emailEditButton.classList.toggle("ri-edit-line");
}; };
@ -80,7 +95,7 @@ class user implements User {
} }
}; };
this._emailEditButton.onclick = () => { this._emailEditButton.onclick = () => {
if (this._email.classList.contains("stealth-input-hidden")) { if (this._emailEditButton.classList.contains("ri-edit-line")) {
document.addEventListener('click', outerClickListener); document.addEventListener('click', outerClickListener);
} else { } else {
this._updateEmail(); this._updateEmail();
@ -94,7 +109,7 @@ class user implements User {
private _updateEmail = () => { private _updateEmail = () => {
let oldEmail = this.email; let oldEmail = this.email;
this.email = this._email.value; this.email = this._email.querySelector("input").value;
let send = {}; let send = {};
send[this.id] = this.email; send[this.id] = this.email;
_post("/users/emails", send, (req: XMLHttpRequest) => { _post("/users/emails", send, (req: XMLHttpRequest) => {

View File

@ -11,17 +11,19 @@ import (
) )
var css = []string{"bundle.css", "remixicon.css"} var css = []string{"bundle.css", "remixicon.css"}
var cssHeader = func() string { var cssHeader string
func (app *appContext) loadCSSHeader() string {
l := len(css) l := len(css)
h := "" h := ""
for i, f := range css { 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) { if l > 1 && i != (l-1) {
h += ", " h += ", "
} }
} }
return h return h
}() }
func gcHTML(gc *gin.Context, code int, file string, templ gin.H) { func gcHTML(gc *gin.Context, code int, file string, templ gin.H) {
gc.Header("Cache-Control", "no-cache") gc.Header("Cache-Control", "no-cache")
@ -34,7 +36,7 @@ func (app *appContext) pushResources(gc *gin.Context, admin bool) {
if admin { 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"} 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 { 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) app.debug.Printf("Failed HTTP2 ServerPush of \"%s\": %+v", f, err)
} }
} }