Files
MeowOS-For-R3P2/patch_v2/meowpanel/web/meowpanel.js
T

75 lines
5.7 KiB
JavaScript

/* meowpanel.js — MeowPanel 前端入口(应用入口/路由/启动)。
* 由 mp_shared.js + mp_pages.js 组合;在两者之后作为经典脚本加载。 */
(function () {
'use strict';
var MP = window.MP;
const { $, $$, LOG_GROUP_NAME, SPARK_MAX, api, apiDownload, applyTheme, authMode, authRequired, barHtml, bindLogin, bindPwDlg, bindSlider, bindThemeUi, browserMode, confirmDlg, dbPct, dbg, dbgErr, debounce, deciToDb, devStyleLabel, devThemeLabel, doLogin, drawSpark, emptyState, errText, esc, fmtBytes, fmtDb, fmtTime, fmtUptime, hideLogin, homeCard, homeKv, homeUnavailable, initTheme, isAvail, levelMeterHtml, loginErr, modePill, passwordDlg, pct, pushSpark, refreshAuthGate, resetSpark, resolveMode, resolveStyle, saveSetting, setConn, showLogin, slur, sparkPeak, sparkRms, sparklineHtml, sparklinePoints, stat, state, storageDel, storageGet, storageSet, storedMode, storedStyle, toast, toastTimer, updateLevelMeter, volTimer, absFor, appInfo, appStatePill, appUninstall, applyScreenDeltaDom, audioCard, audioCtlHtml, audioFlowHtml, audioPortName, audioRouteLabel, batteryCard, batteryCardBody, bindApps, bindAudio, bindFiles, bindFonts, bindHome, bindLogs, bindNet, bindNotif, bindPin, bindPower, bindProc, bindScreen, bindSettings, bindSystem, breakdownCardBody, btCard, createImgFromBlob, crumbHtml, deviceCard, doDownload, ensureScreenCanvas, escSafeAttr, estimateCardBody, eventsBar, fetchAudioOnce, fetchHomeLevel, fetchHomeSystem, fetchNetConns, fetchNetLog, fetchNetOnce, fetchOverviewOnce, fetchPerfOnce, fetchPowerOnce, fetchProcOnce, fetchScreen, fmtDur, fmtFrames, groupName, handleRemoteGesture, healthCard, importFont, importFontPage, installFromFile, installFromPath, joinRel, loadFonts, loadFontsPage, loadPinStatus, logsCrashCard, mkdirFile, navFiles, netBadge, netBannerErr, netCard, netConnsBody, netDnsBody, netIfaceCards, netPolicyCard, netStateCls, netStatusCards, newestStdout, perfCard, pinEdit, pinEditDlg, powerEventsCard, powerHistoryCard, powerPolicyCard, powerProfileLabel, powerSummaryCard, pubBytesCard, remoteBtn, remotePadHtml, remotePointerDown, remotePointerUp, removeFile, renameFile, renderApps, renderAudio, renderBright, renderFiles, renderFontsPage, renderHome, renderHomeCards, renderLogs, renderLogsFiles, renderNet, renderNotif, renderPerf, renderPerfData, renderPower, renderPowerBody, renderProc, renderProcBody, renderScreen, renderSettings, renderSystem, restartScreenPoll, row, screenTap, seedScreenCanvas, segments, sendKey, sendKeyLabel, sendKeyRepeat, sendTheme, setBrightCtl, setPanelPassword, settingControl, srcPill, stopAudio, stopHome, stopNet, stopPerf, stopPower, stopProc, stopScreenPoll, storageCard, svcStatePill, uploadFiles, viewAppStdout, viewLogsCrashTail, volSteps } = MP;
const ROUTES = {
home: { title: '首页仪表盘', render: renderHome, bind: bindHome },
perf: { title: '实时性能', render: renderPerf, bind: null },
bright: { title: '亮度 · 音量', render: renderBright, bind: null },
audio: { title: '音频状态', render: renderAudio, bind: bindAudio },
net: { title: '网络管理', render: renderNet, bind: bindNet },
files: { title: '文件管理', render: renderFiles, bind: bindFiles },
apps: { title: 'MeowAPPs 管理', render: renderApps, bind: bindApps },
fonts: { title: '字体管理', render: renderFontsPage, bind: bindFonts },
settings: { title: '设置镜像', render: renderSettings, bind: bindSettings },
screen: { title: '屏幕 · 遥控', render: renderScreen, bind: bindScreen },
system: { title: '系统信息 / 升级', render: renderSystem, bind: bindSystem },
logs: { title: '系统日志', render: renderLogs, bind: bindLogs },
notif: { title: '通知中心', render: renderNotif, bind: bindNotif },
power: { title: '电源 / 功耗', render: renderPower, bind: bindPower },
proc: { title: '进程 / 服务', render: renderProc, bind: bindProc }
};
let started = false;
function bindNav() {
$$('.nav-item').forEach(b => b.addEventListener('click', () => { location.hash = '#/' + b.dataset.route; }));
$('#menu-btn').addEventListener('click', () => $('#sidebar').classList.toggle('open'));
}
async function init() {
bindNav();
bindThemeUi();
bindSlider();
bindFiles(); bindApps(); bindFonts(); bindSettings(); bindScreen(); bindSystem(); bindLogs(); bindNotif(); bindNet(); bindHome(); bindProc(); bindPin(); bindAudio();
bindLogin();
bindPwDlg();
// 首次进入:访问级 PIN 鉴权——已登录直接进;未设 PIN(且无旧密码)→ 首次设置流程;已设 → 登录
let st = null;
try { st = await api('GET', '/api/auth/status'); } catch (e) { st = null; }
if (st && st.session) { startApp(); return; }
if (st && !st.pin_set && !st.legacy) { showLogin('setup'); return; }
if (st) { showLogin('login'); return; }
startApp(); // 后端不可达:仍启动(显示离线横幅)
}
function route() {
if (state.unauth) { showLogin(MP.authMode); return; } // 未认证 → 登录页(保持当前设置/登录态)
const id = (location.hash || '#/home').replace('#/', '').split('?')[0] || 'home';
const r = ROUTES[id] || ROUTES.home;
state.route = id;
dbg('route →', id);
stopPerf();
stopAudio();
stopNet();
stopScreenPoll();
stopHome();
stopPower();
stopProc();
$$('.nav-item').forEach(b => b.classList.toggle('active', b.dataset.route === id));
$('#page-title').textContent = r.title;
r.render();
}
function startApp() {
if (started) { route(); return; }
started = true;
initTheme();
window.addEventListener('hashchange', route);
route();
}
document.addEventListener('DOMContentLoaded', init);
})();