fix: keep current page on refresh via hash routing (restore page from location.hash, back/forward supported)
This commit is contained in:
+9
-2
@@ -116,8 +116,12 @@ async function load(page = state.page) {
|
|||||||
} catch (error) { toast(error.message, true); }
|
} 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) {
|
function setPage(page) {
|
||||||
|
if (!PAGES.includes(page)) page = 'overview';
|
||||||
state.page = page; state.search = ''; closeSidebar();
|
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));
|
$$('#nav button').forEach((button) => button.classList.toggle('active', button.dataset.page === page));
|
||||||
const titles = { overview:'概览', servers:'服务器', customers:'客户与订阅', chains:'转发与节点', commands:'安装与命令', operations:'设置与运维' };
|
const titles = { overview:'概览', servers:'服务器', customers:'客户与订阅', chains:'转发与节点', commands:'安装与命令', operations:'设置与运维' };
|
||||||
$('#page-title').textContent = titles[page]; $('#breadcrumb').textContent = `NEXUSGATE / ${titles[page]}`;
|
$('#page-title').textContent = titles[page]; $('#breadcrumb').textContent = `NEXUSGATE / ${titles[page]}`;
|
||||||
@@ -462,7 +466,7 @@ document.addEventListener('submit', async (event) => {
|
|||||||
if (form.id === 'login-form') {
|
if (form.id === 'login-form') {
|
||||||
$('#login-error').textContent = '';
|
$('#login-error').textContent = '';
|
||||||
state.session = await api('/api/auth/login', { method:'POST', body:JSON.stringify({ username:data.get('username'), password:data.get('password') }) });
|
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') {
|
if (form.id === 'server-form') {
|
||||||
const resourceId = data.get('resourceId');
|
const resourceId = data.get('resourceId');
|
||||||
@@ -613,13 +617,16 @@ $('#sidebar-scrim').addEventListener('click', closeSidebar);
|
|||||||
$('#refresh').addEventListener('click', () => load());
|
$('#refresh').addEventListener('click', () => load());
|
||||||
$('#logout').addEventListener('click', async () => { try { await api('/api/auth/logout', { method:'POST', body:'{}' }); } finally { showLogin(); } });
|
$('#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() {
|
(async function boot() {
|
||||||
let preferred = 'light'; try { preferred = localStorage.getItem('nexusgate-theme') || 'light'; } catch { /* storage may be disabled */ }
|
let preferred = 'light'; try { preferred = localStorage.getItem('nexusgate-theme') || 'light'; } catch { /* storage may be disabled */ }
|
||||||
setTheme(preferred);
|
setTheme(preferred);
|
||||||
try {
|
try {
|
||||||
const session = await api('/api/session');
|
const session = await api('/api/session');
|
||||||
if (!session.authenticated) return showLogin();
|
if (!session.authenticated) return showLogin();
|
||||||
state.session = session; showApp(); await load('overview');
|
state.session = session; showApp(); setPage(pageFromHash());
|
||||||
} catch { showLogin(); }
|
} catch { showLogin(); }
|
||||||
setInterval(() => { if (state.session && document.visibilityState === 'visible' && !$('#modal').open) load(); }, 45000);
|
setInterval(() => { if (state.session && document.visibilityState === 'visible' && !$('#modal').open) load(); }, 45000);
|
||||||
})();
|
})();
|
||||||
|
|||||||
Reference in New Issue
Block a user