mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 17:10:10 +00:00
split some strings into common file; use lang file to setup page
This commit is contained in:
parent
687edf2b0b
commit
bf1e6230dc
@ -720,7 +720,7 @@
|
||||
"required": false,
|
||||
"requires_restart": false,
|
||||
"type": "text",
|
||||
"value": "Your account was deleted - Jellyfin",
|
||||
"value": "",
|
||||
"description": "Subject of account deletion emails."
|
||||
},
|
||||
"email_html": {
|
||||
|
234
html/setup2.html
234
html/setup2.html
@ -1,9 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="{{ .cssClass }}">
|
||||
<html lang="en" class="light-theme">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="../build/data/web/css/bundle.css">
|
||||
{{ template "header.html" . }}
|
||||
<title>{{ .strings.pageTitle }}</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/bundle.css">
|
||||
<title>{{ .lang.Strings.pageTitle }}</title>
|
||||
</head>
|
||||
<body class="max-w-full overflow-x-hidden section">
|
||||
<div id="notification-box"></div>
|
||||
@ -20,328 +19,327 @@
|
||||
<div class="page-container">
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<div class="row">
|
||||
<img class="banner header" src="../images/banner.svg" alt="jfa-go" />
|
||||
<img class="banner header" src="banner.svg" alt="jfa-go" />
|
||||
</div>
|
||||
<div class="row col flex center">
|
||||
<span class="heading">Welcome!</span>
|
||||
<span class="heading">{{ .lang.StartPage.welcome }}</span>
|
||||
</div>
|
||||
<div class="row col flex center">
|
||||
<p class="content">You'll need to do a few things to set up jfa-go. Press continue to get started.</p>
|
||||
<p class="content">{{ .lang.StartPage.pressStart }}</p>
|
||||
</div>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="support">Make sure you're accessing this page via HTTPS or a Private Network.</span>
|
||||
<span class="button ~urge !normal">Continue</span>
|
||||
<span class="support">{{ .lang.StartPage.httpsNotice }}</span>
|
||||
<span class="button ~urge !normal">{{ .lang.StartPage.start }}</span>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<span class="heading">Language</span>
|
||||
<p class="content">Community translations are available for most parts of jfa-go. You can choose the default languages below, but users can still change it for themselves. If you want to help out, sign up <a href="https://weblate.hrfee.pw">here</a> to start contributing!</p>
|
||||
<span class="heading">{{ .lang.Language.title }}</span>
|
||||
<p class="content" id="language-description"></p>
|
||||
<label class="label">
|
||||
<span class="mt-half">Default admin language</span>
|
||||
<span class="mt-half">{{ .lang.Language.defaultAdminLang }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<select id="ui-language-admin">
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Default account creation language</span>
|
||||
<span class="mt-half">{{ .lang.Language.defaultFormLang }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<select id="ui-language-form">
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Default email language</span>
|
||||
<span class="mt-half">{{ .lang.Language.defaultEmailLang }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<select id="email-language">
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">Back</span>
|
||||
<span class="button ~urge !normal next">Continue</span>
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<span class="heading">Login</span>
|
||||
<p class="content">To access the admin page, you need to login with a method below:</p>
|
||||
<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="login-method" checked><span><b>Authorize through Jellyfin:</b> Login details are shared with Jellyfin, allowing for multiple users.</span>
|
||||
<input type="radio" name="login-method" checked><span>{{ .lang.Login.authorizeWithJellyfin }}</span>
|
||||
</label>
|
||||
<label class="row switch pl-1 pb-1">
|
||||
<input type="checkbox" id="login-jellyfin"><span>Admin users only (recommended)</span>
|
||||
<input type="checkbox" id="login-jellyfin"><span>{{ .lang.Login.adminOnly }}</span>
|
||||
</label>
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="login-method"><span><b>Username & Password:</b> Manually set the username & password.</span>
|
||||
<input type="radio" name="login-method"><span>{{ .lang.Login.authorizeManual }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="login-manual">
|
||||
<label class="label">
|
||||
<span class="mt-half">Username</span>
|
||||
<input type="text" id="login-password" class="input ~neutral !normal mt-half mb-1" placeholder="Username">
|
||||
<span class="mt-half">{{ .lang.Strings.username }}</span>
|
||||
<input type="text" id="login-password" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.username }}">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>Password</span>
|
||||
<input type="password" id="login-username" class="input ~neutral !normal mt-half mb-1" placeholder="Password">
|
||||
<span>{{ .lang.Strings.password }}</span>
|
||||
<input type="password" id="login-username" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.password }}">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>Email address (optional)</span>
|
||||
<span>{{ .lang.Strings.emailAddress }} ({{ .lang.Strings.optional }})</span>
|
||||
<input type="email" class="input ~neutral !normal mt-half" placeholder="email@address">
|
||||
<span class="support mb-1">Your email address can be used to receive activity notifications.</span>
|
||||
<span class="support mb-1">{{ .lang.Login.emailNotice }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">Back</span>
|
||||
<span class="button ~urge !normal next">Continue</span>
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<span class="heading">Jellyfin/Emby</span>
|
||||
<p class="content">jfa-go needs admin access because API tokens don't allow user creation. You should create a separate account and check "Allow this user to manage the server". You can disable everything else. Once done, enter the credentials here.</p>
|
||||
<span class="heading">{{ .lang.JellyfinEmby.title }}</span>
|
||||
<p class="content">{{ .lang.JellyfinEmby.description }}</p>
|
||||
<label class="label">
|
||||
<span>Server Type</span>
|
||||
<span>{{ .lang.Strings.serverType }}</span>
|
||||
<div class="select ~neutral !normal mt-half">
|
||||
<select id="jellyfin-type">
|
||||
<option value="jellyfin">Jellyfin</option>
|
||||
<option value="emby">Emby (experimental)</option>
|
||||
<option value="emby">Emby</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="support mb-1">Emby support is limited and does not support password resets.</p>
|
||||
<p class="support mb-1">{{ .lang.JellyfinEmby.embyNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Server Address (internal)</span>
|
||||
<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">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Server Address (public)</span>
|
||||
<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">Leave blank to use the same address.</p>
|
||||
<p class="support mb-1">{{ .lang.JellyfinEmby.addressExternalNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Username</span>
|
||||
<input type="text" id="jellyfin-username" class="input ~neutral !normal mt-half mb-1" placeholder="Username">
|
||||
<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 }}">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>Password</span>
|
||||
<input type="password" id="jellyfin-password" class="input ~neutral !normal mt-half mb-1" placeholder="Password">
|
||||
<span>{{ .lang.Strings.password }}</span>
|
||||
<input type="password" id="jellyfin-password" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.password }}">
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">Back</span>
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal">Test Connection</span>
|
||||
<span class="button ~urge !normal next" disabled>Continue</span>
|
||||
<span class="button ~urge !normal">{{ .lang.JellyfinEmby.testConnection }}</span>
|
||||
<span class="button ~urge !normal next" disabled>{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<span class="heading">Email</span>
|
||||
<p class="content">jfa-go can send password reset PINs and various notifications. You can connect to an SMTP server, or use the <a href="https://www.mailgun.com/">Mailgun</a> API.</p>
|
||||
<span class="heading">{{ .lang.Email.title }}</span>
|
||||
<p class="content" id="email-description"></p>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label">
|
||||
<span>Server Type</span>
|
||||
<span>{{ .lang.Strings.serverType }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<select id="email-method">
|
||||
<option value="">Disabled</option>
|
||||
<option value="">{{ .lang.Strings.disabled }}</option>
|
||||
<option value="smtp">SMTP</option>
|
||||
<option value="mailgun">Mailgun</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">From Address</span>
|
||||
<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">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Sender Name</span>
|
||||
<span class="mt-half">{{ .lang.Email.senderName }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="email-from" value="Jellyfin">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Date Format</span>
|
||||
<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">Date follows the <a href="https://strftime.org/">strftime</a> format.</p>
|
||||
<p class="support mb-1" id="email-dateformat-notice"></p>
|
||||
</label>
|
||||
<div>
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="email-24h" value="true" checked><span>24h Time</span>
|
||||
<input type="radio" name="email-24h" value="true" checked><span>{{ .lang.Email.time24h }}</span>
|
||||
</label>
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="email-24h" value="false"><span>12h Time</span>
|
||||
<input type="radio" name="email-24h" value="false"><span>{{ .lang.Email.time12h }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<label class="label">
|
||||
<span class="mt-half">Message</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="email-message" value="Need help? Contact me.">
|
||||
<p class="support mb-1">A short message displayed at the bottom of emails.</p>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div id="email-smtp">
|
||||
<label class="label">
|
||||
<span>Encryption</span>
|
||||
<span>{{ .lang.Email.encryption }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<select id="smtp-encryption">
|
||||
<option value="starttls">STARTTLS (Usually port 587)</option>
|
||||
<option value="ssl_tls">SSL/TLS (Usually port 465)</option>
|
||||
<option value="starttls">STARTTLS ({{ .lang.Strings.port }} 587)</option>
|
||||
<option value="ssl_tls">SSL/TLS ({{ .lang.Strings.port }} 465)</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Server Address</span>
|
||||
<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">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Port</span>
|
||||
<span class="mt-half">{{ .lang.Strings.port }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="smtp-port" placeholder="587">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Username</span>
|
||||
<span class="mt-half">{{ .lang.Strings.username }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="smtp-username">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Password</span>
|
||||
<span class="mt-half">{{ .lang.Strings.password }}</span>
|
||||
<input type="password" class="input ~neutral !normal mt-half mb-1" id="smtp-password">
|
||||
</label>
|
||||
</div>
|
||||
<div id="email-mailgun">
|
||||
<label class="label">
|
||||
<span class="mt-half">API URL</span>
|
||||
<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">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">API Key</span>
|
||||
<span class="mt-half">{{ .lang.Email.mailgunApiKey }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="mailgun-api_key">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">Back</span>
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">Continue</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<span class="heading">Notifications</span>
|
||||
<p class="content">If enabled, you can choose (per invite) to receive an email when an invite expires, or a user is created. If you didn't choose Jellyfin Authentication, make sure you provided an email address.</p>
|
||||
<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>Enabled</span>
|
||||
<input type="checkbox" id="notifications-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<span class="heading">Password Resets</span>
|
||||
<p class="content">When a user tries to reset their password, Jellyfin creates a file named "passwordreset-*.json" which contains a PIN. jfa-go reads the file and sends the PIN to the user.</p>
|
||||
<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>Enabled</span>
|
||||
<input type="checkbox" id="password_resets-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Path to Jellyfin configuration directory</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="password_resets-watch_directory" placeholder="/path/to/jellyfin">
|
||||
<p class="support mb-1">If you don't know where this is, Try resetting your password in Jellyfin. A popup with the "<path to jellyfin>/passwordreset-*.json" will appear.</p>
|
||||
<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>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Email subject</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="password_resets-subject" value="Password Reset - Jellyfin">
|
||||
<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 }}">
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">Back</span>
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">Continue</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<span class="heading">Invite Emails</span>
|
||||
<p class="content">If enabled, you can send invites directly to a user's email address. Because you might be using a reverse proxy, you need to provide the URL invites are accessed from. Write your URL Base and append "/invite".</p>
|
||||
<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>Enabled</span>
|
||||
<input type="checkbox" id="invite_emails-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">URL</span>
|
||||
<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">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Email subject</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="invite_emails-subject" value="Invite - Jellyfin">
|
||||
<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 }}">
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">Back</span>
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">Continue</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<span class="heading">Password Validation</span>
|
||||
<p class="content">If enabled, a set of password requirements will show on the create account page, such as minimum length, uppercase/lowercase characters, etc.</p>
|
||||
<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>Enabled</span>
|
||||
<input type="checkbox" id="password_validation-enabled" checked><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Length</span>
|
||||
<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">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Uppercase characters</span>
|
||||
<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">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Lowercase characters</span>
|
||||
<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">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Numbers</span>
|
||||
<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">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Special (%, *, etc.)</span>
|
||||
<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">
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">Back</span>
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">Continue</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<span class="heading">Help Messages</span>
|
||||
<p class="content">These messages will display in the account creation page and in emails.</p>
|
||||
<span class="heading">{{ .lang.HelpMessages.title }}</span>
|
||||
<p class="content">{{ .lang.HelpMessages.description }}</p>
|
||||
<label class="label">
|
||||
<span class="mt-half">Contact Message</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="ui-contact_message" value="Need help? Contact me.">
|
||||
<p class="support mb-1">Displays at the bottom of all pages except admin.</p>
|
||||
<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>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Help Message</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="ui-help_message" value="Enter your details to create an account.">
|
||||
<p class="support mb-1">Displays on the account creation page.</p>
|
||||
<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>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">Success Message</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="ui-success_message" value="Your account has been created. Click below to continue to Jellyfin.">
|
||||
<p class="support mb-1">Displays when a user creates their account.</p>
|
||||
<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>
|
||||
</label>
|
||||
<label class="label">
|
||||
<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>
|
||||
</label>
|
||||
<section class="section ~neutral banner footer flex-expand middle">
|
||||
<span class="button ~neutral !normal back">Back</span>
|
||||
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
|
||||
<div>
|
||||
<span class="button ~urge !normal next">Continue</span>
|
||||
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1">
|
||||
<div class="row col flex center">
|
||||
<span class="heading">Finished!</span>
|
||||
<span class="heading">{{ .lang.EndPage.finished }}</span>
|
||||
</div>
|
||||
<div class="row col flex center">
|
||||
<p class="content">There are more settings you can configure on the admin page. Click below to restart, then refresh the page.</p>
|
||||
<p class="content">{{ .lang.EndPage.restartMessage }}</p>
|
||||
</div>
|
||||
<div class="row col flex center">
|
||||
<span class="button ~urge !normal" id="restart">Submit</span>
|
||||
<span class="button ~urge !normal" id="restart">{{ .lang.Strings.submit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ template "form-base" . }}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
36
lang.go
36
lang.go
@ -26,6 +26,13 @@ func (ls *adminLangs) getOptions(chosen string) (string, []string) {
|
||||
return chosenLang, opts
|
||||
}
|
||||
|
||||
type commonLangs map[string]commonLang
|
||||
|
||||
type commonLang struct {
|
||||
Meta langMeta `json:"meta"`
|
||||
Strings langSection `json:"strings"`
|
||||
}
|
||||
|
||||
type adminLang struct {
|
||||
Meta langMeta `json:"meta"`
|
||||
Strings langSection `json:"strings"`
|
||||
@ -77,6 +84,35 @@ type emailLang struct {
|
||||
WelcomeEmail langSection `json:"welcomeEmail"`
|
||||
}
|
||||
|
||||
type setupLangs map[string]setupLang
|
||||
|
||||
type setupLang struct {
|
||||
Meta langMeta `json:"meta"`
|
||||
Strings langSection `json:"strings"`
|
||||
StartPage langSection `json:"startPage"`
|
||||
EndPage langSection `json:"endPage"`
|
||||
Language langSection `json:"language"`
|
||||
Login langSection `json:"login"`
|
||||
JellyfinEmby langSection `json:"jellyfinEmby"`
|
||||
Email langSection `json:"email"`
|
||||
Notifications langSection `json:"notifications"`
|
||||
PasswordResets langSection `json:"passwordResets"`
|
||||
InviteEmails langSection `json:"inviteEmails"`
|
||||
PasswordValidation langSection `json:"passwordValidation"`
|
||||
HelpMessages langSection `json:"helpMessages"`
|
||||
}
|
||||
|
||||
func (ls *setupLangs) getOptions(chosen string) (string, []string) {
|
||||
opts := make([]string, len(*ls))
|
||||
chosenLang := (*ls)[chosen].Meta.Name
|
||||
i := 0
|
||||
for _, lang := range *ls {
|
||||
opts[i] = lang.Meta.Name
|
||||
i++
|
||||
}
|
||||
return chosenLang, opts
|
||||
}
|
||||
|
||||
type langSection map[string]string
|
||||
|
||||
func (el langSection) format(field string, vals ...string) string {
|
||||
|
@ -19,12 +19,8 @@
|
||||
"create": "Erstellen",
|
||||
"apply": "Anwenden",
|
||||
"delete": "Löschen",
|
||||
"submit": "Absenden",
|
||||
"name": "Name",
|
||||
"date": "Datum",
|
||||
"username": "Benutzername",
|
||||
"password": "Passwort",
|
||||
"emailAddress": "E-Mail-Adresse",
|
||||
"lastActiveTime": "Zuletzt aktiv",
|
||||
"from": "Von",
|
||||
"user": "Benutzer",
|
||||
|
@ -19,12 +19,8 @@
|
||||
"create": "Create",
|
||||
"apply": "Apply",
|
||||
"delete": "Delete",
|
||||
"submit": "Submit",
|
||||
"name": "Name",
|
||||
"date": "Date",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"emailAddress": "Email Address",
|
||||
"lastActiveTime": "Last Active",
|
||||
"from": "From",
|
||||
"user": "User",
|
||||
|
@ -20,12 +20,8 @@
|
||||
"create": "Créer",
|
||||
"apply": "Appliquer",
|
||||
"delete": "Effacer",
|
||||
"submit": "Soumettre",
|
||||
"name": "Nom",
|
||||
"date": "Date",
|
||||
"username": "Nom d'utilisateur",
|
||||
"password": "Mot de passe",
|
||||
"emailAddress": "Addresse Email",
|
||||
"lastActiveTime": "Dernière activité",
|
||||
"from": "De",
|
||||
"user": "Utilisateur",
|
||||
|
@ -19,12 +19,8 @@
|
||||
"create": "Aanmaken",
|
||||
"apply": "Toepassen",
|
||||
"delete": "Verwijderen",
|
||||
"submit": "Verstuur",
|
||||
"name": "Naam",
|
||||
"date": "Datum",
|
||||
"username": "Gebruikersnaam",
|
||||
"password": "Wachtwoord",
|
||||
"emailAddress": "E-mailadres",
|
||||
"lastActiveTime": "Laatst actief",
|
||||
"from": "Van",
|
||||
"user": "Gebruiker",
|
||||
|
11
lang/common/de-de.json
Normal file
11
lang/common/de-de.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Deutsch (DE)"
|
||||
},
|
||||
"strings": {
|
||||
"username": "Benutzername",
|
||||
"password": "Passwort",
|
||||
"emailAddress": "E-Mail-Adresse",
|
||||
"submit": "Absenden"
|
||||
}
|
||||
}
|
11
lang/common/en-us.json
Normal file
11
lang/common/en-us.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "English (US)"
|
||||
},
|
||||
"strings": {
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"emailAddress": "Email Address",
|
||||
"submit": "Submit"
|
||||
}
|
||||
}
|
12
lang/common/fr-fr.json
Normal file
12
lang/common/fr-fr.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Francais (FR)",
|
||||
"author": "https://github.com/Killianbe"
|
||||
},
|
||||
"strings": {
|
||||
"username": "Nom d'utilisateur",
|
||||
"password": "Mot de passe",
|
||||
"emailAddress": "Addresse Email",
|
||||
"submit": "Soumettre"
|
||||
}
|
||||
}
|
11
lang/common/nl-nl.json
Normal file
11
lang/common/nl-nl.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Nederlands (NL)"
|
||||
},
|
||||
"strings": {
|
||||
"username": "Gebruikersnaam",
|
||||
"password": "Wachtwoord",
|
||||
"emailAddress": "E-mailadres",
|
||||
"submit": "Verstuur"
|
||||
}
|
||||
}
|
101
lang/setup/en-us.json
Normal file
101
lang/setup/en-us.json
Normal file
@ -0,0 +1,101 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "English (US)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Setup - jfa-go",
|
||||
"next": "Next",
|
||||
"back": "Back",
|
||||
"optional": "Optional",
|
||||
"serverType": "Server Type",
|
||||
"disabled": "Disabled",
|
||||
"enabled": "Enabled",
|
||||
"port": "Port",
|
||||
"message": "Message",
|
||||
"serverAddress": "Server Address",
|
||||
"emailSubject": "Email Subject",
|
||||
"URL": "URL"
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Welcome!",
|
||||
"pressStart": "You'll need to do a few things to set up jfa-go. Press start to get continue.",
|
||||
"httpsNotice": "Make sure you're accessing this page via HTTPS or on a private network.",
|
||||
"start": "Start"
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "Finished!",
|
||||
"restartMessage": "There are more settings you can configure on the admin page. Click below to restart, then refresh the page."
|
||||
},
|
||||
"language": {
|
||||
"title": "Language",
|
||||
"description": "Community translations are available for most parts of jfa-go. You can choose the default languages below, but users can still change it if they wish. If you want to help translate, sign up to {n} to start contributing!",
|
||||
"defaultAdminLang": "Default admin language",
|
||||
"defaultFormLang": "Default account creation language",
|
||||
"defaultEmailLang": "Default email language"
|
||||
},
|
||||
"login": {
|
||||
"title": "Login",
|
||||
"description": "To access the admin page, you need to login with a method below:",
|
||||
"authorizeWithJellyfin": "Authorize with Jellyfin/Emby: Login details are shared with Jellyfin, which allows for multiple users.",
|
||||
"authorizeManual": "Username and Password: Manually set the username and password.",
|
||||
"adminOnly": "Admin users only (recommended)",
|
||||
"emailNotice": "Your email address can be used to receive notifications."
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
"description": "An admin account is needed because the API does not allow user creation using an API key. You should create a separate account and check 'Allow this user to manage the server'. You can disable everything else. Once done, enter the login details here.",
|
||||
"embyNotice": "Emby support is limited and does not support password resets.",
|
||||
"internal": "Internal",
|
||||
"external": "External",
|
||||
"addressExternalNotice": "Leave blank to use the same address.",
|
||||
"testConnection": "Test Connection"
|
||||
},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"description": "jfa-go can send password reset PINs and various notifications through email. You can connect to an SMTP server, or use the {n} API.",
|
||||
"fromAddress": "From Address",
|
||||
"senderName": "Sender Name",
|
||||
"dateFormat": "Date Format",
|
||||
"dateFormatNotice": "Date follows the strftime format. For more info, visit {n}.",
|
||||
"time24h": "24h Time",
|
||||
"time12h": "12h Time",
|
||||
"encryption": "Encryption",
|
||||
"mailgunApiURL": "API URL",
|
||||
"mailgunApiKey": "API Key"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Notifications",
|
||||
"description": "If enabled, you can choose (per invite) to receive an email when an invite expires, or a user is created. If you didn't choose the Jellyfin login method, make sure you provided your email address."
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "Password Resets",
|
||||
"description": "When a user tries to reset their password, Jellyfin creates a file named 'passwordreset-*.json' which contains a PIN. jfa-go reads the file and sends the PIN to the user.",
|
||||
"pathToJellyfin": "Path to Jellyfin configuration directory",
|
||||
"pathToJellyfinNotice": "If you don't know where this is, try resetting your password in Jellyfin. A popup with '<path to jellyfin>/passwordreset-*.json' will appear."
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "Invite Emails",
|
||||
"description": "If enabled, you can send invites directly to a user's email address. Because you might be using a reverse proxy, you need to provide the URL invites are accessed from. Write your URL Base, and append '/invite'."
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "Password Validation",
|
||||
"description": "If enabled, a set of password requirements will show on the account creation page, such as minimum length, uppercase/lowercase characters, etc.",
|
||||
"length": "Length",
|
||||
"uppercase": "Uppercase characters",
|
||||
"lowercase": "Lowercase characters",
|
||||
"numbers": "Numbers",
|
||||
"special": "Special characters (%, *, etc.)"
|
||||
},
|
||||
"helpMessages": {
|
||||
"title": "Help Messages",
|
||||
"description": "These messages will display in the account creation page and in some emails.",
|
||||
"contactMessage": "Contact Message",
|
||||
"contactMessageNotice": "Displays at the bottom of all pages except admin.",
|
||||
"helpMessage": "Help Message",
|
||||
"helpMessageNotice": "Displays on the account creation page.",
|
||||
"successMessage": "Success Message",
|
||||
"successMessageNotice": "Displays when a user creates their account.",
|
||||
"emailMessage": "Email Message",
|
||||
"emailMessageNotice": "Displays at the bottom of emails."
|
||||
}
|
||||
}
|
21
main.go
21
main.go
@ -516,6 +516,7 @@ func start(asDaemon, firstCall bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
app.storage.lang.CommonPath = filepath.Join(app.localPath, "lang", "common")
|
||||
app.storage.lang.FormPath = filepath.Join(app.localPath, "lang", "form")
|
||||
app.storage.lang.AdminPath = filepath.Join(app.localPath, "lang", "admin")
|
||||
app.storage.lang.EmailPath = filepath.Join(app.localPath, "lang", "email")
|
||||
@ -559,6 +560,22 @@ func start(asDaemon, firstCall bool) {
|
||||
} else {
|
||||
debugMode = false
|
||||
address = "0.0.0.0:8056"
|
||||
|
||||
app.storage.lang.CommonPath = filepath.Join(app.localPath, "lang", "common")
|
||||
app.storage.lang.EmailPath = filepath.Join(app.localPath, "lang", "email")
|
||||
app.storage.lang.SetupPath = filepath.Join(app.localPath, "lang", "setup")
|
||||
err := app.storage.loadLangCommon()
|
||||
if err != nil {
|
||||
app.info.Fatalf("Failed to load language files: %+v\n", err)
|
||||
}
|
||||
err = app.storage.loadLangEmail()
|
||||
if err != nil {
|
||||
app.info.Fatalf("Failed to load language files: %+v\n", err)
|
||||
}
|
||||
err = app.storage.loadLangSetup()
|
||||
if err != nil {
|
||||
app.info.Fatalf("Failed to load language files: %+v\n", err)
|
||||
}
|
||||
}
|
||||
app.info.Println("Loading routes")
|
||||
if debugMode {
|
||||
@ -618,9 +635,7 @@ func start(asDaemon, firstCall bool) {
|
||||
}
|
||||
app.info.Printf("Starting router @ %s", address)
|
||||
} else {
|
||||
router.GET("/", func(gc *gin.Context) {
|
||||
gc.HTML(200, "setup.html", gin.H{})
|
||||
})
|
||||
router.GET("/", app.ServeSetup)
|
||||
router.POST("/jellyfin/test", app.TestJF)
|
||||
router.POST("/config", app.ModifyConfig)
|
||||
app.info.Printf("Loading setup @ %s", address)
|
||||
|
74
setup.go
74
setup.go
@ -1,11 +1,33 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/hrfee/jfa-go/common"
|
||||
"github.com/hrfee/jfa-go/mediabrowser"
|
||||
)
|
||||
|
||||
func (app *appContext) ServeSetup(gc *gin.Context) {
|
||||
lang := gc.Query("lang")
|
||||
if lang == "" {
|
||||
lang = "en-us"
|
||||
} else if _, ok := app.storage.lang.Admin[lang]; !ok {
|
||||
lang = "en-us"
|
||||
}
|
||||
emailLang := lang
|
||||
if _, ok := app.storage.lang.Email[lang]; !ok {
|
||||
emailLang = "en-us"
|
||||
}
|
||||
gc.HTML(200, "setup2.html", gin.H{
|
||||
"lang": app.storage.lang.Setup[lang],
|
||||
"emailLang": app.storage.lang.Email[emailLang],
|
||||
})
|
||||
}
|
||||
|
||||
type testReq struct {
|
||||
Host string `json:"jfHost"`
|
||||
Username string `json:"jfUser"`
|
||||
@ -24,3 +46,55 @@ func (app *appContext) TestJF(gc *gin.Context) {
|
||||
}
|
||||
gc.JSON(200, map[string]bool{"success": true})
|
||||
}
|
||||
|
||||
func (st *Storage) loadLangSetup() error {
|
||||
st.lang.Setup = map[string]setupLang{}
|
||||
var english setupLang
|
||||
load := func(fname string) error {
|
||||
index := strings.TrimSuffix(fname, filepath.Ext(fname))
|
||||
lang := setupLang{}
|
||||
f, err := ioutil.ReadFile(filepath.Join(st.lang.SetupPath, fname))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(f, &lang)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
st.lang.Common.patchCommon(index, &lang.Strings)
|
||||
if fname != "en-us.json" {
|
||||
patchLang(&english.Strings, &lang.Strings)
|
||||
patchLang(&english.StartPage, &lang.StartPage)
|
||||
patchLang(&english.EndPage, &lang.EndPage)
|
||||
patchLang(&english.Language, &lang.Language)
|
||||
patchLang(&english.Login, &lang.Login)
|
||||
patchLang(&english.JellyfinEmby, &lang.JellyfinEmby)
|
||||
patchLang(&english.Email, &lang.Email)
|
||||
patchLang(&english.Notifications, &lang.Notifications)
|
||||
patchLang(&english.PasswordResets, &lang.PasswordResets)
|
||||
patchLang(&english.InviteEmails, &lang.InviteEmails)
|
||||
patchLang(&english.PasswordValidation, &lang.PasswordValidation)
|
||||
patchLang(&english.HelpMessages, &lang.HelpMessages)
|
||||
}
|
||||
st.lang.Setup[index] = lang
|
||||
return nil
|
||||
}
|
||||
err := load("en-us.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
english = st.lang.Setup["en-us"]
|
||||
files, err := ioutil.ReadDir(st.lang.SetupPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range files {
|
||||
if f.Name() != "en-us.json" {
|
||||
err = load(f.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
67
storage.go
67
storage.go
@ -55,9 +55,17 @@ type Lang struct {
|
||||
Form formLangs
|
||||
EmailPath string
|
||||
Email emailLangs
|
||||
CommonPath string
|
||||
Common commonLangs
|
||||
SetupPath string
|
||||
Setup setupLangs
|
||||
}
|
||||
|
||||
func (st *Storage) loadLang() (err error) {
|
||||
err = st.loadLangCommon()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = st.loadLangAdmin()
|
||||
if err != nil {
|
||||
return
|
||||
@ -70,6 +78,20 @@ func (st *Storage) loadLang() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (common *commonLangs) patchCommon(lang string, other *langSection) {
|
||||
if *other == nil {
|
||||
*other = langSection{}
|
||||
}
|
||||
if _, ok := (*common)[lang]; !ok {
|
||||
lang = "en-us"
|
||||
}
|
||||
for n, ev := range (*common)[lang].Strings {
|
||||
if v, ok := (*other)[n]; !ok || v == "" {
|
||||
(*other)[n] = ev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If a given language has missing values, fill it in with the english value.
|
||||
func patchLang(english, other *langSection) {
|
||||
if *other == nil {
|
||||
@ -97,6 +119,49 @@ func patchQuantityStrings(english, other *map[string]quantityString) {
|
||||
}
|
||||
}
|
||||
|
||||
func (st *Storage) loadLangCommon() error {
|
||||
st.lang.Common = map[string]commonLang{}
|
||||
var english commonLang
|
||||
load := func(fname string) error {
|
||||
index := strings.TrimSuffix(fname, filepath.Ext(fname))
|
||||
lang := commonLang{}
|
||||
f, err := ioutil.ReadFile(filepath.Join(st.lang.CommonPath, fname))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if substituteStrings != "" {
|
||||
f = []byte(strings.ReplaceAll(string(f), "Jellyfin", substituteStrings))
|
||||
}
|
||||
err = json.Unmarshal(f, &lang)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fname != "en-us.json" {
|
||||
patchLang(&english.Strings, &lang.Strings)
|
||||
}
|
||||
st.lang.Common[index] = lang
|
||||
return nil
|
||||
}
|
||||
err := load("en-us.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
english = st.lang.Common["en-us"]
|
||||
files, err := ioutil.ReadDir(st.lang.CommonPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range files {
|
||||
if f.Name() != "en-us.json" {
|
||||
err = load(f.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *Storage) loadLangAdmin() error {
|
||||
st.lang.Admin = map[string]adminLang{}
|
||||
var english adminLang
|
||||
@ -114,6 +179,7 @@ func (st *Storage) loadLangAdmin() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
st.lang.Common.patchCommon(index, &lang.Strings)
|
||||
if fname != "en-us.json" {
|
||||
patchLang(&english.Strings, &lang.Strings)
|
||||
patchLang(&english.Notifications, &lang.Notifications)
|
||||
@ -164,6 +230,7 @@ func (st *Storage) loadLangForm() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
st.lang.Common.patchCommon(index, &lang.Strings)
|
||||
if fname != "en-us.json" {
|
||||
patchLang(&english.Strings, &lang.Strings)
|
||||
patchQuantityStrings(&english.ValidationStrings, &lang.ValidationStrings)
|
||||
|
Loading…
Reference in New Issue
Block a user