雨霖铃
9c5f5c8cfe
refactor(StorageCleaner): 规范化页面组件目录结构
...
- 将子组件移至 components/ 子目录(OptionItem、AutoRefreshToggle、CleaningResult、StorageCleanerConfirm、StorageOptionsGrid、ErrorDisplay)
- 创建 __tests__/ 目录结构
- 更新所有相关导入路径
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-10 20:56:38 +08:00
雨霖铃
016173a9c5
refactor(JsonTools): 规范化页面组件目录结构
...
- 将子组件移至 components/ 子目录(JsonDiffInput、DiffResult、JsonFormatSection、JsonConvertSection、DiffNavigator、JsonTree)
- 将 diffEngine.ts 工具函数移至 src/utils/
- 提取 ConvertFunction/ConvertResult 类型到 types.ts,解决循环依赖
- 创建 __tests__/ 目录结构
- 更新所有相关导入路径
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-10 20:39:40 +08:00
雨霖铃
30d3561726
refactor: 规范化页面组件目录结构
...
- 将 QrCodePreview、ImageUploader 移动到 QrCode/components/
- 将 DecodeResultPaper、Base64ConverterSection、TextMode 移动到 Base64Converter/components/
- 提取 useTextMode Hook,遵循 UI + Hook 分离模式
- 简化 SwitchButtonGroup 组件,提取常量到外部
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-10 20:11:35 +08:00
雨霖铃
1f9288f780
refactor: 使用 Label 组件替换原生 label 元素,并在 DecodeResultPaper 中引入 Input 组件
2026-06-10 08:15:09 +08:00
雨霖铃
355a94d116
refactor: 将 formatFileSize 重命名为 formatBytes 并移至通用工具模块
2026-06-10 00:32:29 +08:00
雨霖铃
9a0c8ba850
fix: 更新 features 测试断言以匹配新增的 testDataGenerator
...
fix: 修复测试数据生成器多项代码问题
- useCallback 闭包问题:改用函数式 setFields 更新,避免依赖过时引用
- Worker 复用:复用已有 Worker 而非每次 generate 都销毁重建
- 导出复制反馈:复制操作完成后添加 toast 成功/失败提示
- 字段名校验:添加空值、非法字符、重复名称校验
- i18n 硬编码:GeneratorConfig 和 ruleStorage 统一使用 t() 函数
2026-06-06 23:40:36 +08:00
雨霖铃
6c7b7294b4
feat: 优化规则管理功能
...
- 移动保存按钮到字段配置区域
- 添加规则编辑功能,支持更新和另存为
- 编辑模式下显示编辑状态标识
- 保存时检查规则名称重复,支持覆盖保存
- 优化弹窗样式,统一风格
- 更换加载图标为 FolderOpen
- 添加搜索防抖和错误处理
- 添加国际化文本
2026-06-06 23:08:05 +08:00
雨霖铃
a2e07a9115
refactor: 删除未使用的 defaultNullRate 功能
...
- 移除 GenerateOptions 中的 defaultNullRate 相关 props 和 UI
- 移除 messages.json 中的 testDataGenerator_defaultNullRate 翻译 key
2026-06-06 20:08:06 +08:00
雨霖铃
2464a5fea6
feat: 字段编辑弹窗添加「完成」按钮 去除关闭按钮,添加取消按钮
...
- 弹窗底部添加「完成」按钮,点击关闭弹窗
- DialogContent 支持 showCloseButton prop 控制关闭按钮显示
- 底部添加取消和完成两个按钮
2026-06-06 20:06:48 +08:00
雨霖铃
78f5292b00
fix: 切换为非必填时默认空值率 100%
...
- 必填 → 非必填:默认空值率 100%(始终生成 null)
- 非必填 → 必填:空值率清零
2026-06-06 19:42:55 +08:00
雨霖铃
5a2589cc57
fix: 修复空值率与必填状态的逻辑
...
- 空值率 0% 时自动设为必填(始终生成数据)
- 空值率 > 0% 时设为非必填(按概率生成 null)
- 移除空值率 100% 自动变为必填的错误逻辑
2026-06-06 19:41:42 +08:00
雨霖铃
64db60d75e
fix: 非必填字段预览显示 null
...
- 预览示例数据中,非必填字段显示 null 值
- 保持与实际生成逻辑一致
2026-06-06 19:36:41 +08:00
雨霖铃
7090ba3251
refactor: 数据预览改为显示示例数据,简化组件逻辑
...
- DataPreview 改为接收字段配置,显示一条示例数据
- 移除虚拟列表、格式切换等复杂功能
- 添加 JSON 语法高亮(键名蓝色、字符串绿色、数字琥珀色、布尔紫色)
- 优化空状态样式,垂直居中显示
- 缩短预览区域高度 (400px → 280px)
- 添加 testDataGenerator_sampleData 翻译 key
2026-06-06 19:29:27 +08:00
雨霖铃
31b6edf06b
feat: 生成成功改为 toast 提示
...
- 使用 sonner toast 显示成功提示
- 简化提示:生成完成 + 数据条数
- 仅在失败或有警告时显示结果面板
- 使用 useRef 记录已触发的 result
- 仅在新 result 时触发 toast
2026-06-06 11:05:42 +08:00
雨霖铃
a374bf456d
feat: 数据格式改为按钮组选择
...
- 移除 Select 下拉框
- 改为 JSON/CSV 按钮组
- 选中状态与生成数量按钮样式统一
feat: 优化空值率设置
- 增加 75% 预设选项
- 设置 100% 时自动设为必填
- 限制输入范围 0-100
fix: 空值率预设改为纯数字显示
- 5%/20%/50%/75% 统一样式
fix: 移除空值率低/中/高 i18n 翻译键
fix: 精简生成数量预设选项
- 移除 10、500
- 保留 50、100、1000、5000、10000
2026-06-06 10:52:56 +08:00
雨霖铃
ea10b27c14
feat: 简化字段卡片交互 - 点击直接打开编辑弹窗
...
- 移除字段卡片选中样式
- 点击字段直接打开编辑弹窗
- 简化 FieldItem 组件,移除 isSelected 属性
- 简化 FieldList 接口,onSelect 改为 onEdit
fix: 优化字段编辑弹窗
- 去除弹窗描述文字
- 字段名称增加字符计数 (x/20)
- 字段描述增加字符计数 (x/50)
- 保持 placeholder 提示
fix: 修复弹窗顶部间距问题
- DialogContent 添加 pt-6 避开关闭按钮
- 内容区域移除顶部 padding,改为 pb-6
fix: 增加弹窗顶部间距 (pt-6 → pt-8)
fix: 优化弹窗尺寸和按钮间距
- 弹窗最大宽度 360→420px 适配标签页
- 增加按钮 padding (px-2→px-3, py-1→py-1.5)
- 添加按钮增加 padding (h-8→h-9, px-3)
2026-06-06 10:43:35 +08:00
雨霖铃
40443c8fc5
fix: 优化字段编辑弹窗样式
...
- 去除弹窗标题
- 描述文字显示选择字段提示
- 关闭按钮置顶,不随内容滚动
- 内容区域独立滚动
2026-06-06 10:32:19 +08:00
雨霖铃
ee4a45630e
fix: 限制弹窗尺寸适配 popup 显示
...
- 最大宽度 360px
- 最大高度 calc(100vh - 4rem)
- 内容超出时支持滚动
- 宽度自适应 viewport
2026-06-06 10:31:07 +08:00
雨霖铃
4a423889d9
feat: 字段编辑改为弹窗显示
...
- 添加 Dialog 组件包裹 FieldEditor
- 点击字段卡片打开编辑弹窗
- 简化布局,移除右侧字段编辑面板
- 支持点击遮罩或关闭按钮关闭弹窗
2026-06-06 10:29:44 +08:00
雨霖铃
ee78e314d3
fix: 修复拖拽时滚轮滚动不生效问题
...
- 改为在 document 级别监听 wheel 事件
- 使用 capture 阶段优先处理事件
- 确保在 PointerSensor 拦截前捕获滚轮事件
2026-06-06 10:20:59 +08:00
雨霖铃
ee77c97b56
feat: 拖拽时支持鼠标滚轮滚动列表
...
- 拖拽状态下监听 wheel 事件
- 使用 preventDefault 阻止默认滚动
- 降低滚动速度 (0.5x) 提供更精确的控制
- 自动更新虚拟列表渲染范围
2026-06-06 10:18:13 +08:00
雨霖铃
aa8b84af50
fix: 修复虚拟列表拖拽时显示空白问题
...
- 添加 DragOverlay 独立渲染拖拽中的项目
- 拖拽时扩展预加载范围 (OVERSCAN 2→10)
- 添加 activeId 状态跟踪拖拽项目
- 拖拽中的卡片以半透明效果独立显示
2026-06-06 10:17:16 +08:00
雨霖铃
707f17ac84
feat: 字段列表优化 - 输入限制、选中样式、取消选中
...
- FieldEditor: 字段名称maxLength=20,描述maxLength=50
- FieldItem: 统一有无描述时的垂直居中布局,选中左侧竖线+背景高亮
- FieldList: 点击已选中字段可取消选中,选中态加shadow和ring效果
- index: 支持selectedIndex=-1取消选中
2026-06-06 10:09:48 +08:00
雨霖铃
af0b2d8ed1
fix: 统一字段列表卡片高度,最大字段数改为40
...
- MAX_FIELDS: 20 → 40
- 固定卡片高度52px,无论虚拟/非虚拟模式视觉一致
- 5条以上容器高度固定,启用虚拟滚动
- 主页面添加字段时检查MAX_FIELDS限制
2026-06-06 09:58:57 +08:00
雨霖铃
49e7f1ea55
feat: 实现虚拟列表、拖拽排序、实时预览防抖,更新文档
...
- DataPreview: 大数据量(>100条)自动启用虚拟滚动,仅渲染可见区域
- FieldList: 基于 @dnd-kit/sortable 实现拖拽排序
- index.tsx: 配置变更时300ms防抖生成预览数据
- ui-design.md: 去除平板/移动端响应式、快捷键,更新交互说明
- technical-implementation.md: 去除downloadAsZip,更新虚拟列表说明
2026-06-06 09:42:58 +08:00
雨霖铃
1a92e88934
feat: 实现测试数据生成器完整功能
...
- 添加类型定义 (FieldConfig, DataRule, GeneratorDefinition 等)
- 实现 21 个数据生成器 (个人信息/业务数据/技术数据/基础类型)
- 实现 Web Worker 后台数据生成引擎
- 实现规则存储与管理功能
- 实现 JSON/CSV 数据导出功能
- 开发完整 UI 组件 (字段管理/生成器选择/数据预览/导出面板等)
- 集成到应用功能配置,添加国际化支持
功能特性:
- 实时预览生成的数据
- 字段配置 (名称/描述/必填/空值率/唯一性约束)
- 规则管理 (保存/加载/搜索/导入导出)
- Web Worker 后台生成,支持进度显示和取消
- 响应式布局,支持多种设备
docs: 更新 TASKS.md 所有子任务复选框为已完成状态
2026-06-06 09:29:12 +08:00
雨霖铃
7f22b95aa2
refactor: 移除不必要的 export 关键字
...
中优先级任务:将仅内部使用的函数和类型移除 export 关键字
移除 export 的函数:
- uiPopover: showPopover
- storageCleaner: injectClearLocalStorage, injectClearSessionStorage,
injectClearIndexedDB, injectClearCacheStorage, injectUnregisterServiceWorkers
移除 export 的类型和常量:
- base64Converter: SUPPORTED_IMAGE_TYPES, SUPPORTED_IMAGE_EXTENSIONS,
TextToBase64Result, Base64ToBlobResult
- contextMenu: ContextMenuItemConfig, ContextMenuClickedInfo, ParseResult
- jsonFormatter: JsonMinifyResult
- jsonToToml: JsonToTomlResult
- jsonToYaml: JsonToYamlResult
- jwt: JwtHeader, JwtPayload
- qrCodeParser: QrCodeParseResult
所有 473 个测试通过,类型检查通过
2026-06-06 01:00:10 +08:00
雨霖铃
9990d86270
refactor: 删除高优先级死代码
...
删除未使用的代码以提高代码质量和可维护性:
删除的文件:
- src/pages/Dashboard/ToolCard.tsx:未被使用的组件
- src/utils/useDebounce.ts:未被使用的 hook
- src/components/__tests__/ToolCard.test.tsx:对应组件的测试文件
删除的导出函数:
- chromeTabs: getActiveTab, getActiveTabDomain, ensureContentScriptInjected
- clipboard: copyImageToClipboard
- storageCleaner: isEmptyResult
- chromeI18n: preloadNamespaces
- useContextMenuData: clearContextMenuData
更新了对应的测试文件以保持一致性
总计删除 525 行代码,所有 473 个测试通过
2026-06-06 01:00:10 +08:00
雨霖铃
2520d72eb1
refactor: 移动 CopyButton 测试文件到统一 __tests__ 目录
2026-06-05 21:57:19 +08:00
LingandRX
4d038203a7
fix(CopyButton): 修复 review 反馈并补充测试 ( #66 )
...
* fix: remove non-functional animation classes from CopyButton
* test(CopyButton): 补充单元测试覆盖边界场景
* fix: unify CopyButton imports to named export across all consumers
* fix(CopyButton): add aria-label for screen reader accessibility
2026-06-05 21:16:12 +08:00
LingandRX
2c45ddada9
fix: add missing Toaster component to enable toast display ( #65 )
...
The project was calling toast.success/error/warning from sonner in 7 files,
but the <Toaster> component was never rendered in the React tree. This meant
sonner stored toast data internally but no UI was ever displayed to users.
Changes:
- Create src/components/ui/sonner.tsx with shadcn/ui-style Toaster wrapper
that integrates with ThemeModeProvider for light/dark theme support
- Add <Toaster /> to AppRoot.tsx so it works across all entry points
(popup, sidepanel, browser-tab)
fix: always convert dots to underscores in i18n t() key lookup
The t() function only converted dots to underscores when the key contained
a colon (namespace:key format). Keys using dot notation like
'messages.copySuccess' were passed directly to chrome.i18n.getMessage()
without dot-to-underscore conversion, causing lookups to fail silently and
return empty strings - resulting in toast notifications with no text.
Now all separators (both ':' and '.') are consistently converted to '_'
regardless of format, matching the messages.json key convention.
fix: position toast at bottom-center instead of bottom-right
2026-06-05 19:34:09 +08:00
雨霖铃
77f722b575
fix: 修复右键菜单 srcUrl 误判、pre-push 全量扫描、generating 状态不可见问题
...
- contextMenu: srcUrl 检查限定为 qrCode-image 菜单项,避免其他菜单误返回图片 URL
- pre-push: eslint 改为只检查变更文件(git diff 过滤),tsc 保留全项目检查
- useQrCode: confirmGenerate 用 setTimeout 延迟生成,让 loading 状态先被 React 渲染
- tests: 生成相关测试改为 async + waitFor 适配异步 confirmGenerate
2026-06-05 12:49:43 +08:00
雨霖铃
37bdeb5f3a
fix(qrcode): 去除已上传图片区域重复的文本预览
...
- 移除图片预览区域中的解析结果文本预览
- 解析结果只在下方的 TextInputArea 中显示
- 避免重复显示相同内容
2026-05-30 21:03:35 +08:00
雨霖铃
e919af6857
fix(qrcode): 修复图片右键菜单功能描述和检测逻辑
...
- 修改菜单标题为「解析图片二维码」更准确
- 改进 isImageUrl 函数,支持更多图片URL格式
- 支持 data:image/ 格式
- 支持URL路径中包含图片相关关键词
- 更新国际化文案和测试用例
2026-05-30 21:01:33 +08:00
雨霖铃
5be15301b5
feat(qrcode): 实现图片转二维码右键菜单功能
...
- 添加图片类型的右键菜单配置
- 修改 parseContextMenuClick 支持 srcUrl 参数
- 实现图片URL自动解析功能
- 检测图片URL自动切换到解析模式
- 更新测试用例覆盖新功能
- 新增国际化文案
2026-05-30 20:58:28 +08:00
雨霖铃
306600a35c
refactor(qrcode): 优化二维码转文本布局,与文本转二维码风格统一
...
- 未上传图片时只显示上传区域
- 上传图片后显示小图预览 + 解析结果
- 添加重新上传按钮
- 解析结果文本限制显示长度
- 新增国际化文案(已上传图片、重新上传、解析中等)
- 适配popup窗口紧凑布局
2026-05-30 20:51:48 +08:00
雨霖铃
a0345b384d
style(qrcode): 优化预览态布局适配popup窗口
...
- 调整文本预览区域高度,单行显示截断文本
- 缩小二维码图片尺寸(56x56 -> 48x48)
- 减少内边距和间距,更紧凑的布局
- 确保完整显示在popup窗口中无需滚动
2026-05-30 20:46:47 +08:00
雨霖铃
9458d62a99
feat(qrcode): 右键菜单传入URL时自动生成二维码
...
- 右键菜单传入URL时直接生成二维码,跳转到预览态
- 保留手动输入文本并点击生成按钮的功能
- 优化用户体验,简化操作流程
2026-05-30 20:38:23 +08:00
雨霖铃
5b26287cff
refactor(qrcode): 优化布局逻辑,输入态隐藏预览区域
...
- 输入态:只显示输入框和生成按钮,隐藏二维码预览
- 预览态:上方显示文本预览(超长文本截断),下方显示二维码
- 点击编辑返回输入态,隐藏二维码预览
- 更新测试用例适配新布局
2026-05-30 20:29:12 +08:00
雨霖铃
6dca673a5a
refactor(qrcode): 优化文本转二维码为两步操作模式
...
- 将实时预览改为显式触发生成,用户体验更清晰
- 新增输入态(input)和预览态(preview)两种状态
- 输入态:显示输入框和生成按钮,右侧显示占位提示
- 预览态:显示只读文本预览和编辑按钮,右侧显示二维码
- 保存上次输入内容,返回编辑态时自动回填
- 添加空输入校验和错误提示
- 更新国际化文案
- 完善单元测试覆盖新功能
2026-05-30 20:23:05 +08:00
LingandRX
3f447708b7
fix: replace undefined formatByteSize with formatBytes ( #57 )
...
JsonConvertSection.tsx and JsonFormatSection.tsx were calling
formatByteSize which doesn't exist. The correct function name
imported from @/utils/format is formatBytes.
Co-authored-by: Ubuntu <ubuntu@localhost.localdomain >
2026-05-30 12:55:04 +08:00
LingandRX
f9821553b3
chore: merge develop into main ( #56 )
...
* fix(ci): fix release workflow artifact upload issue
- Split artifact upload into 3 separate steps (Chrome, Firefox, Source)
- Update download steps to match new artifact names
- Add if-no-files-found: error for better error handling
- Fix Node.js 20 compatibility issue with upload-artifact@v4 glob pattern
* docs: 更新 AGENTS.md,添加测试工具和翻译文件结构说明
* docs: 更新 AGENTS.md,完善 CI 步骤和存储键名格式说明
* fix: remove unnecessary animations from StorageCleaner page
- Remove entrance animations (animate-in, fade-in, zoom-in) from all components
- Remove scale effect (active:scale-[0.99]) from clean button
- Remove transition effects (transition-all, transition-colors) from OptionItem, StorageOptionsGrid, AutoRefreshToggle
- Remove bouncing animation from error icon
- Remove pulsing animation from warning banner
- Keep animate-spin on button loading spinner as functional indicator
* fix: remove unnecessary animations from RightClickRestorer page
* fix: remove all unnecessary animations from all pages
- Remove dead code animations (animate-in, fade-in, slide-in, zoom-in, shake) from tailwindcss-animate plugin (not installed)
- Remove decorative transition effects (transition-all, transition-colors) from all page components
- Remove scale effects (active:scale-95) from buttons
- Remove bounce animations (animate-bounce) from icons
- Keep functional animate-spin on loading spinners as they provide essential loading feedback
Affected pages: Dashboard, Timestamp, Jwt, JsonTools, Base64Converter, HtmlToMarkdown, MarkdownToHtml, QrCode, TextStatistics
* docs: 添加项目文档(copilot-instructions、编码规范、各目录 README)
- 新增 .github/copilot-instructions.md:Copilot 指令文件,涵盖构建命令、CI 流水线、项目架构、关键规范
- 新增 .github/CODING_STANDARDS.md:完整的代码编写规范文档(TypeScript、React、样式、错误处理、命名、测试、Hook、i18n、存储等 12 个章节)
- 新增 11 个目录的 README.md:components、components/ui、config、entrypoints、i18n、lib、pages、providers、public、src、types、utils
- 更新 AGENTS.md:补充页面组件模式说明和 components/ui 目录
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(CopyButton): use shadcn buttonVariants instead of duplicated variant classes
Remove hand-written variantClasses/sizeClasses that duplicated shadcn's
buttonVariants. Now extends ButtonProps and imports buttonVariants from
components/ui/button for consistent styling.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(ErrorBoundary): use shadcn destructive tokens instead of hardcoded red colors
Replace hardcoded red-200/red-50/red-600 with border-destructive,
bg-destructive/5, text-destructive. Use variant='destructive' on
Button. Align error log styling with PageErrorBoundary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(TextInputArea): replace hardcoded Chinese strings with i18n t() calls
Use existing translation keys for clear success, copy success, and
copy error messages instead of hardcoded Chinese text.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(QrCodePreview): use shadcn Button instead of manual button styles
Replace hand-written button class strings with shadcn Button component
using outline and default variants. Removes ~15 lines of duplicated
Tailwind classes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* docs(GlobalSnackbar): clarify relationship with sonner toast
Add note explaining when to use GlobalSnackbar (provider context,
severity levels, custom positioning) vs sonner toast (simple one-off
messages).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(ImageUploader): wrap handleClearFile with useCallback
Prevents unnecessary re-renders by memoizing the callback, consistent
with handleFileChange which already uses useCallback.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(SwitchButtonGroup): remove redundant containerPadding conditional
Both branches of the ternary returned 'p-1'. Inline the constant
directly into the className string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(TopBar): add missing openExtensionPage import
The function was called in handleOpenInTab but never imported from
utils/chromeTabs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(TopBar): add selectedIndex boundary protection in keyboard nav
Guard against out-of-bounds access when search results change during
keyboard navigation. Check selectedIndex < totalItems before accessing
arrays.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(RouterContainer): remove unnecessary empty-dep useMemo
getEntryPointType() is a simple config getter. Replace useMemo(() => ..., [])
with a direct call — the empty dep array made the memo pointless.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* feat(i18n): add missing translation keys for error boundaries and copy messages
Add keys for errorBoundary, pageErrorBoundary, router, and
messages.copyEmpty in both zh and en locales.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(CopyButton): replace hardcoded Chinese strings with i18n t() calls
Use useTranslation('common') for tooltip, copy empty/success/error
toast messages.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(ErrorBoundary): replace hardcoded Chinese with i18n via withTranslation HOC
Use react-i18next withTranslation HOC for class component to translate
title, description, and refresh button text.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(PageErrorBoundary): replace hardcoded Chinese with i18n via withTranslation HOC
Use react-i18next withTranslation HOC for class component to translate
title, description, and retry button text.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(RouterContainer): replace hardcoded Chinese with i18n t() calls
Use useTranslation('common') for 404 page title and description with
entryPointType interpolation.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(pages): 修复 TypeScript 错误、硬编码字符串,移除死代码
- 修复 LiveClock.tsx CopyButton size 属性类型错误 (small → sm)
- 修复 ToolCard.tsx 紫色 RGB 值拼写错误 (147,51,2 purple → 147,51,232)
- 替换 4 处硬编码中文为 i18n 调用 (StorageCleaner, JsonTools)
- MarkdownToHtml 预览链接色改为 CSS 变量以支持暗黑模式
- 移除 Base64Converter 中已被 Base64ConverterSection 替代的死代码
(FileMode.tsx, ImageMode.tsx 及其测试文件)
- 更新 README.md 移除对已删除文件的引用
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(CopyButton, LiveClock): 修改按钮大小为 'icon',移除硬编码颜色配置
* refactor(TextInputArea): 复用 CopyButton 组件替换内联复制逻辑
* fix(test): 修复 CopyButton mock 未捕获 clipboard writeText 异常
* refactor: 迁移 i18n 系统从 react-i18next 到 chrome.i18n
- 移除 react-i18next、i18next 及相关依赖
- 删除旧的 i18n/ 目录和 useLazyTranslation 工具
- 新增 utils/chromeI18n.ts 类型安全 wrapper(useI18n Hook + getMessage)
- 生成 public/_locales/{zh,en}/messages.json(298 个翻译 key)
- 批量更新 39+ 组件文件的导入和翻译调用
- 转换翻译键格式:namespace:key → namespace_key
- 修复 ErrorBoundary/PageErrorBoundary 从 withTranslation HOC 改为直接调用 getMessage
- 更新 vitest.setup.ts mock 加载实际翻译文本
- 修复 11 个测试文件的断言以匹配中文翻译
- TypeScript、ESLint、547 项测试全部通过
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* refactor: 移除语言切换按钮
chrome.i18n 语言由浏览器设置决定,不支持运行时切换,移除 TopBar 中的语言切换按钮及相关逻辑。
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* refactor: 移除英文翻译,仅保留中文
删除 public/_locales/en/ 目录,清理 chromeI18n.ts 中未使用的语言切换相关导出。
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* chore: 清理未使用的 i18n key(322 → 245)
移除 77 个未被源码引用的翻译 key,包括:
- jsonFormat_* (17): 未接入的子模式标题和按钮
- buttons_* (15): 代码使用 common: 命名空间格式,直接 key 未引用
- qrCode_* (14): 未使用的页面标题和状态提示
- timestamp/common/storageCleaner/jsonDiff 等零散未用 key
保留了通过模板字面量动态引用的 key(storageCleaner_options_*、common_buttons_themeMode_*、jsonFormat_*InputPlaceholder 等)。
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* refactor: reorganize directory structure into src/
Move all source code directories into src/ for cleaner project structure:
- pages/, components/, utils/, config/, providers/, types/, lib/, assets/, entrypoints/ → src/
- Use WXT srcDir config to resolve @/ alias to src/
- Update tsconfig, vitest, eslint, tailwind configs
- Remove scattered README.md files from subdirectories
- Update documentation (AGENTS.md, CODING_STANDARDS.md, README.md)
- Fix pre-existing lint error in RouterProvider.tsx
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* refactor: remove meaningless comments
Remove 50+ noise comments across the codebase:
- AI-generated verbose prose (💡 emoji, '超进化', '大闸', etc.)
- Comments that restate what the code obviously does
- Comments about deleted code
- Import-level noise comments
- Overly verbose Chinese section markers
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* refactor: clean up unused code and simplify imports
- Remove unused imports and variables across 35 files
- Simplify component logic and remove dead code
- Clean up test files by removing unnecessary setup
- Streamline CI workflow configuration
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* feat: remove HTML-Markdown conversion features (htmlToMarkdown & markdownToHtml)
Removed both conversion tools and all related code:
- Deleted page components: HtmlToMarkdown, MarkdownToHtml
- Deleted utility functions: htmlToMarkdown.ts, markdownToHtml.ts
- Deleted unit tests for both utilities
- Removed feature configs and PageType entries from storage.d.ts
- Removed preview mode types and StorageSchema keys
- Removed all i18n translation keys from messages.json
- Removed vendor-markdown chunk from wxt.config.ts
- Removed marked dependency from package.json
- Updated feature count in tests (11 -> 9, page order 10 -> 8)
- Updated README, AGENTS.md, and copilot-instructions.md
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* feat: redesign Dashboard layout with search and recently used tools
- Add search input at top to filter tools by name/description
- Add 'recently used' section showing last 3 used tools as compact chips
- Add 'all tools' section header for the tool card grid
- Track tool usage via new 'app/recentlyUsedTools' storage key
- Update navigateTo to record recently used tools (max 3, LRU order)
- Add i18n keys: dashboard_searchPlaceholder, dashboard_recentlyUsed, dashboard_allTools
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* feat: replace ToolCard grid with compact icon+name grid on Dashboard
- Replace large ToolCard layout with dense grid (3-6 columns responsive)
- Each item shows icon + tool name in a compact tile
- Hover highlights icon and text with smooth transitions
- Remove ToolCard import from Dashboard (component retained for reuse)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix: remove redundant search input from Dashboard (header already has one)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* feat: optimize TopBar search with Cmd+K shortcut and improved styling
- Add global Cmd/Ctrl+K keyboard shortcut to focus search input
- Show keyboard shortcut hint (⌘K) in search input when empty
- Improve input styling: rounded-lg, softer borders, focus transitions
- Improve dropdown: rounded-lg, larger shadow, better spacing
- Larger result icons (h-8 w-8) with rounded-lg containers
- Refined history section with uppercase label and muted icon
- Search icon fades in on focus via group-focus-within
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* feat: improve search history to show recently used tools with direct navigation
- Store feature keys (PageType) in history instead of translated labels
- Show icon + name + description in history items (same as search results)
- Click or Enter on history item navigates directly to the tool page
- Remove History icon import (no longer needed)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix: useI18n fallback for empty string translations from chrome.i18n
* refactor: 移除设置页面
- 删除 options 入口点目录及相关文件
- 移除 wxt.config.ts 中 options_ui 配置
- 移除 TopBar 组件中的设置按钮和 onOpenOptions prop
- 移除 popup/sidepanel App.tsx 中的 handleOpenOptions
- 移除相关测试中的设置页面引用
- 移除 messages.json 中设置相关翻译键
- 通过 lint、typecheck、test 验证
* docs: 更新文档,移除设置页面引用
- README.md: 移除 entrypoints/options/ 目录说明
- AGENTS.md: 更新项目结构描述,移除 options/ 入口点
* docs: add comprehensive page development standards (CODING_STANDARDS.md §11)
- 新增 §11 页面开发规范(10 个子节),覆盖目录结构分4级、入口组件命名统一为 Index、业务 Hook 内部结构顺序、常量/子组件/存储键/模式切换/布局约定等规范
- 新增 §11.9 页面开发检查清单(10 步逐项确认)
- 更新 AGENTS.md 和 copilot-instructions.md 同步引用新规范章节
- 修正 useLazyTranslation → useI18n 与实际代码保持一致
* refactor(pages): apply UI+Hook separation and unify component naming
- Dashboard, RightClickRestorer: rename page component to Index
- Jwt: extract useJwt.ts hook + JwtSection.tsx sub-component (127→76 lines)
- TextStatistics: extract useTextStatistics.ts hook (63→48 lines)
- JsonTools: extract useJsonTools.ts hook + constants.ts (199→109 lines)
- All pages now follow CODING_STANDARDS.md §11 pattern
* refactor(StorageCleaner): improve style consistency and checkbox alignment
- Group storage options, auto-refresh toggle, and clean button into unified card
- Remove card wrappers from StorageOptionsGrid and AutoRefreshToggle (now sections within parent card)
- Align OptionItem and Select All checkboxes with consistent px-3.5 padding
- Distinguish indeterminate vs checked checkbox states visually
- Standardize spacing (space-y-4), add select-none to page root
- Fix import path for StorageCleanerConfirm to relative ./
* fix(StorageCleaner, Base64Converter): fix layout padding and checkbox alignment
- StorageCleaner: add px-3.5 to grid container to prevent content sticking to border
- StorageCleaner: adjust select-all bar to pl-3.5 pr-7 for checkbox alignment with grid items
- Base64Converter: add px-2 to TextMode and Base64ConverterSection for consistent spacing
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* chore: add initial CLAUDE.md file with reference to @AGENT.md
* docs: add comprehensive visual style guide
Add VISUAL_STYLE_GUIDE.md to standardize UI development:
- Design principles and keywords
- Complete color system (CSS variables, semantic usage)
- Typography hierarchy and patterns
- Spacing, layout, and container specs
- Border radius and shadow system
- Component specs (Button, Input, Card, Dialog, etc.)
- Interaction and animation guidelines
- Dark mode implementation rules
- Tool color palette and assignment
- Code organization standards
- Anti-patterns checklist
- Quick reference appendix
Update .gitignore to allow tracking the style guide.
* docs(AGENTS): update i18n section to reflect chrome.i18n migration
- Replace react-i18next docs with chrome.i18n API documentation
- Update translation file paths from i18n/locales/ to public/_locales/
- Update test mock description for chromeI18n
- Remove references to useLazyTranslation, vendor-i18n chunk, and snackbar
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor(content): simplify content script structure
- Remove messageHandler.ts (6-line pass-through facade)
- Import contextMenuHandler directly from content.ts
- Replace local getI18nText() with shared getMessage() from utils/chromeI18n
Reduces content script files from 3 to 2 and eliminates i18n logic duplication.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor(RightClickRestorer): simplify setDomain logic
Replace nested if/try/catch with a single ternary expression.
isUnsupportedPage() already handles invalid URLs, so new URL() is safe here.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor(background): extract main world injection script
Move the 62-line inline main world injection function from background.ts
to a dedicated utils/rightClickInjection.ts file.
This separates the RightClickRestorer's DOM patching logic from the
service worker's message routing concerns.
- background.ts: -62 lines, now delegates to imported function
- utils/rightClickInjection.ts: new file with mainWorldInjectionScript()
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor(background): simplify RELOAD_TAB with setTimeout
Replace the 30-line chrome.alarms API implementation with a simple
setTimeout for delayed tab reloads.
Rationale: The only usage is a 1-second delay after storage cleaning.
Service workers don't go idle within 1 second, so alarms' persistence
benefit is unnecessary here.
- Removed: alarm naming, create/clear, listener register/unregister
- Added: 4-line setTimeout conditional
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor(storageCleaner): extract executeScript helpers
Extract two generic helpers to eliminate repetitive executeScript boilerplate:
- runScript<T>(): for size/query operations (5 functions)
- runCleanScript(): for cleanup operations (5 functions)
Also add CLEAN_OPTION_KEYS constant shared by formatCleaningResult
and isEmptyResult.
- 428 lines → 379 lines (-49 lines)
- Eliminates ~100 lines of duplicated try/catch/result parsing
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor(base64Converter): simplify utility functions
- Mark formatFileSize() as @deprecated, delegate to formatBytes
- Replace manual for-loop in base64ToBytes() with Uint8Array.from()
- Replace nested loops in sniffMimeFromBytes() with Array.every()
5 insertions(+), 23 deletions(-)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor: replace GlobalSnackbar with sonner toast
Remove the custom 373-line GlobalSnackbar component and its Provider/Hook
in favor of the already-installed sonner library.
Changes:
- Delete src/components/GlobalSnackbar.tsx (+ tests)
- Remove SnackbarProvider from popup/App.tsx and sidepanel/App.tsx
- Replace useSnackbar() calls with toast.success()/toast.error() in:
- ImageUploader.tsx
- useQrCode.ts
- ParsePanel.tsx
- LiveClock.tsx
- Update test mocks to use sonner instead of GlobalSnackbar
-554 lines, +43 lines (net -511 lines)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor(RouterContainer): remove unnecessary useMemo and hoist constant
- Replace useMemo with direct expression for animationClass
- Move entryPointType to module scope (value is fixed after mount)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor: remove unnecessary useMemo calls across components
Replace over-cached simple computations with direct expressions:
- popup/App.tsx: getEntryPointType() and routerConfig (values are stable)
- Dashboard/index.tsx: visibleSet, visibleFeatures, recentFeatures
(Set creation + array filter/map are cheaper than useMemo overhead)
- useTextStatistics.ts: getTextStats(text) (simple string processing)
- ThemeModeProvider.tsx: contextValue object (setMode is stable via useCallback)
-39 lines, +28 lines (net -11 lines)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor: unify formatBytes usage and simplify useContextMenuData
1. Remove formatSize/formatByteSize delegation functions:
- storageCleaner.ts:formatSize (was just formatBytes wrapper)
- textStatistics.ts:formatByteSize (was just formatBytes wrapper)
- Update all callers to import formatBytes directly from @/utils/format
2. Simplify useContextMenuData hook:
- Remove unnecessary useCallback wrapping
- Inline checkAndConsumeData logic directly in useEffect
- Eliminate callback->effect dependency cycle
-69 lines, +67 lines (net -2 lines, but removes 2 indirection layers)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor(storageCleaner): simplify architecture and improve type semantics
- Remove RELOAD_TAB message chain, use chrome.tabs.reload() directly
- Rename IndexedDB label to '站点存储' for accuracy
- Introduce StorageSizeInfo type to distinguish bytes vs count
- Rename totalSize to totalBytes for clarity
- Merge runCleanScript into runScript to reduce duplication
- Rename CleaningResult.success to overallSuccess to avoid confusion
- Remove unused domain state and setDomain call
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor: replace require with import for JSON module in vitest.setup.ts
* refactor: simplify Timestamp and RightClickRestorer
Timestamp:
- Extract shared utilities (msToUnit, dayjsFromTimestamp, ModeType)
- Remove unnecessary useCallback/useMemo/React.memo
- Remove extra info section (relative time, ISO 8601, UTC)
- Fix missing translation key timestamp_unitS
RightClickRestorer:
- Remove website badge (右键已解锁 overlay)
- Remove mouse penetration logic for media elements
- Remove unnecessary useCallback
- Remove redundant setIsLoading call
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* refactor(StorageCleanerConfirm.test.tsx): update IndexedDB label to Chinese translation
---------
Co-authored-by: Ubuntu <ubuntu@localhost.localdomain >
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
2026-05-29 23:00:21 +08:00
LingandRX
945780def8
Develop ( #55 )
...
feat: optimize dashboard/search UX and simplify extension architecture
Redesign Dashboard with compact tool grid and recently used tools
Improve TopBar search UX with Cmd/Ctrl+K shortcut and better history navigation
Reorganize project structure into src/
Migrate i18n from react-i18next to chrome.i18n
Remove runtime language switch and settings page
Remove HTML/Markdown conversion tools
Clean up unused code, dead animations, redundant comments, and imports
Improve component consistency with shadcn/ui patterns
Replace hardcoded strings/colors with i18n tokens and theme tokens
Add comprehensive project documentation and coding standards
Fix CI artifact upload workflow and multiple TypeScript/test issues
Includes various refactors, UI polish, i18n cleanup, CI improvements,
and maintenance updates across the codebase.
2026-05-28 22:39:25 +08:00
LingandRX
d4c29a1bf4
Develop ( #54 )
...
* fix(ci): fix release workflow artifact upload issue
- Split artifact upload into 3 separate steps (Chrome, Firefox, Source)
- Update download steps to match new artifact names
- Add if-no-files-found: error for better error handling
- Fix Node.js 20 compatibility issue with upload-artifact@v4 glob pattern
* docs: 更新 AGENTS.md,添加测试工具和翻译文件结构说明
* docs: 更新 AGENTS.md,完善 CI 步骤和存储键名格式说明
* fix: remove unnecessary animations from StorageCleaner page
- Remove entrance animations (animate-in, fade-in, zoom-in) from all components
- Remove scale effect (active:scale-[0.99]) from clean button
- Remove transition effects (transition-all, transition-colors) from OptionItem, StorageOptionsGrid, AutoRefreshToggle
- Remove bouncing animation from error icon
- Remove pulsing animation from warning banner
- Keep animate-spin on button loading spinner as functional indicator
* fix: remove unnecessary animations from RightClickRestorer page
* fix: remove all unnecessary animations from all pages
- Remove dead code animations (animate-in, fade-in, slide-in, zoom-in, shake) from tailwindcss-animate plugin (not installed)
- Remove decorative transition effects (transition-all, transition-colors) from all page components
- Remove scale effects (active:scale-95) from buttons
- Remove bounce animations (animate-bounce) from icons
- Keep functional animate-spin on loading spinners as they provide essential loading feedback
Affected pages: Dashboard, Timestamp, Jwt, JsonTools, Base64Converter, HtmlToMarkdown, MarkdownToHtml, QrCode, TextStatistics
* docs: 添加项目文档(copilot-instructions、编码规范、各目录 README)
- 新增 .github/copilot-instructions.md:Copilot 指令文件,涵盖构建命令、CI 流水线、项目架构、关键规范
- 新增 .github/CODING_STANDARDS.md:完整的代码编写规范文档(TypeScript、React、样式、错误处理、命名、测试、Hook、i18n、存储等 12 个章节)
- 新增 11 个目录的 README.md:components、components/ui、config、entrypoints、i18n、lib、pages、providers、public、src、types、utils
- 更新 AGENTS.md:补充页面组件模式说明和 components/ui 目录
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(CopyButton): use shadcn buttonVariants instead of duplicated variant classes
Remove hand-written variantClasses/sizeClasses that duplicated shadcn's
buttonVariants. Now extends ButtonProps and imports buttonVariants from
components/ui/button for consistent styling.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(ErrorBoundary): use shadcn destructive tokens instead of hardcoded red colors
Replace hardcoded red-200/red-50/red-600 with border-destructive,
bg-destructive/5, text-destructive. Use variant='destructive' on
Button. Align error log styling with PageErrorBoundary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(TextInputArea): replace hardcoded Chinese strings with i18n t() calls
Use existing translation keys for clear success, copy success, and
copy error messages instead of hardcoded Chinese text.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(QrCodePreview): use shadcn Button instead of manual button styles
Replace hand-written button class strings with shadcn Button component
using outline and default variants. Removes ~15 lines of duplicated
Tailwind classes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* docs(GlobalSnackbar): clarify relationship with sonner toast
Add note explaining when to use GlobalSnackbar (provider context,
severity levels, custom positioning) vs sonner toast (simple one-off
messages).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(ImageUploader): wrap handleClearFile with useCallback
Prevents unnecessary re-renders by memoizing the callback, consistent
with handleFileChange which already uses useCallback.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(SwitchButtonGroup): remove redundant containerPadding conditional
Both branches of the ternary returned 'p-1'. Inline the constant
directly into the className string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(TopBar): add missing openExtensionPage import
The function was called in handleOpenInTab but never imported from
utils/chromeTabs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(TopBar): add selectedIndex boundary protection in keyboard nav
Guard against out-of-bounds access when search results change during
keyboard navigation. Check selectedIndex < totalItems before accessing
arrays.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(RouterContainer): remove unnecessary empty-dep useMemo
getEntryPointType() is a simple config getter. Replace useMemo(() => ..., [])
with a direct call — the empty dep array made the memo pointless.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* feat(i18n): add missing translation keys for error boundaries and copy messages
Add keys for errorBoundary, pageErrorBoundary, router, and
messages.copyEmpty in both zh and en locales.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(CopyButton): replace hardcoded Chinese strings with i18n t() calls
Use useTranslation('common') for tooltip, copy empty/success/error
toast messages.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(ErrorBoundary): replace hardcoded Chinese with i18n via withTranslation HOC
Use react-i18next withTranslation HOC for class component to translate
title, description, and refresh button text.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(PageErrorBoundary): replace hardcoded Chinese with i18n via withTranslation HOC
Use react-i18next withTranslation HOC for class component to translate
title, description, and retry button text.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(RouterContainer): replace hardcoded Chinese with i18n t() calls
Use useTranslation('common') for 404 page title and description with
entryPointType interpolation.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(pages): 修复 TypeScript 错误、硬编码字符串,移除死代码
- 修复 LiveClock.tsx CopyButton size 属性类型错误 (small → sm)
- 修复 ToolCard.tsx 紫色 RGB 值拼写错误 (147,51,2 purple → 147,51,232)
- 替换 4 处硬编码中文为 i18n 调用 (StorageCleaner, JsonTools)
- MarkdownToHtml 预览链接色改为 CSS 变量以支持暗黑模式
- 移除 Base64Converter 中已被 Base64ConverterSection 替代的死代码
(FileMode.tsx, ImageMode.tsx 及其测试文件)
- 更新 README.md 移除对已删除文件的引用
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
* fix(CopyButton, LiveClock): 修改按钮大小为 'icon',移除硬编码颜色配置
* refactor(TextInputArea): 复用 CopyButton 组件替换内联复制逻辑
* fix(test): 修复 CopyButton mock 未捕获 clipboard writeText 异常
---------
Co-authored-by: Ubuntu <ubuntu@localhost.localdomain >
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
2026-05-28 00:40:54 +08:00
LingandRX
efbed7cf53
feat: Tailwind CSS/shadcn/ui 迁移 & 右键菜单功能 ( #42 )
...
* feat: 添加 contextMenus 权限和消息类型定义
* feat: 实现右键菜单注册与点击分流逻辑
- 新增 utils/contextMenu.ts 封装菜单配置和解析函数
- 在 background.ts 监听 onInstalled 初始化菜单
- 实现 contextMenus.onClicked 点击事件处理
- 分流逻辑:优先发送到侧边栏,否则打开 options 页面
- 添加 contextMenu 单元测试(15个测试用例)
- 更新 vitest.setup.ts 添加 contextMenus mock
* feat: 实现 Content Script 原位轻量提示 UI
- 新增 uiPopover.ts 实现原位弹窗组件(深色主题、自动定位、自动隐藏)
- 新增 contextMenuHandler.ts 处理右键菜单消息
- 时间戳转换:在点击位置显示转换结果
- 文本统计:显示字符/单词/行数/字节统计
- 更新 messageHandler.ts 挂载右键菜单消息监听
* feat: 实现 React 页面层右键菜单数据联动
- 新增 useContextMenuData Hook 处理右键菜单数据传递
- 重构 Jwt/Base64Converter/TextStatistics/QrCode 页面接收右键数据
- RouterProvider 支持从 URL 参数解析右键菜单数据
- 添加 contextMenu/pendingData 存储键到 StorageSchema
- 添加 useContextMenuData 单元测试(12个测试用例)
* test: 添加 background 单元测试与边界情况处理
- 新增 entrypoints/__tests__/background.test.ts (12个测试用例)
- 超长文本截断限制 (>10000字符)
- Base64 内联图片拦截并返回错误提示
- 更新 parseContextMenuClick 返回 ParseResult 格式
- 更新测试匹配新的返回格式
- lint/typecheck/test 全部通过 (579个测试)
* fix: 修复右键菜单跳转到错误页面的问题
- 将 options 页面路径从 '/entrypoints/options/index.html' 修正为 '/options.html'
- WXT 构建后 entrypoints/options/index.html 会输出为根目录的 options.html
* fix: 修复右键菜单跳转目标为 popup 页面
- 将 fallback 页面从 options.html 改为 popup.html
- popup 页面使用 RouterProvider,可以正确处理 URL 参数并跳转到对应功能页面
- options 页面是独立设置页,不支持 URL 参数路由
* fix: 使用 openPopup() 替代 tabs.create() 打开弹窗
- background.ts: 使用 browser.action.openPopup() 打开 popup 弹窗
- 先保存数据到 storage,然后打开 popup
- RouterProvider.tsx: 初始化时检查 storage 中的 pendingData 并跳转到对应页面
- 移除之前错误的 tabs.create() 方式
* fix: 修复右键菜单数据未传递到目标页面的问题
- RouterProvider 不再提前清除 pendingData
- 让目标页面的 useContextMenuData 来消费和清除数据
- 这样确保 TextStatistics 等页面能正确接收选中的文本
* fix: 修复 popup 已打开时右键菜单不生效的问题
- 在 RouterProvider 中添加对 contextMenu/pendingData 的 storage 变化监听
- 当 pendingData 变化时,自动跳转到对应功能页面
- 解决了 openPopup() 只聚焦已有窗口而不触发重新挂载的问题
* feat: 支持右键菜单图片二维码识别
- 在 qrCodeParser.ts 中添加 parseQrCodeFromUrl 函数,支持从图片 URL 解析二维码
- 在 QrCodeToUrlSection 中使用 useContextMenuData 接收右键菜单传递的图片 URL
- 自动下载图片并解析二维码,显示解析结果
* refactor: 暂时移除图片二维码识别功能
- 删除 qrCode-image 右键菜单配置
- 删除 parseQrCodeFromUrl 函数
- 删除 QrCodeToUrlSection 中的 useContextMenuData 相关代码
- 更新相关测试用例
* feat: 支持右键菜单时间戳转换
- 在 useTimestampConverter 中添加 useContextMenuData hook
- 智能识别输入是时间戳还是日期时间字符串
- 自动切换到对应模式并执行转换
- 时间戳自动识别秒/毫秒单位
* fix: 修复右键菜单功能的多个逻辑漏洞
1. 修复时区硬编码问题 - 使用用户选择的时区而非固定 Asia/Shanghai
2. 修复 openPopup() 失败后数据残留 - 失败时清除 storage 中的待处理数据
3. 统一数据过期时间常量 - 导出 CONTEXT_MENU_DATA_EXPIRY_MS 并统一使用
4. 修复 featureKey 类型断言不安全 - 使用映射表处理非常规菜单 ID
* refactor(qrcode): 提取独立组件并添加单元测试
- 创建 pages/QrCode/types.ts 定义状态类型接口
- 提取 QrCodePreview 组件用于二维码预览和操作
- 提取 ImageUploader 组件封装图片上传、拖拽、粘贴逻辑
- 重构 UrlToQrCodeSection 状态提升到父组件
- 重构 QrCodeToUrlSection 通过回调传递解析结果
- 更新主页面 index.tsx 集中管理所有状态
- 为 QrCodePreview 和 ImageUploader 添加单元测试 (23 个用例)
* refactor(qrcode): 引入通用组件并重构双栏布局
- 引入 SwitchButtonGroup 用于模式切换
- 引入 TextInputArea 用于文本输入和结果展示
- 使用 MUI Grid 构建响应式双栏布局
- 实现 generate/parse 模式下的左右面板内容切换
- 修复 iconColor 颜色格式错误,使用 qrCodePageStyles.primaryColor
* refactor(qrcode): 国际化补充、质量保障与错误处理优化
- 补充 i18n 翻译键(generateMode, parseMode, pasteHint 等)
- 创建 useDebounce Hook 实现输入防抖 (200ms)
- 使用 useRef 解决 useEffect 无限循环问题
- 编写 pages/QrCode 单元测试 (7 个用例)
- 优化右键菜单错误处理,改进用户提示
- 运行 603 个测试全部通过
* refactor(qrcode): 组件化重构,采用 Context + Hook 模式
- 创建 QrCodeContext 和 QrCodeProvider 管理共享状态
- 提取 useQrCode Hook 封装所有状态和业务逻辑
- 创建 GeneratePanel 组件处理二维码生成模式
- 创建 ParsePanel 组件处理二维码解析模式
- 简化 index.tsx 为容器组件 (340行 → 47行)
- 删除未使用的旧组件文件 (QrCodeToUrlSection, UrlToQrCodeSection)
- 清理 types.ts 中未使用的类型定义
- 603 个测试全部通过
* fix(qrcode): 固定二维码预览图片尺寸,避免布局抖动
- 设置 QR_PREVIEW_IMAGE 固定尺寸 250x250
- 与 QRious 生成的二维码大小保持一致
- 解决输入内容变化时预览窗口大小跳动问题
* fix(qrcode): 修复切换 tab 后二维码图片失效问题
- 移除 ImageUploader 组件卸载时的预览 URL 释放逻辑
- 在 useQrCode hook 中统一管理预览 URL 生命周期
- 创建新预览 URL 前释放旧的,避免内存泄漏
* fix(qrcode): 固定图片上传区域高度,避免布局抖动
- 将 DROPZONE 的 minHeight: 200 改为 height: 250
- 与二维码预览图片高度保持一致
- 解决上传图片时 div 高度变化问题
* refactor(qrCode): 优化二维码解析功能
- 将'二维码转 URL'改为'二维码转文本'
- 将解析结果的文本预览框的 placeholder 置为空
- 去除手动解析二维码功能,只保留自动解析
* fix(pageHeader): 使用 MUI 主题色替代硬编码颜色,支持暗色模式
* feat(pageHeader): popup 模式下隐藏 PageHeader 组件
* fix(i18n): 统一使用 useLazyTranslation 避免翻译 key 闪烁
* perf: 配置 manualChunks 拆分 vendor chunk,优化打包体积
- 使用 Vite 插件 manualChunksForHtmlOnly 仅对 HTML 多入口构建生效
- 跳过 background/content-script 的 IIFE 构建(不支持 manualChunks)
- 拆分 vendor-react (193KB)、vendor-mui (326KB)、vendor-i18n (55KB)
- 按需加载 vendor-qr (78KB)、vendor-dnd (45KB)、vendor-markdown (41KB)
- PageErrorBoundary chunk 从 454KB 降至 36KB
* chore: upgrade wxt to v0.20.26 and @wxt-dev/module-react to v1.2.2
* chore: upgrade low-risk dependencies
- react: 19.2.3 → 19.2.6
- react-dom: 19.2.3 → 19.2.6
- dayjs: 1.11.19 → 1.11.20
- marked: 18.0.3 → 18.0.4
- prettier: 3.8.1 → 3.8.3
- terser: 5.46.0 → 5.47.1
- i18next: 26.0.8 → 26.2.0
- react-i18next: 17.0.6 → 17.0.8
- globals: 17.2.0 → 17.6.0
- eslint-plugin-react-hooks: 7.0.1 → 7.1.1
- @typescript-eslint/*: 8.54.0 → 8.59.4
- typescript-eslint: 8.54.0 → 8.59.4
- @testing-library/jest-dom: 6.6.0 → 6.9.1
- @testing-library/react: 16.0.0 → 16.3.2
- @testing-library/user-event: 14.5.2 → 14.6.1
- @testing-library/dom: added as peer dependency
- @types/react: 19.2.7 → 19.2.15
- @types/chrome: 0.1.36 → 0.1.42
- @types/webextension-polyfill: 0.12.4 → 0.12.5
* chore: upgrade medium-risk dependencies
- lint-staged: 16.2.7 → 17.0.5
- jsdom: 25.0.0 → 29.1.1
- @vitejs/plugin-react: 4.3.4 → 6.0.2
- vitest: 2.0.0 → 4.1.7
- @vitest/coverage-v8: upgraded to match vitest
- @webext-core/messaging: 2.3.0 → 3.0.1
- eslint: 9.39.2 → 10.4.0
- @eslint/js: added as new dependency
- @types/marked: removed (marked now provides its own types)
Fixes:
- Fix ref update during render in useQrCode.ts
- Fix ref update during render in useStorageCleaner.ts
- Add error cause in jwt.ts decode function
- Add type assertion for mock functions in htmlToMarkdown.test.ts
* chore(deps): 降级 eslint 版本并移除 @eslint/js
* docs: 精简 AGENTS.md,聚焦高信号信息
* test: 修复测试中的 act() 警告和 clipboard mock 问题
- TextInputArea: 使用 userEvent 替代 fireEvent,用 vi.spyOn 替代 Object.assign mock clipboard
- ImageMode/FileMode: 添加 waitForStorageReady() 等待 useStorageState 异步初始化
* perf: 优化首屏加载,快照有效时跳过骨架屏
- isLoaded 初始值根据 localStorage 快照是否存在决定
- 后续访问直接渲染真实 DOM,无需等待 chrome.storage 异步加载
- loadInitialData 仍在后台静默执行确保数据同步
* 引入 Tailwind CSS 和 shadcn/ui
* 替换 Timestamp 页面图标为 lucide-react 的 Clock 图标
* 用 Tailwind CSS 重写 Timestamp 页面的 MUI 基础排版组件
* 用 Tailwind CSS 重构 ResultView 和 LiveClock 组件
* 用 Tailwind CSS 重写 Dashboard/index.tsx 和 ToolCard.tsx
* 用 Tailwind CSS 重写 TextStatistics 页面
* 用 Tailwind CSS 重写 Base64Converter 页面
* 用 Tailwind CSS 重写 QrCode 页面及相关组件
* 用 Tailwind CSS 重写 Jwt 页面
* 用 Tailwind CSS 重写 StorageCleaner 页面,创建 shadcn/ui Dialog 组件
* 用 Tailwind CSS 重写 JsonTools 页面
* 用 Tailwind CSS 重构所有共享组件
* 修复 TypeScript 类型错误:将 MUI sx 语法改成标准 CSS 属性
* 重写基础骨架组件:用纯 Tailwind CSS 替换 MUI Box 组件
* 重写所有页面和组件:用纯 Tailwind CSS 替换 MUI 组件和图标
* 移除 MUI 依赖,简化配置文件,重写 ThemeModeProvider
* 移除 wxt.config.ts 中残留的 MUI chunk 配置
* 为 Dialog 组件添加暗黑模式背景色支持
* fix: 修复暗黑模式样式兼容性
- 在 tailwind.config.js 中启用 darkMode: 'class' 并扩展语义化颜色变量
- 将全项目硬编码颜色(bg-white、text-gray-*、border-gray-* 等)替换为语义化类名
- 修复 popup/index.html 硬编码浅色背景色
- 同步更新相关单元测试中的类名断言
* fix: 修复输入框和按钮在暗色模式下的样式问题
- 为 :root 和 .dark 添加 color-scheme,使浏览器表单控件默认样式适配暗色模式
- 将 bg-primary 搭配 text-white 的按钮改为 text-primary-foreground
- 替换残留的 hover:bg-blue-700、text-blue-500、bg-gray-200 等硬编码颜色
- 同步更新 TextInputArea 单元测试
* fix: 增强 SwitchButtonGroup 和立即转换按钮的视觉层级
- SwitchButtonGroup 选中按钮阴影从 shadow-sm 升级到 shadow-md
- 同步更新单元测试中断言
- Timestamp 立即转换按钮添加 shadow-md 增强边界感
* style: 隐藏所有窗口的滚动条
- 在全局 CSS 中为 html 添加 scrollbar-width: none(Firefox)
- 添加 ::-webkit-scrollbar { display: none }(Chrome/Safari/Opera)
* feat: add sonner dependency for toast notifications
* refactor: remove DomainHeader component and its usage
* refactor: 使用 className 替换 sx/buttonSx 并优化 SwitchButtonGroup 选中动画
* refactor: 简化 TextInputArea,移除 showMessage 和 MUI 样式,改用 shadcn 样式和 sonner toast
* refactor: 简化 TextInputArea,移除 showMessage 和 MUI 样式,改用 shadcn 样式和 sonner toast
* refactor: 重构 QrCodePreview 组件,继承 HTMLDiv 属性并统一 shadcn 样式
- 组件改为继承 `React.HTMLAttributes<HTMLDivElement>`,支持外部传入 className 和事件
- 使用 `cn()` 函数合并外部类名
- 空白状态改用 `border border-dashed` 和更浅的 `bg-muted/40` 背景
- 正常状态改为纯白背景柔边圆角容器包裹二维码,确保暗黑模式下黑白对比度
- 下载/复制按钮完全对齐 shadcn 的 Outline 与 Default 样式规范
- 更新测试用例中的 alt 文本为 "QR Code Preview"
* refactor: 将 PageHeader 组件样式从 MUI sx 迁移至 Tailwind 类名,并更新测试
* refactor: 更新PageErrorBoundary的文案和样式以对齐shadcn主题
- 错误提示从“该页面加载失败”改为“该功能运行异常”
- 重试按钮文字从“重试”改为“重新尝试”
- 使用border-destructive, bg-destructive等语义化类名替换硬编码颜色
- 更新对应测试断言
* refactor: 重构 CopyButton 与 RouterContainer 组件,移除 GlobalSnackbar 并统一使用 sonner toast 和 cn 工具函数
* refactor: 移除 MUI sx 样式和未使用的 GlobalSnackbar 引用
* feat: add @radix-ui/react-select dependency
* feat: add Input and Select shadcn UI components
* refactor: 重构 Timestamp 页面使用响应式 Hook 统一状态并全面迁移至 shadcn 样式
* refactor: 将 TextStatistics 页面和 TextInputArea 组件全面迁移至 shadcn 样式并优化布局
* feat: add Badge, Checkbox, Label, and Switch shadcn UI components
* refactor: 全面迁移 StorageCleaner 页面至 shadcn 样式并移除 GlobalSnackbar 依赖
* refactor: 全面重构 JsonTools 页面,采用声明式响应架构并统一 shadcn 样式
* refactor: 全面重构 Jwt 页面,采用防抖输入并统一 shadcn 样式
* refactor: 重构 Dashboard 页面和 ToolCard 组件,全面迁移至 shadcn 样式并优化布局
* refactor: 重构 HtmlToMarkdown 和 MarkdownToHtml 页面,统一 shadcn 样式并优化打印与暗色模式
* refactor: 抽离 useBase64Converter hook 并新增 Base64ConverterSection 组件,统一 Base64 转换页面的 shadcn 样式
* refactor: 重构 QrCode 页面为声明式响应架构并统一 shadcn 样式
* refactor: 优化 Dashboard 布局及 ToolCard 描述文本截断处理
* refactor: 优化 MarkdownToHtml 预览样式,剥离 CSS 变量回退值并增强 iframe 暗色模式自适应
* refactor: 优化 Popover 安全性和交互体验,修复 Context Menu 数据持久化问题并添加 i18n 支持
* refactor: strengthen i18n type safety and fix async Promise handling in language detection
* refactor: extend vitest setup with full chrome/browser mocks and i18n utility mock
* refactor: migrate storage listeners to wxt/browser and refactor provider state management
* refactor: restructure CI/CD pipelines with cached dependencies, separate setup job, and multi-browser builds
* refactor: remove tsc check from lint-staged and reorder lint commands
* refactor: migrate eslint config to tseslint.config with projectService and upgrade React rules
* refactor: use __MSG_ placeholders for i18n and remove postcss config
* refactor: replace __MSG_ placeholders with static strings for extension name and description
* refactor: add React version detection and disable prop-types in eslint; refactor lazy translation tests with proper mock isolation and Chrome/browser stubs
* refactor: use regex matchers in StorageCleanerConfirm tests and add chrome/browser mocks
* refactor: use regex matchers for i18n text and add uniform mocks in test files
* ci: add wxt prepare step to generate .wxt types for typecheck and tests
---------
Co-authored-by: Ubuntu <ubuntu@localhost.localdomain >
2026-05-23 00:02:43 +08:00