Enhance form recognition, optimize UI, and unify components (#19)

- **docs**: 完善组件注释、README 目录结构及 AGENTS.md 文档。
- **refactor**:
  - 提取通用 `PageHeader`、`Button`、`DashboardCard` 及 `ErrorBoundary` 组件。
  - 重构消息通信机制,采用 `@webext-core/messaging` 实现类型安全。
  - 将全局通知系统重构为 `SnackbarProvider` (后合并至 `GlobalSnackbar`)。
  - 迁移样式系统至 MUI 主题,移除冗余 CSS。
  - 优化路由配置,支持独立标签页模式及页面懒加载。
  - 移除未使用文件、URL 工具及表单映射相关功能。
- **feat**:
  - 新增配置导出功能(JSON)及状态提示。
  - 新增侧边栏状态变化通知机制。
  - 新增文本统计及 JWT 解析工具。
  - 优化二维码生成与解析逻辑,换用更轻量的 `qrious` 和 `qr-scanner`。
  - 增强高亮器功能,支持闪烁效果及 Shadow DOM 穿透。
- **style**: 优化仪表盘响应式网格布局及 UI 细节。
- **fix**: 修复 `useStorageState` 依赖缺失及路由初始化性能问题。
- **test**: 更新单元测试以覆盖新增的工具函数及功能特性。
This commit is contained in:
LingandRX
2026-05-03 17:06:32 +08:00
committed by GitHub
parent 8d36f21f1b
commit 57ea4d9858
80 changed files with 1909 additions and 15265 deletions
+32 -42
View File
@@ -1,4 +1,3 @@
import { useMemo } from 'react';
import { Box, IconButton, Typography, Stack, Tooltip } from '@mui/material';
import SettingsIcon from '@mui/icons-material/Settings';
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
@@ -8,47 +7,36 @@ import { useRouter } from '@/providers/RouterProvider';
export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void }) {
const { currentPage, goBack } = useRouter();
const isDetachedMode = useMemo(() => {
return new URLSearchParams(window.location.search).get('mode') === 'detached';
}, []);
const handleDetach = () => {
// 弹出脱离窗口 (以独立面板形式打开当前 URL,并标记 mode=detached)
const url = new URL(window.location.href);
url.searchParams.set('mode', 'detached');
chrome.windows.create({
url: url.toString(),
type: 'panel',
width: 420,
height: 600
});
const handleOpenInTab = () => {
// 在新标签页中打开扩展页面
chrome.tabs.create({ url: chrome.runtime.getURL('popup.html?mode=tab') }).catch(console.error);
window.close();
};
const isDashboard = currentPage === 'dashboard';
return (
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
sx={{
px: 2,
py: 1.5,
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
sx={{
px: { xs: 1.5, sm: 2 },
py: 1.5,
borderBottom: '1px solid',
borderColor: 'grey.100',
bgcolor: 'background.paper',
zIndex: 1100
zIndex: 1100,
}}
>
<Box sx={{ width: 40 }}>
<Box sx={{ width: { xs: 32, sm: 40 } }}>
{!isDashboard && (
<IconButton
size="small"
<IconButton
size="small"
onClick={goBack}
sx={{
sx={{
bgcolor: 'grey.50',
'&:hover': { bgcolor: 'grey.200' }
'&:hover': { bgcolor: 'grey.200' },
}}
>
<ArrowBackIosNewIcon sx={{ fontSize: 14 }} />
@@ -56,27 +44,29 @@ export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void })
)}
</Box>
<Typography
variant="subtitle2"
sx={{
fontWeight: 800,
<Typography
variant="subtitle2"
sx={{
fontWeight: 800,
letterSpacing: '0.5px',
textTransform: 'uppercase',
fontSize: '0.75rem',
color: 'text.secondary'
color: 'text.secondary',
}}
>
Testing Tools
</Typography>
<Stack direction="row" spacing={1} sx={{ width: 80, justifyContent: 'flex-end' }}>
{!isDetachedMode && (
<Tooltip title="独立窗口模式">
<IconButton size="small" onClick={handleDetach}>
<OpenInNewIcon sx={{ fontSize: 18 }} />
</IconButton>
</Tooltip>
)}
<Stack
direction="row"
spacing={0.5}
sx={{ width: { xs: 80, sm: 120 }, justifyContent: 'flex-end' }}
>
<Tooltip title="在标签页打开">
<IconButton size="small" onClick={handleOpenInTab}>
<OpenInNewIcon sx={{ fontSize: 18 }} />
</IconButton>
</Tooltip>
<Tooltip title="设置">
<IconButton size="small" onClick={onOpenOptions}>
<SettingsIcon sx={{ fontSize: 18 }} />