1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2025-01-01 14:00:12 +00:00

Compare commits

..

12 Commits

Author SHA1 Message Date
75796a3981
add optional tls/http2 support
Allows for http2 server push, see the advanced section.
2021-01-15 14:41:44 +00:00
781047058f
update CONTRIBUTING.md 2021-01-15 13:40:42 +00:00
0ac61a59b2
fix display of username box on add account modal 2021-01-15 13:37:09 +00:00
732ed5b0b8
add finished french for admin 2021-01-15 13:30:29 +00:00
42ddbab6cf
fix spelling in french email 2021-01-14 21:39:06 +00:00
432d795880
Fix email language selection, add finished french emails 2021-01-14 20:24:28 +00:00
fe62422a2a
Add email translation, add part of french translations
Admin translation from @Killianbe, Email translation from
@Cornichon420. French is currently not functional, a few things are
missing which i'm waiting on.
2021-01-14 17:51:12 +00:00
c4342b7f1e
attempt to use http2 server push 2021-01-14 14:18:12 +00:00
1fc8873c09
add language selector to admin 2021-01-12 23:43:44 +00:00
a4e44f5a8b
separate options for form and admin language 2021-01-12 23:37:22 +00:00
c9e7e34fbf
Use lang file in typescript 2021-01-12 23:15:12 +00:00
0cb1e7b24b
Start adding translation support for admin 2021-01-12 00:11:40 +00:00
11 changed files with 19 additions and 223 deletions

View File

@ -49,7 +49,6 @@ For [docker](https://hub.docker.com/repository/docker/hrfee/jfa-go), run:
docker create \
--name "jfa-go" \ # Whatever you want to name it
-p 8056:8056 \
# -p 8057:8057 if using tls
-v /path/to/.config/jfa-go:/data \ # Path to wherever you want to store the config file and other data
-v /path/to/jellyfin:/jf \ # Path to jellyfin config directory
-v /etc/localtime:/etc/localtime:ro \ # Makes sure time is correct

View File

@ -232,7 +232,7 @@
"requires_restart": true,
"type": "bool",
"value": false,
"description": "Enable TLS."
"description": "Enable TLS, and by extension HTTP2. This enables server push, where required files are pushed to the web browser before they request them, allowing quicker page loads."
},
"tls_port": {
"name": "TLS Port",

View File

@ -2,6 +2,7 @@
<html lang="en" class="{{ .cssClass }}">
<head>
<link rel="stylesheet" type="text/css" href="css/base.css">
<script>
window.URLBase = "{{ .urlBase }}";
window.notificationsEnabled = {{ .notifications }};

View File

@ -4,7 +4,6 @@
window.validationStrings = JSON.parse({{ .lang.validationStrings }});
window.invalidPassword = "{{ .lang.reEnterPasswordInvalid }}";
window.URLBase = "{{ .urlBase }}";
window.code = "{{ .code }}";
</script>
<script src="js/form.js" type="module"></script>
{{ end }}

View File

@ -40,7 +40,7 @@
"modifySettings": "Modifier les paramètres",
"modifySettingsDescription": "Appliquez les paramètres à partir d'un profil existant ou obtenez-les directement auprès d'un utilisateur.",
"applyHomescreenLayout": "Appliquer la disposition de l'écran d'accueil",
"sendDeleteNotificationEmail": "Envoyer un e-mail de notification",
"sendDeleteNotificationEmail": "Envoyer un e-mail de notification ",
"sendDeleteNotifiationExample": "Votre compte a été supprimé. ",
"settingsRestartRequired": "Redémarrage nécessaire ",
"settingsRestartRequiredDescription": "Un redémarrage est nécessaire pour appliquer certains paramètres que vous avez modifiés. Redémarrer maintenant ou plus tard?",
@ -60,6 +60,7 @@
"addProfileDescription": "Créez un utilisateur Jellyfin et configurez-le, puis sélectionnez-le ci-dessous. Lorsque ce profil est appliqué à une invitation, de nouveaux utilisateurs seront créés avec les paramètres. ",
"addProfileNameOf": "Nom de profil",
"addProfileStoreHomescreenLayout": "Enregistrer la disposition de l'écran d'accueil",
"inviteNoUsersCreated": "Aucun pour l'instant!",
"inviteUsersCreated": "Utilisateurs créer",
"inviteNoProfile": "Aucun profil",
@ -68,6 +69,7 @@
"inviteRemainingUses": "Utilisations restantes",
"inviteNoInvites": "Aucune",
"inviteExpiresInTime": "Expires dans {n}",
"notifyEvent": "Notifier sur:",
"notifyInviteExpiry": "À l'expiration",
"notifyUserCreation": "à la création de l'utilisateur"
@ -117,12 +119,12 @@
"plural": "Supprimer les utilisateurs"
},
"deletedUser": {
"singular": "Supprimer {n} utilisateur.",
"plural": "Supprimer {n} utilisateurs."
"singular": "Supprimer {n} utilisateur.",
"plural": "Supprimer {n} utilisateurs."
},
"appliedSettings": {
"singular": "Appliquer le paramètre {n} utilisteur.",
"plural": "Appliquer les paramètres {n} utilisteurs."
"singular": "Appliquer le paramètre {n} utilisteur.",
"plural": "Appliquer les paramètres {n} utilisteurs."
}
}
}

