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.
This commit is contained in:
LingandRX
2026-05-28 22:39:25 +08:00
committed by GitHub
parent d4c29a1bf4
commit 945780def8
200 changed files with 1557 additions and 4380 deletions
+69
View File
@@ -0,0 +1,69 @@
import { formatBytes } from './format';
/**
* 文本统计信息接口
*/
export interface TextStats {
/** 字符数(包含空格和特殊字符) */
characters: number;
/** 单词数 */
words: number;
/** 行数 */
lines: number;
/** 字节大小 */
bytes: number;
}
/**
* 计算文本统计信息
*
* @param text 输入的文本内容
* @returns 统计结果对象
*/
export function getTextStats(text: string): TextStats {
if (!text) {
return { characters: 0, words: 0, lines: 0, bytes: 0 };
}
// 1. 字符数:统计总字符数量
const characters = text.length;
// 2. 单词数:使用 Intl.Segmenter 识别单词边界
// 这能很好地处理中英文混合文本。中文会按词组切分,英文按单词切分。
let words = 0;
try {
const segmenter = new Intl.Segmenter(undefined, { granularity: 'word' });
const segments = segmenter.segment(text);
for (const segment of segments) {
// isWordLike 为 true 表示该片段是“类词”的(非空格、非标点)
if (segment.isWordLike) {
words++;
}
}
} catch {
// 降级方案:如果不支持 Intl.Segmenter,使用正则匹配英文单词
// 但对中文支持较差
const englishWords = text.match(/\b\w+\b/g) || [];
const chineseChars = text.match(/[\u4e00-\u9fa5]/g) || [];
words = englishWords.length + chineseChars.length;
}
// 3. 行数:统计换行符数量
// 空字符串已在上方处理。非空文本至少有一行。
const lines = text.split('\n').length;
// 4. 字节大小:计算文本内容的字节数 (UTF-8)
const bytes = new TextEncoder().encode(text).length;
return { characters, words, lines, bytes };
}
/**
* 格式化字节大小显示(兼容旧接口,内部委托给 formatBytes
*
* @param bytes 字节数
* @returns 格式化后的字符串
*/
export function formatByteSize(bytes: number): string {
return formatBytes(bytes);
}