UI updates
This commit is contained in:
@@ -7,6 +7,8 @@ import {
|
|||||||
markAllNotificationsRead,
|
markAllNotificationsRead,
|
||||||
getClientEventNotificationEnabled,
|
getClientEventNotificationEnabled,
|
||||||
setClientEventNotificationEnabled,
|
setClientEventNotificationEnabled,
|
||||||
|
requestDesktopNotificationPermission,
|
||||||
|
setDesktopNotificationsEnabled,
|
||||||
} from "./notify-client.js";
|
} from "./notify-client.js";
|
||||||
|
|
||||||
// ── DOM refs ──────────────────────────────────────────────────────────────────
|
// ── DOM refs ──────────────────────────────────────────────────────────────────
|
||||||
@@ -50,6 +52,13 @@ const eventNotifOfflineInput = document.getElementById("event-notif-offline");
|
|||||||
const eventNotifPurgatoryInput = document.getElementById("event-notif-purgatory");
|
const eventNotifPurgatoryInput = document.getElementById("event-notif-purgatory");
|
||||||
const saveEventNotifsBtn = document.getElementById("save-event-notifs");
|
const saveEventNotifsBtn = document.getElementById("save-event-notifs");
|
||||||
|
|
||||||
|
// Browser permission status bar
|
||||||
|
const desktopNotifStatusBar = document.getElementById("desktop-notif-status-bar");
|
||||||
|
const desktopNotifStatusIcon = document.getElementById("desktop-notif-status-icon");
|
||||||
|
const desktopNotifStatusText = document.getElementById("desktop-notif-status-text");
|
||||||
|
const desktopNotifEnableBtn = document.getElementById("desktop-notif-enable-btn");
|
||||||
|
const desktopNotifDeniedHint = document.getElementById("desktop-notif-denied-hint");
|
||||||
|
|
||||||
// Preview modal
|
// Preview modal
|
||||||
const panel = document.getElementById("notification-panel");
|
const panel = document.getElementById("notification-panel");
|
||||||
const previewModal = document.getElementById("notification-preview-modal");
|
const previewModal = document.getElementById("notification-preview-modal");
|
||||||
@@ -601,6 +610,55 @@ document.addEventListener("visibilitychange", clearIfActive);
|
|||||||
window.addEventListener("focus", clearIfActive);
|
window.addEventListener("focus", clearIfActive);
|
||||||
clearIfActive();
|
clearIfActive();
|
||||||
|
|
||||||
|
function updateDesktopPermissionUi() {
|
||||||
|
if (!desktopNotifStatusBar) return;
|
||||||
|
const perm = (typeof Notification !== "undefined") ? Notification.permission : "denied";
|
||||||
|
|
||||||
|
desktopNotifEnableBtn?.classList.add("hidden");
|
||||||
|
desktopNotifDeniedHint?.classList.add("hidden");
|
||||||
|
|
||||||
|
if (perm === "granted") {
|
||||||
|
desktopNotifStatusBar.className = desktopNotifStatusBar.className
|
||||||
|
.replace(/border-\S+/g, "").replace(/bg-\S+/g, "").trimEnd();
|
||||||
|
desktopNotifStatusBar.classList.add("border-emerald-700/50", "bg-emerald-900/10");
|
||||||
|
if (desktopNotifStatusIcon) {
|
||||||
|
desktopNotifStatusIcon.className = "fa-solid fa-circle-dot text-base text-emerald-400";
|
||||||
|
}
|
||||||
|
if (desktopNotifStatusText) desktopNotifStatusText.textContent = "Browser notifications are enabled";
|
||||||
|
} else if (perm === "denied") {
|
||||||
|
desktopNotifStatusBar.className = desktopNotifStatusBar.className
|
||||||
|
.replace(/border-\S+/g, "").replace(/bg-\S+/g, "").trimEnd();
|
||||||
|
desktopNotifStatusBar.classList.add("border-red-700/50", "bg-red-900/10");
|
||||||
|
if (desktopNotifStatusIcon) {
|
||||||
|
desktopNotifStatusIcon.className = "fa-solid fa-circle-dot text-base text-red-400";
|
||||||
|
}
|
||||||
|
if (desktopNotifStatusText) desktopNotifStatusText.textContent = "Browser notifications are blocked";
|
||||||
|
desktopNotifDeniedHint?.classList.remove("hidden");
|
||||||
|
} else {
|
||||||
|
desktopNotifStatusBar.className = desktopNotifStatusBar.className
|
||||||
|
.replace(/border-\S+/g, "").replace(/bg-\S+/g, "").trimEnd();
|
||||||
|
desktopNotifStatusBar.classList.add("border-slate-700", "bg-slate-900/40");
|
||||||
|
if (desktopNotifStatusIcon) {
|
||||||
|
desktopNotifStatusIcon.className = "fa-solid fa-circle-dot text-base text-slate-400";
|
||||||
|
}
|
||||||
|
if (desktopNotifStatusText) desktopNotifStatusText.textContent = "Browser notifications not yet enabled";
|
||||||
|
desktopNotifEnableBtn?.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function wireDesktopPermissionBtn() {
|
||||||
|
if (!desktopNotifEnableBtn) return;
|
||||||
|
desktopNotifEnableBtn.addEventListener("click", async () => {
|
||||||
|
desktopNotifEnableBtn.disabled = true;
|
||||||
|
const result = await requestDesktopNotificationPermission();
|
||||||
|
if (result === "granted") {
|
||||||
|
setDesktopNotificationsEnabled(true);
|
||||||
|
}
|
||||||
|
desktopNotifEnableBtn.disabled = false;
|
||||||
|
updateDesktopPermissionUi();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ── Event notification toggles ───────────────────────────────────────────────
|
// ── Event notification toggles ───────────────────────────────────────────────
|
||||||
function loadEventNotifPrefs() {
|
function loadEventNotifPrefs() {
|
||||||
if (eventNotifOnlineInput) eventNotifOnlineInput.checked = getClientEventNotificationEnabled("client_online");
|
if (eventNotifOnlineInput) eventNotifOnlineInput.checked = getClientEventNotificationEnabled("client_online");
|
||||||
@@ -626,5 +684,7 @@ wireTelegramSave();
|
|||||||
loadMySettings();
|
loadMySettings();
|
||||||
loadEventNotifPrefs();
|
loadEventNotifPrefs();
|
||||||
wireEventNotifSave();
|
wireEventNotifSave();
|
||||||
|
updateDesktopPermissionUi();
|
||||||
|
wireDesktopPermissionBtn();
|
||||||
initRoleUi();
|
initRoleUi();
|
||||||
connect();
|
connect();
|
||||||
|
|||||||
@@ -257,7 +257,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<h2 class="text-lg font-semibold">Desktop Event Notifications</h2>
|
<h2 class="text-lg font-semibold">Desktop Event Notifications</h2>
|
||||||
<p class="text-sm text-slate-400">
|
<p class="text-sm text-slate-400">
|
||||||
Choose which client events trigger a desktop (OS) notification. Desktop notifications must be enabled in <a href="/settings" class="text-sky-400 hover:underline">Settings</a> first.
|
Choose which client events trigger a desktop (OS) notification.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@@ -268,6 +268,25 @@
|
|||||||
<span>Save</span>
|
<span>Save</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Browser permission status -->
|
||||||
|
<div id="desktop-notif-status-bar" class="flex flex-wrap items-center gap-3 mb-4 rounded-lg border px-4 py-3 text-sm">
|
||||||
|
<i id="desktop-notif-status-icon" class="fa-solid fa-circle-dot text-base"></i>
|
||||||
|
<span id="desktop-notif-status-text" class="flex-1">Checking permission…</span>
|
||||||
|
<button
|
||||||
|
id="desktop-notif-enable-btn"
|
||||||
|
class="hidden inline-flex items-center gap-2 px-3 py-1.5 rounded-lg bg-sky-600 hover:bg-sky-500 transition-colors text-white font-medium"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-bell"></i>
|
||||||
|
Enable Notifications
|
||||||
|
</button>
|
||||||
|
<p id="desktop-notif-denied-hint" class="hidden w-full text-xs text-amber-400 mt-1">
|
||||||
|
<i class="fa-solid fa-triangle-exclamation mr-1"></i>
|
||||||
|
Notifications are blocked. Reset notification permissions for this site in your browser settings, then reload.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3 text-sm">
|
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3 text-sm">
|
||||||
<label class="flex items-center gap-3 rounded-lg bg-slate-950 border border-slate-800 px-4 py-3 cursor-pointer hover:border-slate-600 transition-colors">
|
<label class="flex items-center gap-3 rounded-lg bg-slate-950 border border-slate-800 px-4 py-3 cursor-pointer hover:border-slate-600 transition-colors">
|
||||||
<input id="event-notif-online" type="checkbox" class="h-4 w-4 accent-emerald-500 shrink-0" />
|
<input id="event-notif-online" type="checkbox" class="h-4 w-4 accent-emerald-500 shrink-0" />
|
||||||
|
|||||||
@@ -25,6 +25,35 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<section class="bg-slate-900/60 border border-slate-800 rounded-xl p-5 space-y-4">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="flex items-center justify-center w-9 h-9 rounded-lg bg-sky-500/10 border border-sky-500/30">
|
||||||
|
<i class="fa-brands fa-telegram text-sky-400"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2 class="text-lg font-semibold">News & Updates</h2>
|
||||||
|
<p class="text-sm text-slate-400">Stay up to date with the newest features, releases, and announcements.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="rounded-lg border border-slate-700 bg-slate-900 px-4 py-4 flex flex-col sm:flex-row sm:items-center gap-4">
|
||||||
|
<div class="flex-1">
|
||||||
|
<p class="text-sm text-slate-300">
|
||||||
|
Follow the official Overlord Telegram channel for the latest updates, changelogs, and feature announcements.
|
||||||
|
</p>
|
||||||
|
<p class="text-xs text-slate-500 mt-1">Channel: <span class="text-slate-400 font-mono">@kunta</span></p>
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
href="https://t.me/kunta"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-sky-600 hover:bg-sky-500 transition-colors text-white text-sm font-medium whitespace-nowrap"
|
||||||
|
>
|
||||||
|
<i class="fa-brands fa-telegram"></i>
|
||||||
|
Open on Telegram
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="grid grid-cols-1 xl:grid-cols-2 gap-6">
|
<section class="grid grid-cols-1 xl:grid-cols-2 gap-6">
|
||||||
<div class="bg-slate-900/60 border border-slate-800 rounded-xl p-5 space-y-4">
|
<div class="bg-slate-900/60 border border-slate-800 rounded-xl p-5 space-y-4">
|
||||||
<div>
|
<div>
|
||||||
@@ -349,6 +378,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script type="module" src="/assets/nav.js"></script>
|
<script type="module" src="/assets/nav.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user