View File

@ -1,130 +0,0 @@
{
"meta": {
"name": "Nederlands (NL)"
},
"strings": {
"invites": "Uitnodigingen",
"accounts": "Accounts",
"settings": "Instellingen",
"theme": "Thema",
"inviteDays": "Dagen",
"inviteHours": "Uren",
"inviteMinutes": "Minuten",
"inviteNumberOfUses": "Aantal keer gebruikt",
"warning": "Waarschuwing",
"inviteInfiniteUsesWarning": "ongelimiteerde uitnodigingen kunnen misbruikt worden",
"inviteSendToEmail": "Stuur naar",
"login": "Inloggen",
"logout": "Uitloggen",
"create": "Aanmaken",
"apply": "Toepassen",
"delete": "Verwijderen",
"submit": "Verstuur",
"name": "Naam",
"date": "Datum",
"username": "Gebruikersnaam",
"password": "Wachtwoord",
"emailAddress": "Email adres",
"lastActiveTime": "Laatst actief",
"from": "Van",
"user": "Gebruiker",
"aboutProgram": "Over",
"version": "Versie",
"commitNoun": "Commit",
"newUser": "Nieuwe gebruiker",
"profile": "Profiel",
"success": "Success",
"error": "Fout",
"unknown": "Onbekend",
"modifySettings": "Instellingen aanpassen",
"modifySettingsDescription": "Pas instellingen van een bestaand profiel toe, of neem ze direct over van een gebruiker.",
"applyHomescreenLayout": "Sla startpagina indeling op",
"sendDeleteNotificationEmail": "Stuur meldingsemail",
"sendDeleteNotifiationExample": "Je account is verwijderd.",
"settingsRestartRequired": "Herstart nodig",
"settingsRestartRequiredDescription": "Er is een herstart nodig om de wijzigingen door te voeren. Herstart nu of later?",
"settingsApplyRestartLater": "Sla op, herstart later",
"settingsApplyRestartNow": "Sla op & herstart",
"settingsApplied": "Wijzigingen doorgevoerd.",
"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",
"ombiUserDefaultsDescription": "Maak een Ombi gebruiker aan met de gewenste instellingen, en selecteer deze hieronder. Deze instellingen/rechten worden opgeslagen en toegepast voor nieuwe Ombi gebruikers die jfa-go aanmaakt",
"userProfiles": "Gebruikersprofielen",
"userProfilesDescription": "Profielen worden toegepast op gebruikers wanneer ze een account aanmaken. Een profiel bevat rechten voor bibliotheken en indeling van de startpagina.",
"userProfilesIsDefault": "Standaard",
"userProfilesLibraries": "Bibliotheken",
"addProfile": "Voer profiel toe",
"addProfileDescription": "Maak een Jellyfin gebruiker aan met de gewenste instellingen en selecteer deze hieronder. Wanneer dit profiel wordt toegepast op een uitnodiging, worden nieuwe gebruikers aangemaakt met deze instellingen.",
"addProfileNameOf": "Profielnaam",
"addProfileStoreHomescreenLayout": "Sla startpaginaindeling op",
"inviteNoUsersCreated": "Nog geen!",
"inviteUsersCreated": "Aangemaakte gebruikers",
"inviteNoProfile": "Geen profiel",
"copy": "Kopiëer",
"inviteDateCreated": "Aangemaakt",
"inviteRemainingUses": "Resterend aantal gebruiken",
"inviteNoInvites": "Geen",
"inviteExpiresInTime": "Verloopt over {n}",
"notifyEvent": "Meldingen:",
"notifyInviteExpiry": "Bij verloop",
"notifyUserCreation": "Bij aanmaken gebruiker"
},
"notifications": {
"changedEmailAddress": "Email adres van {n} gewijzigd.",
"userCreated": "Gebruiker {n} aangemaakt.",
"createProfile": "Profiel {n} aangemaakt.",
"saveSettings": "De instellingen zijn opgeslagen",
"setOmbiDefaults": "De ombi standaardinstellingen zijn opgeslagen.",
"errorConnection": "Kon geen verbinding maken met jfa-go.",
"error401Unauthorized": "Geen toegang. Probeer de pagina te vernieuwen.",
"errorSettingsAppliedNoHomescreenLayout": "De instellingen zijn toegepast, maar wijzigen van de startpaginaindeling is misschien mislukt.",
"errorHomescreenAppliedNoSettings": "Startpaginaindeling toegepast, maar opslaan van instellingen is misschien mislukt.",
"errorSettingsFailed": "Opslaan mislukt.",
"errorLoginBlank": "De gebruikersnaam en/of wachtwoord is leeg.",
"errorUnknown": "Onbekende fout.",
"errorBlankFields": "Velden leeggelaten",
"errorDeleteProfile": "Verwijderen van profiel {n} mislukt",
"errorLoadProfiles": "Fout bij het laden van profielen.",
"errorCreateProfile": "Aanmaken van profile {n} mislukt",
"errorSetDefaultProfile": "Fout bij instellen van standaardprofiel.",
"errorLoadUsers": "Laden van gebruikers mislukt.",
"errorSaveSettings": "Opslaan van instellingen mislukt.",
"errorLoadSettings": "Laden van instellingen mislukt.",
"errorSetOmbiDefaults": "Opslaan van ombi standaardinstellingen mislukt.",
"errorLoadOmbiUsers": "Laden van ombi gebruikers mislukt.",
"errorChangedEmailAddress": "Wijzigen van emailadres van {n} mislukt.",
"errorFailureCheckLogs": "Mislukt (controleer console/logbestanden)",
"errorPartialFailureCheckLogs": "Gedeeltelijke fout (controleer console/logbestanden)"
},
"quantityStrings": {
"modifySettingsFor": {
"singular": "Wijzig instellingen voor {n} gebruiker",
"plural": "Wijzig instellingen voor {n} gebruikers"
},
"deleteNUsers": {
"singular": "Verwijder {n} gebruiker",
"plural": "Verwijder {n} gebruikers"
},
"addUser": {
"singular": "Voeg gebruiker toe",
"plural": "Voer gebruikers toe"
},
"deleteUser": {
"singular": "Verwijder gebruiker",
"plural": "Verwijder gebruikers"
},
"deletedUser": {
"singular": "{n} gebruiker verwijderd.",
"plural": "{n} gebruikers verwijderd."
},
"appliedSettings": {
"singular": "Instellingen toegepast op {n} gebruiker.",
"plural": "Instellingen toegepast op {n} gebruikers."
}
}
}

