mirror of
https://github.com/hrfee/jfa-go.git
synced 2026-01-18 16:47:42 +01:00
web: remove almost every use of ml/mr
replace with flex and gap mostly. For #450.
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
{{ if .discordEnabled }}
|
||||
<div id="modal-discord" class="modal">
|
||||
<div class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3">
|
||||
<span class="heading mb-4">{{ .strings.linkDiscord }}</span>
|
||||
<p class="content mb-4"> {{ .discordSendPINMessage }}</p>
|
||||
<h1 class="text-center text-2xl mb-2 pin"></h1>
|
||||
<div class="row center">
|
||||
<a class="my-5 hover:underline">
|
||||
<span class="mr-2">{{ .strings.joinTheServer }}</span>
|
||||
<span id="discord-invite"></span>
|
||||
<div class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3 flex flex-col gap-4">
|
||||
<span class="heading">{{ .strings.linkDiscord }}</span>
|
||||
<p class="content"> {{ .discordSendPINMessage }}</p>
|
||||
<h1 class="text-center text-2xl pin"></h1>
|
||||
<div class="flex flex-row gap-2 justify-center items-center">
|
||||
<a class="hover:underline flex flex-row gap-4 items-center">
|
||||
<span>{{ .strings.joinTheServer }}</span>
|
||||
<span id="discord-invite" class="flex flex-row gap-2 items-center"></span>
|
||||
</a>
|
||||
</div>
|
||||
<span class="button ~info @low full-width center mt-4" id="discord-waiting">{{ .strings.success }}</span>
|
||||
<span class="button ~info @low full-width center" id="discord-waiting">{{ .strings.success }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
{{ if .matrixEnabled }}
|
||||
<div id="modal-matrix" class="modal">
|
||||
<div class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3">
|
||||
<span class="heading mb-4">{{ .strings.linkMatrix }}</span>
|
||||
<p class="content mb-4"> {{ .strings.matrixEnterUser }}</p>
|
||||
<div class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3 flex flex-col gap-4">
|
||||
<span class="heading">{{ .strings.linkMatrix }}</span>
|
||||
<p class="content"> {{ .strings.matrixEnterUser }}</p>
|
||||
<input type="text" class="input ~neutral @high" placeholder="@user:riot.im" id="matrix-userid">
|
||||
<div class="subheading link-center mt-4">
|
||||
<span class="shield ~info mr-4">
|
||||
<div class="subheading flex flex-row gap-2 justify-center items-center">
|
||||
<span class="shield ~info">
|
||||
<span class="icon">
|
||||
<i class="ri-chat-3-line"></i>
|
||||
</span>
|
||||
</span>
|
||||
{{ .matrixUser }}
|
||||
<span>{{ .matrixUser }}</span>
|
||||
</div>
|
||||
<span class="button ~info @low full-width center mt-4" id="matrix-send">{{ .strings.submit }}</span>
|
||||
<span class="button ~info @low full-width center" id="matrix-send">{{ .strings.submit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
{{ if .telegramEnabled }}
|
||||
<div id="modal-telegram" class="modal">
|
||||
<div class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3">
|
||||
<span class="heading mb-4">{{ .strings.linkTelegram }}</span>
|
||||
<p class="content mb-4">{{ .strings.sendPIN }}</p>
|
||||
<p class="text-center text-2xl mb-2 pin"></p>
|
||||
<a class="subheading link link-center" href="{{ .telegramURL }}" target="_blank">
|
||||
<span class="shield ~info mr-4">
|
||||
<div class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3 flex flex-col gap-4">
|
||||
<span class="heading">{{ .strings.linkTelegram }}</span>
|
||||
<p class="content">{{ .strings.sendPIN }}</p>
|
||||
<p class="text-center text-2xl pin"></p>
|
||||
<a class="subheading link flex flex-row gap-2 justify-center items-center" href="{{ .telegramURL }}" target="_blank">
|
||||
<span class="shield ~info">
|
||||
<span class="icon">
|
||||
<i class="ri-telegram-line"></i>
|
||||
</span>
|
||||
</span>
|
||||
@<span class="username">{{ .telegramUsername }}</span>
|
||||
<span class="hover:underline">@<span class="username">{{ .telegramUsername }}</span></span>
|
||||
</a>
|
||||
<span class="button ~info @low full-width center mt-4" id="telegram-waiting">{{ .strings.success }}</span>
|
||||
<span class="button ~info @low full-width center" id="telegram-waiting">{{ .strings.success }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<p>{{ .strings.buildTime }} <span class="text-black dark:text-white font-mono bg-inherit">{{ .buildTime }}</span></p>
|
||||
<p>{{ .strings.builtBy }} <span class="text-black dark:text-white font-mono bg-inherit">{{ .builtBy }}</span></p>
|
||||
<p>{{ .strings.buildTags }} <span class="text-black dark:text-white font-mono bg-inherit">{{ .buildTags }}</span></p>
|
||||
<div class="flex flex-row flex-wrap gap-2 my-2">
|
||||
<div class="flex flex-row flex-wrap gap-2">
|
||||
<a class="button ~neutral lang-link flex flex-row gap-2" href="https://github.com/hrfee/jfa-go"><i class="ri-github-line"></i>github</a>
|
||||
<a class="button ~urge lang-link" href="https://wiki.jfa-go.com">wiki/docs</a>
|
||||
<a class="button ~positive lang-link" href="https://weblate.jfa-go.com">translation</a>
|
||||
@@ -56,9 +56,9 @@
|
||||
<span class="chev"></span>
|
||||
</a>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button ~neutral mb-2 w-full lang-link">GitHub</a>
|
||||
<a href="https://ko-fi.com/hrfee" target="_blank" class="button ~neutral mb-2 w-full lang-link">Ko-fi</a>
|
||||
<div class="card ~neutral @low flex flex-col gap-2">
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button ~neutral w-full lang-link">GitHub</a>
|
||||
<a href="https://ko-fi.com/hrfee" target="_blank" class="button ~neutral w-full lang-link">Ko-fi</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -82,10 +82,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal-modify-user" class="modal">
|
||||
<form class="card relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3" id="form-modify-user" href="">
|
||||
<form class="card relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3 flex flex-col gap-2" id="form-modify-user" href="">
|
||||
<span class="heading"><span id="header-modify-user"></span> <span class="modal-close">×</span></span>
|
||||
<p class="content my-4">{{ .strings.modifySettingsDescription }}</p>
|
||||
<div class="flex flex-col gap-4 my-2">
|
||||
<p class="content">{{ .strings.modifySettingsDescription }}</p>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-row gap-2">
|
||||
<label class="grow">
|
||||
<input type="radio" name="modify-user-source" class="unfocused" id="radio-use-profile" checked>
|
||||
@@ -257,7 +257,7 @@
|
||||
<input type="checkbox" id="expiry-extend-enable" checked>
|
||||
<span>{{ .strings.sendDeleteNotificationEmail }}</span>
|
||||
</label>
|
||||
<textarea id="textarea-extend-enable" class="textarea full-width ~neutral @low mb-4" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
|
||||
<textarea id="textarea-extend-enable" class="textarea full-width ~neutral @low" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~critical @low full-width center supra submit">{{ .strings.submit }}</span>
|
||||
@@ -375,7 +375,7 @@
|
||||
<button class="button ~info @low" id="settings-backups-backup">{{ .strings.backupNow }}</button>
|
||||
<button class="button ~neutral @low" id="settings-backups-upload">{{ .strings.backupUpload }}</button>
|
||||
<input id="backups-file" name="backups-file" type="file" hidden>
|
||||
<button class="button ~neutral @low" id="settings-backups-sort-direction">{{ .strings.sortDirection }}</button>
|
||||
<button class="button ~neutral @low flex flex-row gap-2" id="settings-backups-sort-direction">{{ .strings.sortDirection }}</button>
|
||||
</div>
|
||||
<div class="overflow-x-auto text-xs md:text-sm">
|
||||
<table class="table">
|
||||
@@ -400,7 +400,7 @@
|
||||
<p class="content">{{ .strings.backupCanDownload }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<button class="button flex w-full ~info @low"><span class="flex items-center" id="settings-backed-up-download">{{ .strings.download }}</span></button>
|
||||
<button class="button flex w-full ~info @low"><span class="flex flex-row gap-2 items-center" id="settings-backed-up-download">{{ .strings.download }}</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -515,27 +515,27 @@
|
||||
</form>
|
||||
</div>
|
||||
<div id="modal-update" class="modal">
|
||||
<div class="relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3 content card">
|
||||
<div class="relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3 card flex flex-col gap-2">
|
||||
<span class="heading">{{ .strings.updates }} <span class="modal-close">×</span></span>
|
||||
<p class="content">
|
||||
<h2 class="mt-2">
|
||||
<div class="content flex flex-col">
|
||||
<h2>
|
||||
<a id="update-version"></a> (<span class="font-mono bg-inherit" id="update-commit"></span>)
|
||||
</h2>
|
||||
<p class="content mt-2" id="update-description"></p>
|
||||
<p class="support mt-2" id="update-date"></p>
|
||||
<div class="content markdown-box mt-2" id="update-changelog"></div>
|
||||
</p>
|
||||
<span class="button ~info @low full-width center mt-2" id="update-download">{{ .strings.download }}</span>
|
||||
<span class="button ~urge @low full-width center mt-2" id="update-update">{{ .strings.update }}</span>
|
||||
<p class="content" id="update-description"></p>
|
||||
<div class="content markdown-box" id="update-changelog"></div>
|
||||
<p class="support" id="update-date"></p>
|
||||
</div>
|
||||
<span class="button ~info @low full-width center" id="update-download">{{ .strings.download }}</span>
|
||||
<span class="button ~urge @low full-width center" id="update-update">{{ .strings.update }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ template "account-linking-telegram.html" . }}
|
||||
{{ if .discordEnabled }}
|
||||
<div id="modal-discord" class="modal">
|
||||
<div class="card relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3">
|
||||
<span class="heading mb-4"><span id="discord-header"></span><span class="modal-close">×</span></span>
|
||||
<p class="content mb-4" id="discord-description"></p>
|
||||
<div class="row">
|
||||
<div class="card relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3 flex flex-col gap-2">
|
||||
<span class="heading"><span id="discord-header"></span><span class="modal-close">×</span></span>
|
||||
<p class="content" id="discord-description"></p>
|
||||
<div>
|
||||
<input type="search" class="col sm field ~neutral @low input" id="discord-search" placeholder="user#1234">
|
||||
</div>
|
||||
<table class="table"><tbody id="discord-list"></tbody></table>
|
||||
@@ -543,12 +543,21 @@
|
||||
</div>
|
||||
{{ end }}
|
||||
<div id="modal-matrix" class="modal">
|
||||
<form class="card relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3" id="form-matrix" href="">
|
||||
<form class="card relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3 flex flex-col gap-2" id="form-matrix" href="">
|
||||
<span class="heading">{{ .strings.linkMatrix }}</span>
|
||||
<p class="content my-4">{{ .strings.linkMatrixDescription }}</p>
|
||||
<input type="text" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.matrixHomeServer }}" id="matrix-homeserver">
|
||||
<input type="text" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.username }}" id="matrix-user">
|
||||
<input type="password" class="field input ~neutral @high mt-4 mb-2" placeholder="{{ .strings.password }}" id="matrix-password">
|
||||
<p class="content">{{ .strings.linkMatrixDescription }}</p>
|
||||
<label class="flex flex-col gap-2">
|
||||
<span class="supra">{{ .strings.matrixHomeServer }}</span>
|
||||
<input type="text" class="field input ~neutral @high" placeholder="{{ .strings.matrixHomeServer }}" id="matrix-homeserver">
|
||||
</label>
|
||||
<label class="flex flex-col gap-2">
|
||||
<span class="supra">{{ .strings.username }}</span>
|
||||
<input type="text" class="field input ~neutral @high" placeholder="{{ .strings.username }}" id="matrix-user">
|
||||
</label>
|
||||
<label class="flex flex-col gap-2">
|
||||
<span class="supra">{{ .strings.password }}</span>
|
||||
<input type="password" class="field input ~neutral @high" placeholder="{{ .strings.password }}" id="matrix-password">
|
||||
</label>
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge @low full-width center supra submit">{{ .strings.submit }}</span>
|
||||
@@ -726,7 +735,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab-accounts" class="flex flex-col gap-4 unfocused">
|
||||
<div class="card @low dark:~d_neutral accounts mb-4 overflow-visible flex flex-col gap-2">
|
||||
<div class="card @low dark:~d_neutral accounts overflow-visible flex flex-col gap-2">
|
||||
<div id="accounts-filter-dropdown" class="dropdown manual z-10 w-full">
|
||||
<div class="flex flex-col md:flex-row align-middle gap-2">
|
||||
<div class="flex flex-row gap-4 align-middle justify-between md:justify-normal">
|
||||
@@ -747,7 +756,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-display max-w-full">
|
||||
<div class="card ~neutral @low mt-2 overflow-x-scroll" id="accounts-filter-list">
|
||||
<div class="card ~neutral @low overflow-x-scroll" id="accounts-filter-list">
|
||||
<p class="supra pb-2">{{ .strings.filters }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -765,11 +774,11 @@
|
||||
<button class="button ~neutral @low center accounts-load-all">{{ .strings.loadAll }}</button>
|
||||
<span class="button ~neutral @low center " id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
||||
<div id="accounts-announce-dropdown" class="dropdown pb-0i " tabindex="0">
|
||||
<span class="w-full button ~info @low center items-baseline" id="accounts-announce">{{ .strings.announce }}</span>
|
||||
<span class="w-full button ~info @low center items-baseline flex flex-row gap-2" id="accounts-announce">{{ .strings.announce }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="supra sm">{{ .strings.templates }}</span>
|
||||
<div id="accounts-announce-templates"></div>
|
||||
<div id="accounts-announce-templates" class="flex flex-col gap-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -780,9 +789,9 @@
|
||||
<div id="accounts-expiry-dropdown" class="dropdown pb-0i " tabindex="0">
|
||||
<span class="w-full button ~positive @low center items-baseline flex flex-row gap-2" id="accounts-expiry-dropdown-button">{{ .strings.expiry }}<i class="ri-arrow-down-s-line"></i></span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<div class="card ~neutral @low flex flex-col gap-2">
|
||||
<span class="button ~warning full-width @low center" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
||||
<span class="button ~critical full-width @low center mt-2" id="accounts-remove-expiry">{{ .strings.removeExpiry }}</span>
|
||||
<span class="button ~critical full-width @low center" id="accounts-remove-expiry">{{ .strings.removeExpiry }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -850,7 +859,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab-activity" class="flex flex-col gap-4 unfocused">
|
||||
<div class="card @low dark:~d_neutral activity mb-4 overflow-visible flex flex-col gap-2">
|
||||
<div class="card @low dark:~d_neutral activity overflow-visible flex flex-col gap-2">
|
||||
<div id="activity-filter-dropdown" class="dropdown manual z-10 w-full" tabindex="0">
|
||||
<div class="flex flex-col md:flex-row align-middle gap-2">
|
||||
<div class="flex flex-row gap-4 align-middle justify-between md:justify-normal">
|
||||
@@ -874,7 +883,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-display max-w-full">
|
||||
<div class="card ~neutral @low mt-2 overflow-x-scroll" id="activity-filter-list">
|
||||
<div class="card ~neutral @low overflow-x-scroll" id="activity-filter-list">
|
||||
<p class="supra pb-2">{{ .strings.filters }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -899,7 +908,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="activity-card-list"></div>
|
||||
<div id="activity-card-list" class="flex flex-col gap-2"></div>
|
||||
<div id="activity-loader"></div>
|
||||
<div class="flex flex-row gap-2 justify-center">
|
||||
<button class="button ~neutral @low" id="activity-load-more">{{ .strings.loadMore }}</button>
|
||||
@@ -944,9 +953,9 @@
|
||||
</div>
|
||||
<div class="card ~neutral @low overflow flex-1 grow" id="settings-panel">
|
||||
<div class="settings-section unfocused h-[100%]" id="settings-not-found">
|
||||
<div class="flex flex-col h-[100%] justify-center items-center">
|
||||
<span class="text-2xl font-medium italic mb-2">{{ .strings.noResultsFound }}</span>
|
||||
<span class="mb-2 px-12 text-center">{{ .strings.settingsMaybeUnderAdvanced }}</span>
|
||||
<div class="flex flex-col gap-4 h-[100%] justify-center items-center">
|
||||
<span class="text-2xl font-medium italic">{{ .strings.noResultsFound }}</span>
|
||||
<span class="px-12 text-center">{{ .strings.settingsMaybeUnderAdvanced }}</span>
|
||||
<button class="button ~neutral @low settings-search-clear flex flex-row gap-2">
|
||||
<span>{{ .strings.clearSearch }}</span><i class="ri-close-line"></i>
|
||||
</button>
|
||||
|
||||
@@ -9,34 +9,30 @@
|
||||
<body>
|
||||
<div class="page-container m-2 lg:my-20 lg:mx-64">
|
||||
<div class="card ~critical sectioned">
|
||||
<section class="section ~critical">
|
||||
<section class="section ~critical flex flex-col gap-2">
|
||||
<span class="heading">Crash report for jfa-go</span>
|
||||
{{ if .Err }}
|
||||
<div class="font-mono bg-inherit pre-line mt-4 mb-4">
|
||||
<div class="font-mono bg-inherit pre-line">
|
||||
Error: {{ .Err }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<a class="button ~critical mb-4" target="_blank" href="https://github.com/hrfee/jfa-go/issues/new/choose">Create an Issue</a>
|
||||
<a class="button ~critical w-full center" target="_blank" href="https://github.com/hrfee/jfa-go/issues/new/choose">Create an Issue</a>
|
||||
</section>
|
||||
<section class="section ~neutral @low">
|
||||
<div class="flex flex-row justify-between">
|
||||
<span class="subheading">Full Log</span>
|
||||
<span class="button ~urge ml-4" id="copy-log">Copy</span>
|
||||
<section class="section ~neutral @low flex flex-col gap-4">
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<span class="subheading font-medium">Full Log</span>
|
||||
<span class="button ~urge" id="copy-log">Copy</span>
|
||||
</div>
|
||||
<div class="row mb-4">
|
||||
<label class="col mr-4">
|
||||
<span class="button ~neutral @high supra full-width center" id="button-log-normal">Normal</span>
|
||||
</label>
|
||||
<label class="col mr-4">
|
||||
<span class="button ~neutral @low supra full-width center" id="button-log-sanitized">Sanitized</span>
|
||||
</label>
|
||||
<div class="flex flex-row gap-2 justify-between">
|
||||
<button class="button ~neutral @high supra w-full center" id="button-log-normal">Normal</button>
|
||||
<button class="button ~neutral @low supra w-full center" id="button-log-sanitized">Sanitized</button>
|
||||
</div>
|
||||
<div id="log-normal">
|
||||
<pre class="font-mono bg-inherit pre-line">{{ .Log }}</pre>
|
||||
<pre class="card font-mono bg-inherit pre-line">{{ .Log }}</pre>
|
||||
</div>
|
||||
<div id="log-sanitized" class="unfocused">
|
||||
<p class="subheading">An attempt has been made to remove sensitive info, but make sure to check yourself.</p>
|
||||
<pre class="font-mono bg-inherit pre-line">{{ .SanitizedLog }}</pre>
|
||||
<div id="log-sanitized" class="flex flex-col gap-2 unfocused">
|
||||
<p class="support subheading">An attempt has been made to remove sensitive info, but make sure to check yourself.</p>
|
||||
<pre class="card font-mono bg-inherit pre-line">{{ .SanitizedLog }}</pre>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
</div>
|
||||
<div class="card dark:~d_neutral @low">
|
||||
<div class="flex flex-col md:flex-row gap-3 items-baseline mb-2">
|
||||
<span class="heading mr-5">
|
||||
<span class="heading">
|
||||
{{ if .passwordReset }}
|
||||
{{ .strings.passwordReset }}
|
||||
{{ else }}
|
||||
@@ -82,23 +82,23 @@
|
||||
<span class="button ~info @low full-width center mb-4" id="link-matrix">{{ .strings.linkMatrix }} {{ if .matrixRequired }}({{ .strings.required }}){{ end }}</span>
|
||||
{{ end }}
|
||||
{{ if or (.telegramEnabled) (or .discordEnabled .matrixEnabled) }}
|
||||
<div id="contact-via" class="unfocused">
|
||||
<label class="row switch pb-4 unfocused">
|
||||
<input type="checkbox" name="contact-via" value="email" id="contact-via-email" class="mr-2"><span>Contact through Email</span>
|
||||
<div id="contact-via" class="unfocused flex flex-col gap-2">
|
||||
<label class="flex flex-row gap-2 switch unfocused">
|
||||
<input type="checkbox" name="contact-via" value="email" id="contact-via-email"><span>Contact through Email</span>
|
||||
</label>
|
||||
{{ if .telegramEnabled }}
|
||||
<label class="row switch pb-4 unfocused">
|
||||
<input type="checkbox" name="contact-via" value="telegram" id="contact-via-telegram" class="mr-2"><span>Contact through Telegram</span>
|
||||
<label class="flex flex-row gap-2 switch unfocused">
|
||||
<input type="checkbox" name="contact-via" value="telegram" id="contact-via-telegram"><span>Contact through Telegram</span>
|
||||
</label>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<label class="row switch pb-4 unfocused">
|
||||
<input type="checkbox" name="contact-via" value="discord" id="contact-via-discord" class="mr-2"><span>Contact through Discord</span>
|
||||
<label class="flex flex-row gap-2 switch unfocused">
|
||||
<input type="checkbox" name="contact-via" value="discord" id="contact-via-discord"><span>Contact through Discord</span>
|
||||
</label>
|
||||
{{ end }}
|
||||
{{ if .matrixEnabled }}
|
||||
<label class="row switch pb-4 unfocused">
|
||||
<input type="checkbox" name="contact-via" value="matrix" id="contact-via-matrix" class="mr-2"><span>Contact through Matrix</span>
|
||||
<label class="flex flex-row gap-2 switch unfocused">
|
||||
<input type="checkbox" name="contact-via" value="matrix" id="contact-via-matrix"><span>Contact through Matrix</span>
|
||||
</label>
|
||||
{{ end }}
|
||||
</div>
|
||||
@@ -141,11 +141,19 @@
|
||||
</ul>
|
||||
</div>
|
||||
{{ if .captcha }}
|
||||
<div class="card ~neutral @low mb-4">
|
||||
<span class="label supra mb-2">CAPTCHA {{ if not .reCAPTCHA }}<span id="captcha-regen" title="{{ .strings.refresh }}" class="badge lg @low ~info ml-2 float-right"><i class="ri-refresh-line"></i></span><span id="captcha-success" class="badge lg @low ~critical ml-2 float-right"><i class="ri-close-line"></i></span>{{ end }}</span>
|
||||
<div id="captcha-img" class="mt-2 mb-2 {{ if .reCAPTCHA }}g-recaptcha{{ end }}"></div>
|
||||
<div class="card ~neutral @low mb-4 flex flex-col gap-2">
|
||||
<div class="flex flex-row justify-between gap-2">
|
||||
<span class="label supra">CAPTCHA</span>
|
||||
{{ if not .reCAPTCHA }}
|
||||
<div class="flex flex-row gap-2">
|
||||
<button id="captcha-regen" aria-label="{{ .strings.refresh }}" title="{{ .strings.refresh }}" class="badge lg @low ~info"><i class="ri-refresh-line"></i></button>
|
||||
<span id="captcha-success" class="badge lg @low ~critical"><i class="ri-close-line"></i></span>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div id="captcha-img" class="{{ if .reCAPTCHA }}g-recaptcha{{ end }}"></div>
|
||||
{{ if not .reCAPTCHA }}
|
||||
<input class="field ~neutral @low" id="captcha-input" class="mt-2" placeholder="CAPTCHA">
|
||||
<input class="field ~neutral @low" id="captcha-input" placeholder="CAPTCHA">
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<span class="dropdown z-[11]" tabindex="0" id="lang-dropdown">
|
||||
<span class="button ~urge dropdown-button">
|
||||
<i class="ri-global-line"></i>
|
||||
<span class="ml-2 chev"></span>
|
||||
<span class="button ~urge dropdown-button flex flex-row gap-2 h-full" title="{{ .strings.language }}" aria-label="{{ .strings.language }}">
|
||||
<i class="icon ri-global-line"></i>
|
||||
<i class="icon ri-arrow-down-s-line"></i>
|
||||
</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low flex flex-col gap-2">
|
||||
@@ -13,7 +13,7 @@
|
||||
<input type="radio" name="lang-time" id="lang-24h">
|
||||
<span>{{ .strings.time24h }}</span>
|
||||
</label>
|
||||
<div id="lang-list"></div>
|
||||
<div id="lang-list" class="flex flex-col gap-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
{{ $hasTwoCards = 1 }}
|
||||
<div class="card mx-2 flex-initial w-full lg:w-[35%] mb-4 lg:mb-0 dark:~d_neutral @low content">
|
||||
<span class="heading row">{{ .strings.loginNotAdmin }}</span>
|
||||
<a class="button ~info h-12 w-full" href="{{ .pages.Base }}{{ .pages.MyAccount }}"><i class="ri-account-circle-fill mr-2"></i>{{ .strings.myAccount }}</a>
|
||||
<a class="button ~info h-12 w-full flex flex-row gap-2" href="{{ .pages.Base }}{{ .pages.MyAccount }}"><i class="ri-account-circle-fill"></i>{{ .strings.myAccount }}</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</head>
|
||||
<body class="max-w-full overflow-x-hidden section">
|
||||
<div id="notification-box"></div>
|
||||
<div class="page-container m-2 lg:my-20 lg:mx-64 flex flex-col gap-4 items-center">
|
||||
<div class="page-container m-2 lg:my-20 lg:mx-64 flex flex-col gap-4">
|
||||
<div class="top-2 inset-x-2 lg:absolute flex flex-row justify-between">
|
||||
<div class="flex flex-row gap-2">
|
||||
{{ template "lang-select.html" . }}
|
||||
@@ -322,10 +322,10 @@
|
||||
</label>
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="label flex flex-col gap-2">
|
||||
<div class="switch"><input type="radio" class="mr-2" name="email-24h" value="true" checked><span>{{ .lang.Strings.time24h }}</span></div>
|
||||
<div class="switch flex flex-row gap-2"><input type="radio" name="email-24h" value="true" checked><span>{{ .lang.Strings.time24h }}</span></div>
|
||||
</label>
|
||||
<label class="label flex flex-col gap-2">
|
||||
<div class="switch"><input type="radio" class="mr-2" name="email-24h" value="false"><span>{{ .lang.Strings.time12h }}</span></div>
|
||||
<div class="switch flex flex-row gap-2"><input type="radio" name="email-24h" value="false"><span>{{ .lang.Strings.time12h }}</span></div>
|
||||
</label>
|
||||
</div>
|
||||
<div id="email-sect" class="flex flex-row gap-2 justify-between">
|
||||
|
||||
102
html/user.html
102
html/user.html
@@ -23,46 +23,44 @@
|
||||
<body class="max-w-full overflow-x-hidden section">
|
||||
<div id="modal-email" class="modal">
|
||||
<div class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3">
|
||||
<div class="content">
|
||||
<span class="heading mb-4 my-2"></span>
|
||||
<label class="label supra row m-1" for="modal-email-input">{{ .strings.emailAddress }}</label>
|
||||
<div class="row">
|
||||
<input type="email" class="col sm field ~neutral @low input" id="modal-email-input" placeholder="{{ .strings.emailAddress }}">
|
||||
</div>
|
||||
<button class="button ~urge @low supra full-width center lg my-2 modal-submit">{{ .strings.submit }}</button>
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="heading"></span>
|
||||
<label class="label flex flex-col gap-2">
|
||||
<span class="supra">{{ .strings.emailAddress }}</span>
|
||||
<input type="email" class="field ~neutral @low input" id="modal-email-input" placeholder="{{ .strings.emailAddress }}">
|
||||
</label>
|
||||
<button class="button ~urge @low supra full-width center lg modal-submit">{{ .strings.submit }}</button>
|
||||
</div>
|
||||
<div class="confirmation-required unfocused">
|
||||
<span class="heading mb-4">{{ .strings.confirmationRequired }} <span class="modal-close">×</span></span>
|
||||
<p class="content mb-4">{{ .strings.confirmationRequiredMessage }}</p>
|
||||
<div class="confirmation-required unfocused flex flex-col gap-2">
|
||||
<span class="heading">{{ .strings.confirmationRequired }} <span class="modal-close">×</span></span>
|
||||
<p class="content">{{ .strings.confirmationRequiredMessage }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ if .pwrEnabled }}
|
||||
<div id="modal-pwr" class="modal">
|
||||
<div class="card content relative mx-auto my-[10%] w-4/5 lg:w-1/3 ~neutral @low">
|
||||
<div class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3 ~neutral @low flex flex-col gap-2">
|
||||
<span class="heading">{{ .strings.resetPassword }}</span>
|
||||
<p class="content my-2">
|
||||
{{ if .linkResetEnabled }}
|
||||
{{ .strings.resetPasswordThroughLinkStart }}
|
||||
<ul class="content">
|
||||
{{ if .resetPasswordUsername }}<li>{{ .strings.resetPasswordUsername }}</li>{{ end }}
|
||||
{{ if .resetPasswordEmail }}<li>{{ .strings.resetPasswordEmail }}</li>{{ end }}
|
||||
{{ if .resetPasswordContactMethod }}<li>{{ .strings.resetPasswordContactMethod }}</li>{{ end }}
|
||||
</ul>
|
||||
{{ .strings.resetPasswordThroughLinkEnd }}
|
||||
{{ else }}
|
||||
{{ .strings.resetPasswordThroughJellyfin }}
|
||||
{{ end }}
|
||||
</p>
|
||||
<div class="row">
|
||||
<input type="text" class="col sm field ~neutral @low input" id="pwr-address" placeholder="username | example@example.com | user#1234 | @user:host | @username">
|
||||
<div class="content">
|
||||
{{ if .linkResetEnabled }}
|
||||
<p>{{ .strings.resetPasswordThroughLinkStart }}</p>
|
||||
<ul class="content">
|
||||
{{ if .resetPasswordUsername }}<li>{{ .strings.resetPasswordUsername }}</li>{{ end }}
|
||||
{{ if .resetPasswordEmail }}<li>{{ .strings.resetPasswordEmail }}</li>{{ end }}
|
||||
{{ if .resetPasswordContactMethod }}<li>{{ .strings.resetPasswordContactMethod }}</li>{{ end }}
|
||||
</ul>
|
||||
<p>{{ .strings.resetPasswordThroughLinkEnd }}</p>
|
||||
{{ else }}
|
||||
<p>{{ .strings.resetPasswordThroughJellyfin }}</p>
|
||||
{{ end }}
|
||||
</div>
|
||||
<input type="text" class="col sm field ~neutral @low input" id="pwr-address" placeholder="username | example@example.com | user#1234 | @user:host | @username">
|
||||
{{ if .linkResetEnabled }}
|
||||
<span class="button ~info @low full-width center mt-4" id="pwr-submit">
|
||||
<span class="button ~info @low full-width center" id="pwr-submit">
|
||||
{{ .strings.submit }}
|
||||
</span>
|
||||
{{ else }}
|
||||
<a class="button ~info @low full-width center mt-4" href="{{ .jfLink }}" target="_blank">{{ .strings.continue }}</a>
|
||||
<a class="button ~info @low full-width center" href="{{ .jfLink }}" target="_blank">{{ .strings.continue }}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,12 +73,12 @@
|
||||
<div class="flex flex-row gap-2">
|
||||
{{ template "lang-select.html" . }}
|
||||
<span class="button ~warning h-min" alt="{{ .strings.theme }}" id="button-theme"><i class="ri-sun-line"></i></span>
|
||||
<span class="button ~critical @low mb-4 unfocused" id="logout-button">{{ .strings.logout }}</span>
|
||||
<span class="button ~critical @low unfocused" id="logout-button">{{ .strings.logout }}</span>
|
||||
</div>
|
||||
<a class="button ~info unfocused h-min" href="/" id="admin-back-button"><i class="ri-arrow-left-fill mr-2"></i>{{ .strings.admin }}</a>
|
||||
<a class="button ~info unfocused h-min flex flex-row gap-2" href="/" id="admin-back-button"><i class="ri-arrow-left-fill"></i>{{ .strings.admin }}</a>
|
||||
</div>
|
||||
<div class="card @low dark:~d_neutral mb-4" id="card-user">
|
||||
<span class="heading mb-2"></span>
|
||||
<div class="card @low dark:~d_neutral" id="card-user">
|
||||
<span class="heading flex flex-row gap-4"></span>
|
||||
</div>
|
||||
<div class="columns-1 sm:columns-2 gap-4" id="user-cardlist">
|
||||
{{ if index . "PageMessageEnabled" }}
|
||||
@@ -90,15 +88,15 @@
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<div class="card @low dark:~d_neutral flex-col" id="card-contact">
|
||||
<span class="heading mb-2">{{ .strings.contactMethods }}</span>
|
||||
<div class="card @low dark:~d_neutral flex flex-col gap-2" id="card-contact">
|
||||
<span class="heading">{{ .strings.contactMethods }}</span>
|
||||
<div class="content flex justify-between flex-col h-100"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="card @low dark:~d_neutral content" id="card-password">
|
||||
<span class="heading row mb-2">{{ .strings.changePassword }}</span>
|
||||
<div class="">
|
||||
<div class="my-2">
|
||||
<div class="card @low dark:~d_neutral flex flex-col gap-2" id="card-password">
|
||||
<span class="heading">{{ .strings.changePassword }}</span>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="content">
|
||||
<span class="label supra row">{{ .strings.passwordRequirementsHeader }}</span>
|
||||
<ul>
|
||||
{{ range $key, $value := .requirements }}
|
||||
@@ -108,15 +106,15 @@
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="my-2">
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="label supra" for="user-old-password">{{ .strings.oldPassword }}</label>
|
||||
<input type="password" class="input ~neutral @low mt-2 mb-4" placeholder="{{ .strings.password }}" id="user-old-password" aria-label="{{ .strings.oldPassword }}">
|
||||
<input type="password" class="input ~neutral @low" placeholder="{{ .strings.password }}" id="user-old-password" aria-label="{{ .strings.oldPassword }}">
|
||||
<label class="label supra" for="user-new-password">{{ .strings.newPassword }}</label>
|
||||
<input type="password" class="input ~neutral @low mt-2 mb-4" placeholder="{{ .strings.password }}" id="user-new-password" aria-label="{{ .strings.newPassword }}">
|
||||
<input type="password" class="input ~neutral @low" placeholder="{{ .strings.password }}" id="user-new-password" aria-label="{{ .strings.newPassword }}">
|
||||
|
||||
<label class="label supra" for="user-reenter-password">{{ .strings.reEnterPassword }}</label>
|
||||
<input type="password" class="input ~neutral @low mt-2 mb-4" placeholder="{{ .strings.password }}" id="user-reenter-new-password" aria-label="{{ .strings.reEnterPassword }}">
|
||||
<span class="button ~info @low full-width center mt-4" id="user-password-submit">
|
||||
<input type="password" class="input ~neutral @low" placeholder="{{ .strings.password }}" id="user-reenter-new-password" aria-label="{{ .strings.reEnterPassword }}">
|
||||
<span class="button ~info @low full-width center" id="user-password-submit">
|
||||
{{ .strings.changePassword }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -124,21 +122,21 @@
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="card @low dark:~d_neutral unfocused" id="card-status">
|
||||
<span class="heading mb-2">{{ .strings.expiry }}</span>
|
||||
<aside class="aside ~warning user-expiry my-4"></aside>
|
||||
<div class="card @low dark:~d_neutral unfocused flex flex-col gap-2" id="card-status">
|
||||
<span class="heading">{{ .strings.expiry }}</span>
|
||||
<aside class="aside ~warning user-expiry"></aside>
|
||||
<div class="user-expiry-countdown"></div>
|
||||
</div>
|
||||
</div>
|
||||
{{ if .referralsEnabled }}
|
||||
<div>
|
||||
<div class="card @low dark:~d_neutral unfocused" id="card-referrals">
|
||||
<span class="heading mb-2">{{ .strings.referrals }}</span>
|
||||
<aside class="aside ~neutral my-4 col user-referrals-description"></aside>
|
||||
<div class="card @low dark:~d_neutral unfocused flex flex-col gap-2" id="card-referrals">
|
||||
<span class="heading">{{ .strings.referrals }}</span>
|
||||
<aside class="aside ~neutral col user-referrals-description"></aside>
|
||||
<div class="flex flex-row justify-between gap-2">
|
||||
<div class="user-referrals-info"></div>
|
||||
<div class="grid my-2">
|
||||
<button type="button" class="user-referrals-button button ~info dark:~d_info @low" title="Copy">{{ .strings.copyReferral }}<i class="ri-file-copy-line ml-2"></i></button>
|
||||
<div class="user-referrals-info flex flex-col gap-2"></div>
|
||||
<div class="grid">
|
||||
<button type="button" class="user-referrals-button button ~info dark:~d_info @low flex flex-row gap-2" title="Copy">{{ .strings.copyReferral }}<i class="ri-file-copy-line"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"name": "English (US)"
|
||||
},
|
||||
"strings": {
|
||||
"language": "Language",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"emailAddress": "Email Address",
|
||||
|
||||
2
setup.go
2
setup.go
@@ -40,7 +40,7 @@ func (app *appContext) ServeSetup(gc *gin.Context) {
|
||||
return
|
||||
}
|
||||
pages := PagePathsDTO{PagePaths: PAGES}
|
||||
gc.HTML(200, "setup.html", gin.H{
|
||||
app.gcHTML(gc, 200, "setup.html", SetupPage, lang, gin.H{
|
||||
"cssVersion": cssVersion,
|
||||
"pages": pages,
|
||||
"lang": app.storage.lang.Setup[lang],
|
||||
|
||||
@@ -34,5 +34,11 @@ copyButton.onclick = () => {
|
||||
toClipboard("```\n" + logSanitized.textContent + "```");
|
||||
}
|
||||
copyButton.textContent = "Copied.";
|
||||
setTimeout(() => { copyButton.textContent = "Copy"; }, 1500);
|
||||
copyButton.classList.add("~positive");
|
||||
copyButton.classList.remove("~urge");
|
||||
setTimeout(() => {
|
||||
copyButton.textContent = "Copy";
|
||||
copyButton.classList.add("~urge");
|
||||
copyButton.classList.remove("~positive");
|
||||
}, 1500);
|
||||
};
|
||||
|
||||
@@ -266,7 +266,7 @@ interface sendDTO {
|
||||
|
||||
if (window.captcha && !window.reCAPTCHA) {
|
||||
captcha.generate();
|
||||
(document.getElementById("captcha-regen") as HTMLSpanElement).onclick = captcha.generate;
|
||||
(document.getElementById("captcha-regen") as HTMLButtonElement).onclick = captcha.generate;
|
||||
captcha.input.onkeyup = validator.validate;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,10 +150,10 @@ export class Discord extends ServiceLinker {
|
||||
(link.parentElement as HTMLAnchorElement).target = "_blank";
|
||||
let innerHTML = ``;
|
||||
if (inv.icon != "") {
|
||||
innerHTML += `<span class="img-circle lg mr-4"><img class="img-circle" src="${inv.icon}" width="64" height="64"></span>${window.discordServerName}`;
|
||||
innerHTML += `<span class="img-circle lg"><img class="img-circle" src="${inv.icon}" width="64" height="64"></span>${window.discordServerName}`;
|
||||
} else {
|
||||
innerHTML += `
|
||||
<span class="shield mr-4 bg-discord"><i class="ri-discord-fill ri-xl text-white"></i></span>${window.discordServerName}
|
||||
<span class="shield bg-discord"><i class="ri-discord-fill ri-xl text-white"></i></span>${window.discordServerName}
|
||||
`;
|
||||
}
|
||||
link.innerHTML = innerHTML;
|
||||
|
||||
@@ -313,44 +313,44 @@ class user implements User, SearchableItem {
|
||||
const email = this._emailAddress != "";
|
||||
if (!telegram && !discord && !matrix && !email) return;
|
||||
let innerHTML = `
|
||||
<i class="icon ri-settings-2-line ml-2 dropdown-button"></i>
|
||||
<i class="icon ri-settings-2-line dropdown-button"></i>
|
||||
<div class="dropdown manual over-top">
|
||||
<div class="dropdown-display lg">
|
||||
<div class="card ~neutral @low">
|
||||
<div class="supra sm mb-2">${window.lang.strings("contactThrough")}</div>
|
||||
<div class="card ~neutral @low flex flex-col gap-2">
|
||||
<div class="supra sm">${window.lang.strings("contactThrough")}</div>
|
||||
<div class="accounts-area-email">
|
||||
<label class="row switch pb-2">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-email mr-2">
|
||||
<label class="row switch flex flex-row gap-2">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-email">
|
||||
</span>Email</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="accounts-area-telegram">
|
||||
<label class="row switch pb-2">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-telegram mr-2">
|
||||
<label class="row switch flex flex-row gap-2">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-telegram">
|
||||
<span>Telegram</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="accounts-area-discord">
|
||||
<label class="row switch pb-2">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-discord mr-2">
|
||||
<label class="row switch flex flex-row gap-2">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-discord">
|
||||
<span>Discord</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="accounts-area-matrix">
|
||||
<label class="row switch pb-2">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-matrix mr-2">
|
||||
<label class="row switch flex flex-row gap-2">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-matrix">
|
||||
<span>Matrix</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="supra sm mb-2 accounts-unlink-header">${window.lang.strings("unlink")}:</div>
|
||||
<div class="supra sm accounts-unlink-header">${window.lang.strings("unlink")}:</div>
|
||||
<div class="accounts-unlink-telegram">
|
||||
<button class="button ~critical mb-2 w-full">Telegram</button>
|
||||
<button class="button ~critical w-full">Telegram</button>
|
||||
</div>
|
||||
<div class="accounts-unlink-discord">
|
||||
<button class="button ~critical mb-2 w-full">Discord</button>
|
||||
<button class="button ~critical w-full">Discord</button>
|
||||
</div>
|
||||
<div class="accounts-unlink-matrix">
|
||||
<button class="button ~critical mb-2 w-full">Matrix</button>
|
||||
<button class="button ~critical w-full">Matrix</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -404,12 +404,12 @@ class user implements User, SearchableItem {
|
||||
this._notifyDropdown.querySelector(".accounts-area-matrix").classList.remove("unfocused");
|
||||
this._notifyDropdown.querySelector(".accounts-unlink-matrix").classList.remove("unfocused");
|
||||
this._matrix.innerHTML = `
|
||||
<div class="table-inline">
|
||||
<div class="accounts-settings-area flex flex-row gap-2 justify-center">
|
||||
${u}
|
||||
</div>
|
||||
`;
|
||||
if (lastNotifyMethod) {
|
||||
(this._matrix.querySelector(".table-inline") as HTMLDivElement).appendChild(this._notifyDropdown);
|
||||
(this._matrix.querySelector(".accounts-settings-area") as HTMLDivElement).appendChild(this._notifyDropdown);
|
||||
}
|
||||
}
|
||||
this._checkUnlinkArea();
|
||||
@@ -475,12 +475,12 @@ class user implements User, SearchableItem {
|
||||
this._notifyDropdown.querySelector(".accounts-area-telegram").classList.remove("unfocused");
|
||||
this._notifyDropdown.querySelector(".accounts-unlink-telegram").classList.remove("unfocused");
|
||||
this._telegram.innerHTML = `
|
||||
<div class="table-inline">
|
||||
<div class="accounts-settings-area flex flex-row gap-2 justify-center">
|
||||
<a href="https://t.me/${u}" target="_blank">@${u}</a>
|
||||
</div>
|
||||
`;
|
||||
if (lastNotifyMethod) {
|
||||
(this._telegram.querySelector(".table-inline") as HTMLDivElement).appendChild(this._notifyDropdown);
|
||||
(this._telegram.querySelector(".accounts-settings-area") as HTMLDivElement).appendChild(this._notifyDropdown);
|
||||
}
|
||||
}
|
||||
this._checkUnlinkArea();
|
||||
@@ -545,12 +545,12 @@ class user implements User, SearchableItem {
|
||||
this._notifyDropdown.querySelector(".accounts-area-discord").classList.remove("unfocused");
|
||||
this._notifyDropdown.querySelector(".accounts-unlink-discord").classList.remove("unfocused");
|
||||
this._discord.innerHTML = `
|
||||
<div class="table-inline">
|
||||
<div class="accounts-settings-area flex flex-row gap-2 justify-center">
|
||||
<a href="https://discord.com/users/${this._discordID}" class="discord-link" target="_blank">${u}</a>
|
||||
</div>
|
||||
`;
|
||||
if (lastNotifyMethod) {
|
||||
(this._discord.querySelector(".table-inline") as HTMLDivElement).appendChild(this._notifyDropdown);
|
||||
(this._discord.querySelector(".accounts-settings-area") as HTMLDivElement).appendChild(this._notifyDropdown);
|
||||
}
|
||||
}
|
||||
this._checkUnlinkArea();
|
||||
@@ -1647,15 +1647,15 @@ export class accountsList extends PaginatedList {
|
||||
return;
|
||||
}
|
||||
if (list.length > 0) {
|
||||
this._announceButton.innerHTML = `${window.lang.strings("announce")} <i class="ml-2 ri-arrow-drop-down-line"></i>`;
|
||||
this._announceButton.innerHTML = `${window.lang.strings("announce")} <i class="ri-arrow-drop-down-line"></i>`;
|
||||
}
|
||||
const dList = document.getElementById("accounts-announce-templates") as HTMLDivElement;
|
||||
dList.textContent = '';
|
||||
for (let name of list) {
|
||||
const el = document.createElement("div") as HTMLDivElement;
|
||||
el.classList.add("flex", "flex-row", "justify-between", "truncate", "mt-2");
|
||||
el.classList.add("flex", "flex-row", "gap-2", "justify-between", "truncate");
|
||||
el.innerHTML = `
|
||||
<span class="button ~neutral sm full-width accounts-announce-template-button">${name}</span><span class="button ~critical fr ml-4 accounts-announce-template-delete">×</span>
|
||||
<span class="button ~neutral sm full-width accounts-announce-template-button">${name}</span><span class="button ~critical accounts-announce-template-delete">×</span>
|
||||
`;
|
||||
let urlSafeName = encodeURIComponent(encodeURIComponent(name));
|
||||
(el.querySelector("span.accounts-announce-template-button") as HTMLSpanElement).onclick = () => {
|
||||
|
||||
@@ -244,6 +244,8 @@ export class Activity implements activity, SearchableItem {
|
||||
else this._card.classList.remove(moodColours[i]);
|
||||
} */
|
||||
|
||||
// lazy late addition, hide then unhide if needed
|
||||
this._expiryTypeBadge.classList.add("unfocused");
|
||||
if (this.type == "changePassword" || this.type == "resetPassword") {
|
||||
let innerHTML = ``;
|
||||
if (this.type == "changePassword") innerHTML = window.lang.strings("accountChangedPassword");
|
||||
@@ -265,13 +267,16 @@ export class Activity implements activity, SearchableItem {
|
||||
} else if (this.type == "creation") {
|
||||
this._title.innerHTML = window.lang.strings("accountCreated").replace("{user}", this._genUserLink());
|
||||
if (this.source_type == "user") {
|
||||
this._referrer.innerHTML = `<span class="supra mr-2">${window.lang.strings("referrer")}</span>${this._genSrcUserLink()}`;
|
||||
this._referrer.classList.remove("unfocused");
|
||||
this._referrer.innerHTML = `<span class="supra">${window.lang.strings("referrer")}</span>${this._genSrcUserLink()}`;
|
||||
} else {
|
||||
this._referrer.classList.add("unfocused");
|
||||
this._referrer.textContent = ``;
|
||||
}
|
||||
} else if (this.type == "deletion") {
|
||||
if (this.source_type == "daemon") {
|
||||
this._title.innerHTML = window.lang.strings("accountExpired").replace("{user}", this._genUserText());
|
||||
this._expiryTypeBadge.classList.remove("unfocused");
|
||||
this._expiryTypeBadge.classList.add("~critical");
|
||||
this._expiryTypeBadge.classList.remove("~info");
|
||||
this._expiryTypeBadge.textContent = window.lang.strings("deleted");
|
||||
@@ -283,6 +288,7 @@ export class Activity implements activity, SearchableItem {
|
||||
} else if (this.type == "disabled") {
|
||||
if (this.source_type == "daemon") {
|
||||
this._title.innerHTML = window.lang.strings("accountExpired").replace("{user}", this._genUserLink());
|
||||
this._expiryTypeBadge.classList.remove("unfocused");
|
||||
this._expiryTypeBadge.classList.add("~info");
|
||||
this._expiryTypeBadge.classList.remove("~critical");
|
||||
this._expiryTypeBadge.textContent = window.lang.strings("disabled");
|
||||
@@ -327,8 +333,10 @@ export class Activity implements activity, SearchableItem {
|
||||
set ip(v: string) {
|
||||
this._act.ip = v;
|
||||
if (v) {
|
||||
this._ip.innerHTML = `<span class="supra mr-2">IP</span><span class="font-mono bg-inherit">${v}</span>`;
|
||||
this._ip.classList.remove("unfocused");
|
||||
this._ip.innerHTML = `<span class="supra">IP</span><span class="font-mono bg-inherit">${v}</span>`;
|
||||
} else {
|
||||
this._ip.classList.add("unfocused");
|
||||
this._ip.textContent = ``;
|
||||
}
|
||||
}
|
||||
@@ -382,23 +390,23 @@ export class Activity implements activity, SearchableItem {
|
||||
constructor(act: activity) {
|
||||
this._card = document.createElement("div");
|
||||
|
||||
this._card.classList.add("card", "@low", "my-2");
|
||||
this._card.classList.add("card", "@low", "flex", "flex-col", "gap-2");
|
||||
|
||||
this._card.innerHTML = `
|
||||
<div class="flex flex-col md:flex-row justify-between mb-2">
|
||||
<div class="flex flex-row flex-wrap justify-between items-start gap-1">
|
||||
<span class="heading truncate flex-initial md:text-2xl text-xl activity-title"></span>
|
||||
<div class="flex flex-col flex-none ml-0 md:ml-2">
|
||||
<div class="flex flex-row flex-wrap gap-2">
|
||||
<span class="activity-expiry-type badge self-stretch"></span>
|
||||
<span class="font-medium md:text-sm text-xs activity-time" aria-label="${window.lang.strings("date")}"></span>
|
||||
<span class="activity-expiry-type badge self-start md:self-end mt-1"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row justify-between items-end">
|
||||
<div class="flex flex-col md:flex-row gap-2">
|
||||
<div>
|
||||
<span class="content supra mr-2 activity-source-type"></span><span class="activity-source"></span>
|
||||
<div class="flex flex-row justify-between items-baseline">
|
||||
<div class="flex flex-col md:flex-row gap-1 items-baseline">
|
||||
<div class="flex flex-row gap-2 items-baseline">
|
||||
<span class="supra activity-source-type"></span><span class="activity-source"></span>
|
||||
</div>
|
||||
<span class="content activity-referrer"></span>
|
||||
<span class="content activity-ip"></span>
|
||||
<span class="activity-referrer flex flex-row gap-2 items-baseline"></span>
|
||||
<span class="activity-ip flex flex-row gap-2 items-baseline"></span>
|
||||
</div>
|
||||
<div>
|
||||
<button class="button @low hover:~critical rounded-full px-1 py-px activity-delete" aria-label="${window.lang.strings("delete")}"><i class="ri-close-line"></i></button>
|
||||
@@ -583,7 +591,7 @@ export class activityList extends PaginatedList {
|
||||
this._ascending = v;
|
||||
// Setting default sort makes sense, since this is the only sort ever being done.
|
||||
this._c.defaultSortAscending = this.ascending;
|
||||
this._sortDirection.innerHTML = `${window.lang.strings("sortDirection")} <i class="ri-arrow-${v ? "up" : "down"}-s-line ml-2"></i>`;
|
||||
this._sortDirection.innerHTML = `${window.lang.strings("sortDirection")} <i class="ri-arrow-${v ? "up" : "down"}-s-line"></i>`;
|
||||
// NOTE: We don't actually re-sort the list here, instead just use setOrdering to apply this.ascending before a reload.
|
||||
this._search.setOrdering(this._search.ordering, this._c.defaultSortField, this.ascending);
|
||||
if (this._hasLoaded) {
|
||||
|
||||
@@ -184,18 +184,24 @@ export class notificationBox implements NotificationBox {
|
||||
private _errorTypes: { [type: string]: boolean } = {};
|
||||
private _positiveTypes: { [type: string]: boolean } = {};
|
||||
timeout: number;
|
||||
constructor(box: HTMLDivElement, timeout?: number) { this._box = box; this.timeout = timeout || 5; }
|
||||
constructor(box: HTMLDivElement, timeout?: number) {
|
||||
this._box = box;
|
||||
this._box.classList.add("flex", "flex-col", "gap-2");
|
||||
this.timeout = timeout || 5;
|
||||
}
|
||||
|
||||
static baseClasses = ["aside", "flex", "flex-row", "justify-between", "gap-4"];
|
||||
|
||||
private _error = (message: string): HTMLElement => {
|
||||
const noti = document.createElement('aside');
|
||||
noti.classList.add("aside", "~critical", "@low", "mt-2", "notification-error");
|
||||
noti.classList.add(...notificationBox.baseClasses, "~critical", "@low", "notification-error");
|
||||
let error = "";
|
||||
if (window.lang) {
|
||||
error = window.lang.strings("error") + ":"
|
||||
}
|
||||
noti.innerHTML = `<strong>${error}</strong> ${message}`;
|
||||
noti.innerHTML = `<div><strong>${error}</strong> ${message}</div>`;
|
||||
const closeButton = document.createElement('span') as HTMLSpanElement;
|
||||
closeButton.classList.add("button", "~critical", "@low", "ml-4");
|
||||
closeButton.classList.add("button", "~critical", "@low");
|
||||
closeButton.innerHTML = `<i class="icon ri-close-line"></i>`;
|
||||
closeButton.onclick = () => this._close(noti);
|
||||
noti.classList.add("animate-slide-in");
|
||||
@@ -205,10 +211,10 @@ export class notificationBox implements NotificationBox {
|
||||
|
||||
private _positive = (bold: string, message: string): HTMLElement => {
|
||||
const noti = document.createElement('aside');
|
||||
noti.classList.add("aside", "~positive", "@low", "mt-2", "notification-positive");
|
||||
noti.innerHTML = `<strong>${bold}</strong> ${message}`;
|
||||
noti.classList.add(...notificationBox.baseClasses, "~positive", "@low", "notification-positive");
|
||||
noti.innerHTML = `<div><strong>${bold}</strong> ${message}</div>`;
|
||||
const closeButton = document.createElement('span') as HTMLSpanElement;
|
||||
closeButton.classList.add("button", "~positive", "@low", "ml-4");
|
||||
closeButton.classList.add("button", "~positive", "@low");
|
||||
closeButton.innerHTML = `<i class="icon ri-close-line"></i>`;
|
||||
closeButton.onclick = () => this._close(noti);
|
||||
noti.classList.add("animate-slide-in");
|
||||
|
||||
@@ -76,13 +76,22 @@ export class PageManager {
|
||||
}
|
||||
|
||||
load(name: string = "") {
|
||||
name = decodeURI(name);
|
||||
if (!this.pages.has(name)) return window.history.pushState(name || this.defaultName, this.defaultTitle, "")
|
||||
const p = this.pages.get(name);
|
||||
this.loadPage(p);
|
||||
}
|
||||
|
||||
loadPage (p: Page) {
|
||||
window.history.pushState(p.name || this.defaultName, p.title, p.url + window.location.search);
|
||||
let url = p.url;
|
||||
// Fix ordering of query params and hash
|
||||
if (url.includes("#")) {
|
||||
let split = url.split("#");
|
||||
url = split[0] + window.location.search + "#" + split[1];
|
||||
} else {
|
||||
url = url + window.location.search;
|
||||
}
|
||||
window.history.pushState(p.name || this.defaultName, p.title, url);
|
||||
}
|
||||
|
||||
prev(name: string = "") {
|
||||
|
||||
@@ -50,10 +50,12 @@ class profile implements Profile {
|
||||
get admin(): boolean { return this._adminChip.classList.contains("chip"); }
|
||||
set admin(state: boolean) {
|
||||
if (state) {
|
||||
this._adminChip.classList.add("chip", "~info", "ml-2");
|
||||
this._adminChip.classList.remove("unfocused");
|
||||
this._adminChip.classList.add("chip", "~info");
|
||||
this._adminChip.textContent = "Admin";
|
||||
} else {
|
||||
this._adminChip.classList.remove("chip", "~info", "ml-2");
|
||||
this._adminChip.classList.add("unfocused");
|
||||
this._adminChip.classList.remove("chip", "~info");
|
||||
this._adminChip.textContent = "";
|
||||
}
|
||||
}
|
||||
@@ -115,7 +117,7 @@ class profile implements Profile {
|
||||
constructor(name: string, p: Profile) {
|
||||
this._row = document.createElement("tr") as HTMLTableRowElement;
|
||||
let innerHTML = `
|
||||
<td><b class="profile-name"></b> <span class="profile-admin"></span></td>
|
||||
<td><div class="flex flex-row items-baseline gap-2"><b class="profile-name"></b> <span class="profile-admin"></span></div></td>
|
||||
<td><input type="radio" name="profile-default"></td>
|
||||
`;
|
||||
if (window.ombiEnabled) innerHTML += `
|
||||
|
||||
@@ -114,9 +114,14 @@ export class BoolQuery extends Query {
|
||||
super(subject, QueryOperator.Equal);
|
||||
this.type = "bool";
|
||||
this._value = value;
|
||||
this._card.classList.add("button", "~" + (this._value ? "positive" : "critical"), "@high", "center");
|
||||
this._card.classList.add("button", "@high", "center", "flex", "flex-row", "gap-2");
|
||||
if (this._value) {
|
||||
this._card.classList.add("~positive");
|
||||
} else {
|
||||
this._card.classList.add("~critical");
|
||||
}
|
||||
this._card.innerHTML = `
|
||||
<span class="font-bold mr-2">${subject.name}</span>
|
||||
<span class="font-bold">${subject.name}</span>
|
||||
<i class="text-2xl ri-${this._value? "checkbox" : "close"}-circle-fill"></i>
|
||||
`;
|
||||
}
|
||||
@@ -156,9 +161,9 @@ export class StringQuery extends Query {
|
||||
super(subject, QueryOperator.Equal);
|
||||
this.type = "string";
|
||||
this._value = value.toLowerCase();
|
||||
this._card.classList.add("button", "~neutral", "@low", "center");
|
||||
this._card.classList.add("button", "~neutral", "@low", "center", "flex", "flex-row", "gap-2");
|
||||
this._card.innerHTML = `
|
||||
<span class="font-bold mr-2">${subject.name}:</span> "${this._value}"
|
||||
<span class="font-bold">${subject.name}:</span> "${this._value}"
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -203,10 +208,10 @@ export class DateQuery extends Query {
|
||||
super(subject, operator);
|
||||
this.type = "date";
|
||||
this._value = value;
|
||||
this._card.classList.add("button", "~neutral", "@low", "center");
|
||||
this._card.classList.add("button", "~neutral", "@low", "center", "flex", "flex-row", "gap-2");
|
||||
let dateText = QueryOperatorToDateText(operator);
|
||||
this._card.innerHTML = `
|
||||
<span class="font-bold mr-2">${subject.name}:</span> ${dateText != "" ? dateText+" " : ""}${value.text}
|
||||
<span class="font-bold">${subject.name}:</span> ${dateText != "" ? dateText+" " : ""}${value.text}
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -575,6 +580,8 @@ export class Search {
|
||||
};
|
||||
|
||||
generateFilterList = () => {
|
||||
const filterListContainer = document.createElement("div");
|
||||
filterListContainer.classList.add("flex", "flex-row", "flex-wrap", "gap-2");
|
||||
// Generate filter buttons
|
||||
for (let queryName of Object.keys(this._c.queries)) {
|
||||
const query = this._c.queries[queryName];
|
||||
@@ -585,9 +592,9 @@ export class Search {
|
||||
}
|
||||
|
||||
const container = document.createElement("span") as HTMLSpanElement;
|
||||
container.classList.add("button", "button-xl", "~neutral", "@low", "mb-1", "mr-2", "align-bottom");
|
||||
container.classList.add("button", "button-xl", "~neutral", "@low", "align-bottom", "flex", "flex-row", "gap-2");
|
||||
container.innerHTML = `
|
||||
<div class="flex flex-col mr-2">
|
||||
<div class="flex flex-col">
|
||||
<span>${query.name}</span>
|
||||
<span class="support">${query.description || ""}</span>
|
||||
</div>
|
||||
@@ -596,13 +603,13 @@ export class Search {
|
||||
const pos = document.createElement("button") as HTMLButtonElement;
|
||||
pos.type = "button";
|
||||
pos.ariaLabel = `Filter by "${query.name}": True`;
|
||||
pos.classList.add("button", "~positive", "ml-2");
|
||||
pos.classList.add("button", "~positive");
|
||||
pos.innerHTML = `<i class="ri-checkbox-circle-fill"></i>`;
|
||||
pos.addEventListener("click", () => this.fillInFilter(queryName, "true"));
|
||||
const neg = document.createElement("button") as HTMLButtonElement;
|
||||
neg.type = "button";
|
||||
neg.ariaLabel = `Filter by "${query.name}": False`;
|
||||
neg.classList.add("button", "~critical", "ml-2");
|
||||
neg.classList.add("button", "~critical");
|
||||
neg.innerHTML = `<i class="ri-close-circle-fill"></i>`;
|
||||
neg.addEventListener("click", () => this.fillInFilter(queryName, "false"));
|
||||
|
||||
@@ -612,8 +619,8 @@ export class Search {
|
||||
if (query.string) {
|
||||
const button = document.createElement("button") as HTMLButtonElement;
|
||||
button.type = "button";
|
||||
button.classList.add("button", "~urge", "ml-2");
|
||||
button.innerHTML = `<i class="ri-equal-line mr-2"></i>${window.lang.strings("matchText")}`;
|
||||
button.classList.add("button", "~urge", "flex", "flex-row", "gap-2");
|
||||
button.innerHTML = `<i class="ri-equal-line"></i>${window.lang.strings("matchText")}`;
|
||||
|
||||
// Position cursor between quotes
|
||||
button.addEventListener("click", () => this.fillInFilter(queryName, `""`, -1));
|
||||
@@ -623,20 +630,20 @@ export class Search {
|
||||
if (query.date) {
|
||||
const onDate = document.createElement("button") as HTMLButtonElement;
|
||||
onDate.type = "button";
|
||||
onDate.classList.add("button", "~urge", "ml-2");
|
||||
onDate.innerHTML = `<i class="ri-calendar-check-line mr-2"></i>On Date`;
|
||||
onDate.classList.add("button", "~urge", "flex", "flex-row", "gap-2");
|
||||
onDate.innerHTML = `<i class="ri-calendar-check-line"></i>On Date`;
|
||||
onDate.addEventListener("click", () => this.fillInFilter(queryName, `"="`, -1));
|
||||
|
||||
const beforeDate = document.createElement("button") as HTMLButtonElement;
|
||||
beforeDate.type = "button";
|
||||
beforeDate.classList.add("button", "~urge", "ml-2");
|
||||
beforeDate.innerHTML = `<i class="ri-calendar-check-line mr-2"></i>Before Date`;
|
||||
beforeDate.classList.add("button", "~urge", "flex", "flex-row", "gap-2");
|
||||
beforeDate.innerHTML = `<i class="ri-calendar-check-line"></i>Before Date`;
|
||||
beforeDate.addEventListener("click", () => this.fillInFilter(queryName, `"<"`, -1));
|
||||
|
||||
const afterDate = document.createElement("button") as HTMLButtonElement;
|
||||
afterDate.type = "button";
|
||||
afterDate.classList.add("button", "~urge", "ml-2");
|
||||
afterDate.innerHTML = `<i class="ri-calendar-check-line mr-2"></i>After Date`;
|
||||
afterDate.classList.add("button", "~urge", "flex", "flex-row", "gap-2");
|
||||
afterDate.innerHTML = `<i class="ri-calendar-check-line"></i>After Date`;
|
||||
afterDate.addEventListener("click", () => this.fillInFilter(queryName, `">"`, -1));
|
||||
|
||||
container.appendChild(onDate);
|
||||
@@ -644,8 +651,9 @@ export class Search {
|
||||
container.appendChild(afterDate);
|
||||
}
|
||||
|
||||
this._c.filterList.appendChild(container);
|
||||
filterListContainer.appendChild(container);
|
||||
}
|
||||
this._c.filterList.appendChild(filterListContainer)
|
||||
}
|
||||
|
||||
onServerSearch = () => {
|
||||
|
||||
@@ -345,7 +345,7 @@ class DOMList extends DOMSetting implements SList {
|
||||
container.classList.add("flex", "flex-row", "justify-between");
|
||||
container.innerHTML = `
|
||||
<input type="text" class="input ~neutral @low">
|
||||
<button class="button ~neutral @low center -ml-10 rounded-s-none aria-label="${window.lang.strings("delete")}" title="${window.lang.strings("delete")}">
|
||||
<button class="button ~neutral @low center inside-input rounded-s-none aria-label="${window.lang.strings("delete")}" title="${window.lang.strings("delete")}">
|
||||
<i class="ri-close-line"></i>
|
||||
</button>
|
||||
`;
|
||||
@@ -536,6 +536,7 @@ class groupButton extends groupableItem {
|
||||
private _indent: number;
|
||||
private _parentSidebar: HTMLElement;
|
||||
|
||||
// one of the few sanctioned uses of ml/mr. Looks worse with ms/me.
|
||||
private static readonly _margin = "ml-6";
|
||||
private _indentClasses = ["h-11", "h-10", "h-9"];
|
||||
private _indentClass = () => {
|
||||
@@ -1087,7 +1088,7 @@ export class settingsList {
|
||||
|
||||
setBackupSort = (ascending: boolean) => {
|
||||
this._backupSortAscending = ascending;
|
||||
this._backupSortDirection.innerHTML = `${window.lang.strings("sortDirection")} <i class="${ascending ? "ri-arrow-up-s-line" : "ri-arrow-down-s-line"} ml-2"></i>`;
|
||||
this._backupSortDirection.innerHTML = `${window.lang.strings("sortDirection")} <i class="${ascending ? "ri-arrow-up-s-line" : "ri-arrow-down-s-line"}"></i>`;
|
||||
this._getBackups();
|
||||
};
|
||||
|
||||
@@ -1103,8 +1104,8 @@ export class settingsList {
|
||||
location.innerHTML = window.lang.strings("backupCanBeFound").replace("{filepath}", `<span class="text-black dark:text-white font-mono bg-inherit">"`+backupDTO.path+`"</span>`);
|
||||
download.innerHTML = `
|
||||
<i class="ri-download-line"></i>
|
||||
<span class="ml-2">${window.lang.strings("download")}</span>
|
||||
<span class="badge ~info @low ml-2">${backupDTO.size}</span>
|
||||
<span>${window.lang.strings("download")}</span>
|
||||
<span class="badge ~info @low">${backupDTO.size}</span>
|
||||
`;
|
||||
|
||||
download.parentElement.onclick = () => _download("/backups/" + backupDTO.name, backupDTO.name);
|
||||
@@ -1127,9 +1128,9 @@ export class settingsList {
|
||||
<td>${toDateString(new Date(b.date*1000))}</td>
|
||||
<td class="font-mono">${b.commit || "?"}</td>
|
||||
<td><div class="flex flex-row gap-2 items-stretch justify-center">
|
||||
<span class="backup-download button ~positive @low" title="${window.lang.strings("backupDownload")}">
|
||||
<span class="backup-download button ~positive @low flex flex-row gap-2" title="${window.lang.strings("backupDownload")}">
|
||||
<i class="ri-download-line"></i>
|
||||
<span class="badge ~positive @low ml-2">${b.size}</span>
|
||||
<span class="badge ~positive @low">${b.size}</span>
|
||||
</span>
|
||||
<span class="backup-restore button ~critical @low" title="${window.lang.strings("backupRestore")}"><i class="icon ri-restart-line"></i></span>
|
||||
</div></td>
|
||||
@@ -1461,7 +1462,6 @@ export class settingsList {
|
||||
continue;
|
||||
}
|
||||
|
||||
// element.classList.remove("-mx-2", "my-2", "p-2", "aside", "~neutral", "@low");
|
||||
element.classList.add("opacity-50", "pointer-events-none");
|
||||
element.setAttribute("aria-disabled", "true");
|
||||
let matchedSetting = setting.setting.toLowerCase().includes(query) ||
|
||||
@@ -1478,7 +1478,6 @@ export class settingsList {
|
||||
((setting.advanced && this._advanced) ||
|
||||
!(setting.advanced)));
|
||||
if (shouldShow || query == "") {
|
||||
// element.classList.add("-mx-2", "my-2", "p-2", "aside", "~neutral", "@low");
|
||||
element.classList.remove("opacity-50", "pointer-events-none");
|
||||
element.setAttribute("aria-disabled", "false");
|
||||
}
|
||||
|
||||
@@ -568,7 +568,7 @@ const cards = Array.from(document.getElementsByClassName("page-container")[0].qu
|
||||
pages.setPage({
|
||||
name: title,
|
||||
title: titleEl.textContent + " - jfa-go",
|
||||
url: "/#" + title,
|
||||
url: "/" + (!title ? "" : "#") + title,
|
||||
show: () => {
|
||||
cards[i].classList.remove("unfocused");
|
||||
return true;
|
||||
|
||||
63
ts/user.ts
63
ts/user.ts
@@ -1,7 +1,7 @@
|
||||
import { ThemeManager } from "./modules/theme.js";
|
||||
import { lang, LangFile, loadLangSelector } from "./modules/lang.js";
|
||||
import { Modal } from "./modules/modal.js";
|
||||
import { _get, _post, _delete, notificationBox, whichAnimationEvent, toDateString, toggleLoader, addLoader, removeLoader, toClipboard } from "./modules/common.js";
|
||||
import { _get, _post, _delete, notificationBox, whichAnimationEvent, toDateString, addLoader, removeLoader, toClipboard } from "./modules/common.js";
|
||||
import { Login } from "./modules/login.js";
|
||||
import { Discord, Telegram, Matrix, ServiceConfiguration, MatrixConfiguration } from "./modules/account-linking.js";
|
||||
import { Validator, ValidatorConf, ValidatorRespDTO } from "./modules/validator.js";
|
||||
@@ -108,10 +108,10 @@ if (window.pwrEnabled && window.linkResetEnabled) {
|
||||
const submitButton = document.getElementById("pwr-submit");
|
||||
const input = document.getElementById("pwr-address") as HTMLInputElement;
|
||||
submitButton.onclick = () => {
|
||||
toggleLoader(submitButton);
|
||||
addLoader(submitButton);
|
||||
_post("/my/password/reset/" + input.value, null, (req: XMLHttpRequest) => {
|
||||
if (req.readyState != 4) return;
|
||||
toggleLoader(submitButton);
|
||||
removeLoader(submitButton);
|
||||
if (req.status != 204) {
|
||||
window.notifications.customError("unkownError", window.lang.notif("errorUnknown"));;
|
||||
window.modals.pwr.close();
|
||||
@@ -183,40 +183,43 @@ class ContactMethods {
|
||||
|
||||
append = (name: string, details: MyDetailsContactMethod, icon: string, addEditFunc?: (add: boolean) => void, required?: boolean) => {
|
||||
const row = document.createElement("div");
|
||||
row.classList.add("flex", "flex-row", "justify-between", "my-2", "flex-nowrap");
|
||||
row.classList.add("flex", "flex-row", "justify-between", "gap-2", "flex-nowrap");
|
||||
let innerHTML = `
|
||||
<div class="flex items-baseline flex-nowrap truncate">
|
||||
<div class="flex items-baseline flex-row gap-2 flex-nowrap truncate">
|
||||
<span class="shield ~urge" alt="${name}">
|
||||
<span class="icon">
|
||||
${icon}
|
||||
</span>
|
||||
</span>
|
||||
<span class="ml-2 font-bold text-ellipsis overflow-hidden">${(details.value == "") ? window.lang.strings("notSet") : details.value}</span>
|
||||
<span class="font-bold text-ellipsis overflow-hidden">${(details.value == "") ? window.lang.strings("notSet") : details.value}</span>
|
||||
</div>
|
||||
<div class="flex items-center ml-2">
|
||||
<button class="user-contact-enabled-disabled button ~neutral" ${details.value == "" ? "disabled" : ""}>
|
||||
<input type="checkbox" class="mr-2" ${details.value == "" ? "disabled" : ""}>
|
||||
<span>${window.lang.strings("enabled")}</span>
|
||||
</button>
|
||||
<div class="flex flex-col justify-center">
|
||||
<div class="flex items-center flex-row gap-2">
|
||||
|
||||
<button class="user-contact-enabled-disabled button ~neutral flex flex-row gap-2" ${details.value == "" ? "disabled" : ""}>
|
||||
<input type="checkbox" ${details.value == "" ? "disabled" : ""}>
|
||||
<span>${window.lang.strings("enabled")}</span>
|
||||
</button>
|
||||
`;
|
||||
if (addEditFunc) {
|
||||
innerHTML += `
|
||||
<button class="user-contact-edit button ~info ml-2">
|
||||
<i class="ri-${details.value == "" ? "add" : "edit"}-fill mr-2"></i>
|
||||
<span>${details.value == "" ? window.lang.strings("add") : window.lang.strings("edit")}</span>
|
||||
</button>
|
||||
<button class="user-contact-edit button ~info flex flex-row gap-2">
|
||||
<i class="ri-${details.value == "" ? "add" : "edit"}-fill"></i>
|
||||
<span>${details.value == "" ? window.lang.strings("add") : window.lang.strings("edit")}</span>
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
|
||||
if (!required && details.value != "") {
|
||||
innerHTML += `
|
||||
<button class="user-contact-delete button ~critical ml-2" alt="${window.lang.strings("delete")}" text="${window.lang.strings("delete")}">
|
||||
×
|
||||
</button>
|
||||
<button class="user-contact-delete button ~critical h-[100%]" alt="${window.lang.strings("delete")}" text="${window.lang.strings("delete")}">
|
||||
<i class="icon ri-close-line"></i>
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
|
||||
innerHTML += `
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -358,12 +361,12 @@ class ReferralCard {
|
||||
this._descriptionEl = this._card.querySelector(".user-referrals-description") as HTMLSpanElement;
|
||||
|
||||
this._infoArea.innerHTML = `
|
||||
<div class="row my-3">
|
||||
<div class="">
|
||||
<div class="inline baseline">
|
||||
<span class="text-2xl referral-remaining-uses"></span> <span class="text-gray-400 text-lg">${window.lang.strings("inviteRemainingUses")}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-3">
|
||||
<div class="">
|
||||
<div class="inline baseline">
|
||||
<span class="text-gray-400 text-lg">${window.lang.strings("expiry")}</span> <span class="text-2xl referral-expiry"></span>
|
||||
<div>
|
||||
@@ -381,7 +384,7 @@ class ReferralCard {
|
||||
toClipboard(this._url);
|
||||
const content = this._button.innerHTML;
|
||||
this._button.innerHTML = `
|
||||
${window.lang.strings("copied")} <i class="ri-check-line ml-2"></i>
|
||||
${window.lang.strings("copied")} <i class="ri-check-line"></i>
|
||||
`;
|
||||
this._button.classList.add("~positive");
|
||||
this._button.classList.remove("~info");
|
||||
@@ -454,7 +457,7 @@ class ExpiryCard {
|
||||
if (ymd[i] == 0) continue;
|
||||
const words = window.lang.quantity(langKeys[i], ymd[i]).split(" ");
|
||||
innerHTML += `
|
||||
<div class="row my-3">
|
||||
<div class="row">
|
||||
<div class="inline baseline">
|
||||
<span class="text-2xl">${words[0]}</span> <span class="text-gray-400 text-lg">${words[1]}</span>
|
||||
</div>
|
||||
@@ -504,14 +507,18 @@ const addEditEmail = (add: boolean): void => {
|
||||
|
||||
const submit = window.modals.email.modal.querySelector(".modal-submit") as HTMLButtonElement;
|
||||
submit.onclick = () => {
|
||||
toggleLoader(submit);
|
||||
addLoader(submit);
|
||||
_post("/my/email", {"email": input.value}, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4 && (req.status == 303 || req.status == 200)) {
|
||||
if (req.readyState != 4) return;
|
||||
removeLoader(submit);
|
||||
if (req.status == 303 || req.status == 200) {
|
||||
document.dispatchEvent(new CustomEvent("details-reload"));
|
||||
window.modals.email.close();
|
||||
}
|
||||
}, true, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4 && req.status == 401) {
|
||||
if (req.readyState != 4) return;
|
||||
removeLoader(submit);
|
||||
if (req.status == 401) {
|
||||
content.classList.add("unfocused");
|
||||
confirmationRequired.classList.remove("unfocused");
|
||||
}
|
||||
@@ -607,8 +614,8 @@ changePasswordButton.addEventListener("click", () => {
|
||||
}
|
||||
}, true, (req: XMLHttpRequest) => {
|
||||
if (req.readyState != 4) return;
|
||||
removeLoader(changePasswordButton);
|
||||
if (req.status == 401) {
|
||||
removeLoader(changePasswordButton);
|
||||
window.notifications.customError("oldPasswordError", window.lang.notif("errorOldPassword"));
|
||||
return;
|
||||
}
|
||||
@@ -629,10 +636,10 @@ document.addEventListener("details-reload", () => {
|
||||
<span>${window.lang.strings("welcomeUser").replace("{user}", window.username)}</span>
|
||||
`;
|
||||
if (details.admin) {
|
||||
innerHTML += `<span class="chip ~info ml-4">${window.lang.strings("admin")}</span>`;
|
||||
innerHTML += `<span class="chip ~info">${window.lang.strings("admin")}</span>`;
|
||||
}
|
||||
if (details.disabled) {
|
||||
innerHTML += `<span class="chip ~warning ml-4">${window.lang.strings("disabled")}</span>`;
|
||||
innerHTML += `<span class="chip ~warning">${window.lang.strings("disabled")}</span>`;
|
||||
}
|
||||
|
||||
rootCard.querySelector(".heading").innerHTML = innerHTML;
|
||||
|
||||
16
views.go
16
views.go
@@ -54,7 +54,11 @@ func (app *appContext) getURLBase(gc *gin.Context) string {
|
||||
|
||||
func (app *appContext) gcHTML(gc *gin.Context, code int, file string, page Page, lang string, templ gin.H) {
|
||||
gc.Header("Cache-Control", "no-cache")
|
||||
app.BasePageTemplateValues(gc, lang, page, templ)
|
||||
if page == SetupPage {
|
||||
app.SetBaseLangTemplateValues(gc, lang, templ)
|
||||
} else {
|
||||
app.BasePageTemplateValues(gc, lang, page, templ)
|
||||
}
|
||||
gc.HTML(code, file, templ)
|
||||
}
|
||||
|
||||
@@ -121,6 +125,15 @@ func (app *appContext) BasePageTemplateValues(gc *gin.Context, lang string, page
|
||||
set("pwrEnabled", app.config.Section("password_resets").Key("enabled").MustBool(false))
|
||||
}
|
||||
set("referralsEnabled", app.config.Section("user_page").Key("enabled").MustBool(false) && app.config.Section("user_page").Key("referrals").MustBool(false))
|
||||
app.SetBaseLangTemplateValues(gc, lang, base)
|
||||
}
|
||||
|
||||
func (app *appContext) SetBaseLangTemplateValues(gc *gin.Context, lang string, base gin.H) {
|
||||
set := func(k string, v any) {
|
||||
if _, ok := base[k]; !ok {
|
||||
base[k] = v
|
||||
}
|
||||
}
|
||||
langComponents := strings.Split(lang, "-")
|
||||
var shortLang string
|
||||
if len(langComponents) < 1 {
|
||||
@@ -142,6 +155,7 @@ const (
|
||||
FormPage
|
||||
PWRPage
|
||||
UserPage
|
||||
SetupPage
|
||||
OtherPage
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user