Update web/templates/base.html

This commit is contained in:
Joshua Laymon 2025-09-06 03:37:54 +00:00
parent e9f6637e24
commit 6917a47604

View File

@ -12,14 +12,29 @@
<link id="theme-css" rel="stylesheet" <link id="theme-css" rel="stylesheet"
href="{% static 'themes/' %}{{ request.session.theme|default:'classic' }}.css"> href="{% static 'themes/' %}{{ request.session.theme|default:'classic' }}.css">
<script> <script>
// Early apply from localStorage to prevent flash if a user-selected theme exists // Resolve theme ASAP: localStorage first, else server session fallback.
// Then: set data-theme, point the theme CSS, and remember it.
(function () { (function () {
try { try {
var server = "{{ request.session.theme|default:'classic' }}";
var stored = localStorage.getItem('theme'); var stored = localStorage.getItem('theme');
var theme = stored || server;
// Mark the document with the final theme
document.documentElement.setAttribute('data-theme', theme);
// Point the theme stylesheet (only if localStorage had something)
if (stored) { if (stored) {
document.documentElement.setAttribute('data-theme', stored); var href = "{% static 'themes/' %}" + stored + ".css";
document.getElementById('theme-css').href = '{% static "themes/" %}' + stored + '.css'; var link = document.getElementById('theme-css');
if (link && link.href.indexOf(href) === -1) link.href = href;
} }
// Persist the final theme so next load is consistent
localStorage.setItem('theme', theme);
// Defer body class toggle to right after <body> opens (below).
window.__resolvedTheme = theme;
} catch (e) {} } catch (e) {}
})(); })();
</script> </script>
@ -76,7 +91,6 @@
/* --- additions for mobile hamburger --- */ /* --- additions for mobile hamburger --- */
.hamburger { display:none; } .hamburger { display:none; }
.mobile-menu[hidden]{ display:none; } .mobile-menu[hidden]{ display:none; }
@media (max-width:700px){ @media (max-width:700px){
.desktop-nav { display:none; } .desktop-nav { display:none; }
.hamburger{ .hamburger{
@ -115,10 +129,21 @@
</style> </style>
</head> </head>
{# Auto-apply 'themed-bg' for Classic so your original gradient shows everywhere (passthrough) #} <body class="{% block body_class %}{% endblock %}">
{% with current_theme=request.session.theme|default:'classic' %} <script>
<body class="{% block body_class %}{% endblock %}{% if current_theme == 'classic' %} themed-bg{% endif %}"> // Apply/Remove the gradient class based on the final resolved theme.
{% endwith %} (function () {
try {
var theme = window.__resolvedTheme || document.documentElement.getAttribute('data-theme') || 'classic';
if (theme === 'classic') {
document.body.classList.add('themed-bg'); // your original gradient class from app.css
} else {
document.body.classList.remove('themed-bg');
}
} catch (e) {}
})();
</script>
<div class="topbar-wrap"> <div class="topbar-wrap">
<div class="topbar"> <div class="topbar">
<div class="brand"> <div class="brand">
@ -200,7 +225,7 @@
<script> <script>
(function () { (function () {
/* mobile hamburger */ // mobile hamburger
const btn = document.getElementById('hamburger'); const btn = document.getElementById('hamburger');
const menu = document.getElementById('mobileMenu'); const menu = document.getElementById('mobileMenu');
if (btn && menu) { if (btn && menu) {
@ -215,25 +240,21 @@
window.matchMedia('(min-width: 701px)').addEventListener('change', () => close()); window.matchMedia('(min-width: 701px)').addEventListener('change', () => close());
} }
/* USER MENU: desktop dropdown */ // USER MENU: desktop dropdown
const userBtn = document.getElementById('userMenuBtn'); const userBtn = document.getElementById('userMenuBtn');
const userMenu = document.getElementById('userMenu'); const userMenu = document.getElementById('userMenu');
if (userBtn && userMenu) { if (userBtn && userMenu) {
const open = () => { userMenu.hidden = false; userBtn.setAttribute('aria-expanded','true'); }; const open = () => { userMenu.hidden = false; userBtn.setAttribute('aria-expanded','true'); };
const close = () => { userMenu.hidden = true; userBtn.setAttribute('aria-expanded','false'); }; const close = () => { userMenu.hidden = true; userBtn.setAttribute('aria-expanded','false'); };
userBtn.addEventListener('click', (e) => { e.stopPropagation(); userMenu.hidden ? open() : close(); }); userBtn.addEventListener('click', (e) => { e.stopPropagation(); userMenu.hidden ? open() : close(); });
document.addEventListener('click', (e) => { document.addEventListener('click', (e) => {
if (userMenu.hidden) return; if (userMenu.hidden) return;
if (!userMenu.contains(e.target) && !userBtn.contains(e.target)) close(); if (!userMenu.contains(e.target) && !userBtn.contains(e.target)) close();
}); });
document.addEventListener('keydown', (e) => { if (e.key === 'Escape') close(); }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape') close(); });
userMenu.addEventListener('click', (e) => { userMenu.addEventListener('click', (e) => {
if (e.target.closest('a') || e.target.closest('button')) close(); if (e.target.closest('a') || e.target.closest('button')) close();
}); });
window.addEventListener('blur', close); window.addEventListener('blur', close);
} }
})(); })();