a1a49944dfac7cedda9f620ea6e8b13fd824f421
The four-page switch lived as a string union (Page) plus an if/else
chain in AppInner, with TopBar reverse-importing Sidebar's NAV_ITEMS
to find the icon for the active tab. Adding a page touched four
places and there was no URL, no history, no deep-linking.
Move routing behind @tanstack/react-router with a layout route
(AppLayout) that owns the polling lists, processOps, selectedUin
and the unload-failed alert; child routes render through <Outlet/>
and read shared state from a new AppStateContext. AuthBoundary still
gates login / forced-password-change above the router. Sidebar uses
<Link> + useRouterState for active state; TopBar and MainLayout look
up the current path the same way.
Behaviour-preserving:
- LoginPage / ChangePasswordPage still mount above the router.
- AppLayout never unmounts during navigation, so selectedUin,
processOps state, the polling state and the unload-failed dialog
all survive page switches just like before.
- Logout calls history.replaceState('/') so the next login lands on
the overview page, matching pre-router behaviour.
- The sidebar-active-pill layoutId animation and the page-transition
AnimatePresence are preserved, keyed off pathname instead of the
removed `active` prop.
New URLs (/, /config, /logs, /settings) work on refresh because the
backend already had SPA fallback in core/src/webui/server.ts. Bundle
grows ~84KB (gzip +27KB) for the router runtime.
❄️ SnowLuma
Next Remote Protocol Framework.
关于项目
项目处于开发初期,仅支持部分功能,高速迭代中,随时可能出现破坏性更新。
鸣谢
LagrangeV2 - Proto
NapCatQQ - Scaner/Packet
辅助编程
推荐 Opus4.6 + Gemini3.1pro 对本项目辅助开发
本项目大量使用Ai技术。
加入我们
Languages
TypeScript
98.9%
CSS
0.5%
JavaScript
0.5%