View File

@ -1,41 +0,0 @@
{
"meta": {
"name": "Nederlands (NL)"
},
"userCreated": {
"title": "Melding: Gebruiker aangemaakt",
"aUserWasCreated": "Er is een gebruiker aangemaakt door gebruik te maken van code {n}.",
"name": "Naam",
"emailAddress": "Adres",
"time": "Tijdstip",
"notificationNotice": "Opmerking: Meldingsemails kunnen worden aan- of uitgezet via het admin dashboard."
},
"inviteExpiry": {
"title": "Melding: Uitnodiging verlopen",
"inviteExpired": "Uitnodiging verlopen.",
"expiredAt": "Code {n} is verlopen op {n}.",
"notificationNotice": "Opmerking: Meldingsemails kunnen worden aan- of uitgezet via het admin dashboard."
},
"passwordReset": {
"title": "Wachtwoordreset aangevraagd - Jellyfin",
"helloUser": "Hoi {n},",
"someoneHasRequestedReset": "Iemand heeft recentelijk een wachtwoordreset aangevraagd in Jellyfin.",
"ifItWasYou": "Als jij dit was, voor dan onderstaande PIN in.",
"codeExpiry": "De code verloopt op {n}, op {n} UTC, dat is over {n}.",
"ifItWasNotYou": "Als jij dit niet was, negeer dan alsjeblieft deze email.",
"pin": "PIN"
},
"userDeleted": {
"title": "Je account is verwijderd - Jellyfin",
"yourAccountWasDeleted": "Je Jellyfin account is verwijderd.",
"reason": "Reden"
},
"inviteEmail": {
"title": "Uitnodiging - Jellyfin",
"hello": "Hoi",
"youHaveBeenInvited": "Je bent uitgenodigd voor Jellyfin.",
"toJoin": "Volg onderstaande link om door te gaan.",
"inviteExpiry": "Deze uitnodiging verloopt op {n}, om {n}, dat is over {n}, dus wees er snel bij.",
"linkButton": "Maak account aan"
}
}

