Commit Graph

313 Commits

Author SHA1 Message Date
雨霖铃 1a92e88934 feat: 实现测试数据生成器完整功能
- 添加类型定义 (FieldConfig, DataRule, GeneratorDefinition 等)
- 实现 21 个数据生成器 (个人信息/业务数据/技术数据/基础类型)
- 实现 Web Worker 后台数据生成引擎
- 实现规则存储与管理功能
- 实现 JSON/CSV 数据导出功能
- 开发完整 UI 组件 (字段管理/生成器选择/数据预览/导出面板等)
- 集成到应用功能配置,添加国际化支持

功能特性:
- 实时预览生成的数据
- 字段配置 (名称/描述/必填/空值率/唯一性约束)
- 规则管理 (保存/加载/搜索/导入导出)
- Web Worker 后台生成,支持进度显示和取消
- 响应式布局,支持多种设备

docs: 更新 TASKS.md 所有子任务复选框为已完成状态
2026-06-06 09:29:12 +08:00
雨霖铃 2b84eda24f docs: 统一测试数据生成器文档,移除 SQL/TypeScript 导出,修复接口命名不一致
- 移除所有文档中的 SQL 和 TypeScript 导出格式引用
- 统一数据导出格式为 JSON 和 CSV
- 移除 GeneratorDefinition 中的 icon 字段
- 更新 generatorCategories 配置,包含所有 21 个生成器
- 统一 rule-management.md 和 technical-implementation.md 中的接口名称为 DataRule
- 更新 ui-design.md 中的界面设计,移除 SQL/TypeScript 相关元素
2026-06-06 09:04:53 +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
雨霖铃 ea0552e8aa feat: 替换项目图标为自定义 logo
- 替换 public/icon/ 目录下所有 PNG 图标文件为新 logo
- 删除 public/wxt.svg(不再需要)
- 在 wxt.config.ts 中添加 icons 和 default_icon 配置
- 更新 public/README.md 文档
2026-06-06 01:00:10 +08:00
雨霖铃 97098c3abe 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 00:55:05 +08:00
雨霖铃 7afce94d93 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 00:49:57 +08:00
雨霖铃 e2b76a5f86 feat: 替换项目图标为自定义 logo
- 替换 public/icon/ 目录下所有 PNG 图标文件为新 logo
- 删除 public/wxt.svg(不再需要)
- 在 wxt.config.ts 中添加 icons 和 default_icon 配置
- 更新 public/README.md 文档
2026-06-05 23:57:04 +08:00
雨霖铃 1ab79785b6 docs(AGENTS.md): 添加 Git Commit 必须使用中文描述的规范 2026-06-05 23:41:04 +08:00
雨霖铃 c40b66b703 docs: 更新测试数据生成器功能设计文档
主要更新:
- 添加字段必填/选填设置和空值率配置
- 移除标签管理系统(20条规则无需标签)
- 添加组合策略保证唯一性生成
- 添加价格生成器(真实分布/心理定价)
- 添加场景化生成器(年龄/数量/评分/折扣/库存)
- 更新所有文档移除emoji,使用纯文字
- 更新类型定义和生成逻辑
2026-06-05 23:40:36 +08:00
雨霖铃 f55fd4338d docs(AGENTS.md): 添加 Git Commit 必须使用中文描述的规范 2026-06-05 22:54:29 +08:00
雨霖铃 27c1cf37e3 chore: update .gitignore with common ignore patterns
- Add environment variable files (.env, .env.local, .env.*.local)
- Add build output directories (dist/, build/)
- Add test coverage directory (coverage/)
- Add IDE workspace files (*.code-workspace)
- Add TypeScript build info files (*.tsbuildinfo, *.tsxbuildinfo)
- Remove docs/* to track documentation files
2026-06-05 22:53:39 +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
LingandRX a0b1ade662 Merge branch 'main' into develop 2026-06-05 13:10:34 +08:00
雨霖铃 d964e27c9d fix(hooks): 用 merge-base 替代 rev-parse 修复 pre-push 变更文件检测 2026-06-05 13:02:30 +08:00
LingandRX 359326c6da Hotfix/contextmenu srcurl generating fix (#63)
* 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

* fix(hooks): pre-push 无 upstream 时回退到 origin/main 对比
2026-06-05 12:53:19 +08:00
雨霖铃 10644fae95 fix(hooks): pre-push 无 upstream 时回退到 origin/main 对比 2026-06-05 12:50:55 +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
LingandRX 0624b609be Merge pull request #62 from LingandRX/hotfix/remove-unused-alarms
hotfix: remove unused alarms permission
v1.0.6
2026-06-02 19:10:26 +08:00
Ubuntu f551428142 hotfix: remove unused alarms permission 2026-06-02 19:09:39 +08:00
LingandRX 1ae057ccfa Merge pull request #61 from LingandRX/hotfix/revert-version
hotfix: revert package.json version to 1.0.0
2026-06-02 14:59:34 +08:00
Ubuntu 400a1afb0c hotfix: revert package.json version to 1.0.0 2026-06-02 14:58:54 +08:00
LingandRX c6d0914d33 Merge pull request #60 from LingandRX/develop
fix: update _locales path in vitest.setup.ts
2026-06-02 14:38:05 +08:00
Ubuntu 7617e317f2 fix: update _locales path from zh to zh_CN in vitest.setup.ts 2026-06-02 14:35:56 +08:00
LingandRX 396b3d7013 Merge pull request #59 from LingandRX/develop
fix: correct default_locale to zh_CN
2026-06-02 14:18:20 +08:00
雨霖铃 92fb853329 fix: correct default_locale to zh_CN to match _locales directory 2026-06-02 14:16:33 +08:00
雨霖铃 e4e5464be0 chore(hooks): 优化 lint-staged 和 git hooks 配置
- lint-staged: 本地开发仅自动修复不阻塞,CI 环境严格检查
- pre-commit: 后台运行 tsc 类型检查,前台运行 lint-staged
- pre-push: 新增严格检查闸门(tsc + eslint --max-warnings=0)
2026-05-30 21:31:12 +08:00
LingandRX f4b6ae89b5 Merge pull request #58 from LingandRX/develop
chore: merge develop into main (v1.x.x)
2026-05-30 21:20:52 +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
雨霖铃 afd57bb5b2 Merge branch 'main' into develop 2026-05-30 19:47:16 +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
雨霖铃 355ab0cf86 Merge remote-tracking branch 'origin/main' into develop 2026-05-29 22:59:10 +08:00
雨霖铃 13113f0ea2 refactor(StorageCleanerConfirm.test.tsx): update IndexedDB label to Chinese translation 2026-05-29 22:42:59 +08:00
雨霖铃 0d69695dbb 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>
2026-05-29 22:40:11 +08:00
雨霖铃 093bf278da refactor: replace require with import for JSON module in vitest.setup.ts 2026-05-29 22:08:04 +08:00
雨霖铃 f9fbc79612 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>
2026-05-29 21:59:54 +08:00
雨霖铃 1b9f6d044d 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>
2026-05-29 21:08:27 +08:00
雨霖铃 b41cfb2a02 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>
2026-05-29 20:59:03 +08:00
雨霖铃 93019f56cf 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>
2026-05-29 20:55:05 +08:00
雨霖铃 2727e60025 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>
2026-05-29 20:47:16 +08:00