Files
holesail-browser/extension/dashboard/core/init.js
T
Raven Scott 2595a01f65
CI / Build & Test (push) Successful in 4m27s
feat: autopass-based cross-device sync for Holesail Browser
- Native host: add autopass + corestore deps, sync-manager (createInvite, pairWithInvite, push/pull)
- Apply synced state via same flow as backup restore (state.json only, no certs)
- Holesail-manager: setOnStateSaved hook for sync push
- Extension: Sync dashboard page, getSyncStatus/createSyncInvite/pairWithInvite, syncApplied event
- Docs: NATIVE-HOST.md sync commands, SYNC.md
2026-03-15 01:31:51 -04:00

94 lines
3.1 KiB
JavaScript

/**
* Dashboard entry point. Guards against loading outside the dashboard context,
* initialises navigation and all page event handlers, then starts the 2-second
* refresh cycle.
* Depends on: all other dashboard modules (loaded before this file)
*/
/**
* Guard: only run when loaded as the actual dashboard page.
*/
if (!document.getElementById('page-dashboard') && !document.querySelector('.sidebar-logo')) {
throw new Error('dashboard scripts loaded outside dashboard context — aborting');
}
/**
* Initialise the dashboard: set the version string, wire up navigation and all
* page event handlers, run the first state refresh, and start the 2-second polling interval.
* @returns {Promise<void>}
*/
async function init() {
log('Dashboard initializing…');
try {
const manifest = chrome.runtime.getManifest();
const versionEl = $('sidebarVersion');
if (versionEl && manifest.version) {
versionEl.textContent = 'v' + manifest.version + ' · hole.sail';
}
} catch (_) {}
setupNavigation();
setupEvents();
setupCertValidator();
setupSshEvents();
setupRdpEvents();
setupBackupEvents();
setupSyncEvents();
await refresh();
// When native host emits syncApplied, refresh state immediately
chrome.runtime.onMessage.addListener((msg) => {
if (msg.type === 'holesail-event' && msg.payload && msg.payload.event === 'syncApplied') {
refresh();
}
});
// Main state-refresh interval: configurable (2s / 5s / 10s), or paused when tab is hidden or setting is 0.
let _refreshIntervalId = null;
function _getRefreshMs() {
const ms = (settings.dashboardRefreshIntervalMs !== undefined ? settings.dashboardRefreshIntervalMs : 2000);
return (typeof ms === 'number' && ms >= 0 ? ms : 2000);
}
function _startRefreshInterval() {
if (_refreshIntervalId) clearInterval(_refreshIntervalId);
_refreshIntervalId = null;
if (document.visibilityState === 'hidden') return;
const ms = _getRefreshMs();
if (ms <= 0) return;
_refreshIntervalId = setInterval(refresh, ms);
}
function _restartRefreshInterval() {
_startRefreshInterval();
}
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
refresh();
_startRefreshInterval();
} else {
if (_refreshIntervalId) { clearInterval(_refreshIntervalId); _refreshIntervalId = null; }
}
});
_startRefreshInterval();
window._restartRefreshInterval = _restartRefreshInterval;
// Latency-ping interval — driven by settings.latencyPingIntervalMs.
let _pingInterval = null;
function _restartPingInterval() {
if (_pingInterval) clearInterval(_pingInterval);
_pingInterval = null;
if (settings.latencyPingEnabled === false) return;
const ms = (settings.latencyPingIntervalMs > 0 ? settings.latencyPingIntervalMs : 5000);
_pingInterval = setInterval(_pingLatencyBadges, ms);
}
_restartPingInterval();
window._restartPingInterval = _restartPingInterval;
window.addEventListener('beforeunload', () => {
if (_refreshIntervalId) clearInterval(_refreshIntervalId);
if (_pingInterval) clearInterval(_pingInterval);
}, { once: true });
}
init();