View File

@ -94,17 +94,12 @@ if (window.location.pathname == "/") {
}
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 = "../"; }
}
if (lang) {
tab += "?lang=" + lang
}
window.history.replaceState("", "Admin - jfa-go", tab);
});

View File

@ -6,7 +6,6 @@ interface formWindow extends Window {
validationStrings: pwValStrings;
invalidPassword: string;
modal: Modal;
code: string;
}
interface pwValString {
@ -89,7 +88,7 @@ const create = (event: SubmitEvent) => {
event.preventDefault();
toggleLoader(submitSpan);
let send: sendDTO = {
code: window.code,
code: window.location.href.split('/').pop(),
username: usernameField.value,
email: emailField.value,
password: passwordField.value

View File

@ -30,11 +30,7 @@ export class DOMInvite implements Invite {
get code(): string { return this._code; }
set code(code: string) {
this._code = code;
let codeLink = window.location.href;
for (let split of ["#", "?"]) {
codeLink = codeLink.split(split)[0];
}
this._codeLink = codeLink + "invite/" + code;
this._codeLink = window.location.href.split("#")[0] + "invite/" + code;
const linkEl = this._codeArea.querySelector("a") as HTMLAnchorElement;
linkEl.textContent = code.replace(/-/g, '-');
linkEl.href = this._codeLink;

View File

@ -7,41 +7,12 @@ import (
"github.com/gin-gonic/gin"
)
var css = []string{"base.css", "a17t.css", "remixicon.css", "modal.css", "dark.css", "tooltip.css", "loader.css"}
var cssHeader = func() string {
l := len(css)
h := ""
for i, f := range css {
h += "</css/" + f + ">; rel=preload; as=style"
if l > 1 && i != (l-1) {
h += ", "
}
}
return h
}()
func gcHTML(gc *gin.Context, code int, file string, templ gin.H) {
gc.Header("Cache-Control", "no-cache")
gc.HTML(code, file, templ)
}
func (app *appContext) pushResources(gc *gin.Context, admin bool) {
if pusher := gc.Writer.Pusher(); pusher != nil {
app.debug.Println("Using HTTP2 Server push")
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 {
app.debug.Printf("Failed HTTP2 ServerPush of \"%s\": %+v", f, err)
}
}
}
}
gc.Header("Link", cssHeader)
}
func (app *appContext) AdminPage(gc *gin.Context) {
app.pushResources(gc, true)
lang := gc.Query("lang")
if lang == "" {
lang = app.storage.lang.chosenAdminLang
@ -51,6 +22,14 @@ func (app *appContext) AdminPage(gc *gin.Context) {
emailEnabled, _ := app.config.Section("invite_emails").Key("enabled").Bool()
notificationsEnabled, _ := app.config.Section("notifications").Key("enabled").Bool()
ombiEnabled := app.config.Section("ombi").Key("enabled").MustBool(false)
if pusher := gc.Writer.Pusher(); pusher != nil {
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 {
app.debug.Printf("Failed HTTP2 ServerPush of \"%s\": %+v", f, err)
}
}
}
gcHTML(gc, http.StatusOK, "admin.html", gin.H{
"urlBase": app.URLBase,
"cssClass": app.cssClass,
@ -68,7 +47,6 @@ func (app *appContext) AdminPage(gc *gin.Context) {
}
func (app *appContext) InviteProxy(gc *gin.Context) {
app.pushResources(gc, false)
code := gc.Param("invCode")
lang := gc.Query("lang")
if lang == "" {
@ -95,7 +73,6 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
"email": email,
"username": !app.config.Section("email").Key("no_username").MustBool(false),
"lang": app.storage.lang.Form[lang]["strings"],
"code": code,
})
} else {
gcHTML(gc, 404, "invalidCode.html", gin.H{
@ -106,7 +83,6 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
}
func (app *appContext) NoRouteHandler(gc *gin.Context) {
app.pushResources(gc, false)
gcHTML(gc, 404, "404.html", gin.H{
"cssClass": app.cssClass,
"contactMessage": app.config.Section("ui").Key("contact_message").String(),