fix: keep current page on refresh via hash routing (restore page from location.hash, back/forward supported)

This commit is contained in:
aaaamoooo
2026-10-20 15:09:44 +08:00
parent 495b949f18
commit 1b77c610f4
+9 -2
View File
@@ -116,8 +116,12 @@ async function load(page = state.page) {
} catch (error) { toast(error.message, true); }
}
const PAGES = ['overview', 'servers', 'customers', 'chains', 'commands', 'operations'];
function pageFromHash() { const page = location.hash.replace(/^#/, ''); return PAGES.includes(page) ? page : 'overview'; }
function setPage(page) {
if (!PAGES.includes(page)) page = 'overview';
state.page = page; state.search = ''; closeSidebar();
if (location.hash !== `#${page}`) history.pushState(null, '', `#${page}`);
$$('#nav button').forEach((button) => button.classList.toggle('active', button.dataset.page === page));
const titles = { overview:'概览', servers:'服务器', customers:'客户与订阅', chains:'转发与节点', commands:'安装与命令', operations:'设置与运维' };
$('#page-title').textContent = titles[page]; $('#breadcrumb').textContent = `NEXUSGATE / ${titles[page]}`;
@@ -462,7 +466,7 @@ document.addEventListener('submit', async (event) => {
if (form.id === 'login-form') {
$('#login-error').textContent = '';
state.session = await api('/api/auth/login', { method:'POST', body:JSON.stringify({ username:data.get('username'), password:data.get('password') }) });
showApp(); setPage('overview'); return;
showApp(); setPage(pageFromHash()); return;
}
if (form.id === 'server-form') {
const resourceId = data.get('resourceId');
@@ -613,13 +617,16 @@ $('#sidebar-scrim').addEventListener('click', closeSidebar);
$('#refresh').addEventListener('click', () => load());
$('#logout').addEventListener('click', async () => { try { await api('/api/auth/logout', { method:'POST', body:'{}' }); } finally { showLogin(); } });
window.addEventListener('popstate', () => { const page = pageFromHash(); if (state.session && page !== state.page) setPage(page); });
window.addEventListener('hashchange', () => { const page = pageFromHash(); if (state.session && page !== state.page) setPage(page); });
(async function boot() {
let preferred = 'light'; try { preferred = localStorage.getItem('nexusgate-theme') || 'light'; } catch { /* storage may be disabled */ }
setTheme(preferred);
try {
const session = await api('/api/session');
if (!session.authenticated) return showLogin();
state.session = session; showApp(); await load('overview');
state.session = session; showApp(); setPage(pageFromHash());
} catch { showLogin(); }
setInterval(() => { if (state.session && document.visibilityState === 'visible' && !$('#modal').open) load(); }, 45000);
})();