refactor: 统一中文文案并简化组件结构,提升代码可读性
移除 chrome.i18n 后,将各功能页面、布局与工具模块的 UI 文案改为内联中文; 删除冗余注释与过度抽象(如 ToolCard、StatCard),精简 props 与状态管理; 同步优化 JsonTools、StorageCleaner、Timestamp、TestDataGenerator、Dashboard、 Base64Converter、RightClickRestorer、TextStatistics、TopBar、RouterProvider、 ThemeModeProvider 及生成器库与 utils 工具文件。
This commit is contained in:
@@ -40,12 +40,12 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
|
||||
decodedFileName,
|
||||
setCustomFileName,
|
||||
resetAll,
|
||||
safeFileSelect,
|
||||
handleFileSelect,
|
||||
maxFileSizeStr,
|
||||
} = useBase64Converter({ mode });
|
||||
|
||||
const handleDirectionChange = (next: Base64ConvertDirection) => {
|
||||
if (!next || next === direction) return;
|
||||
if (next === direction) return;
|
||||
resetAll();
|
||||
setDirection(next);
|
||||
};
|
||||
@@ -80,7 +80,7 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
|
||||
e.preventDefault();
|
||||
setIsDragging(false);
|
||||
const file = e.dataTransfer.files[0];
|
||||
if (file) safeFileSelect(file);
|
||||
if (file) void handleFileSelect(file);
|
||||
}}
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
className={cn(
|
||||
@@ -99,7 +99,7 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
|
||||
hidden
|
||||
onChange={(e) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (file) safeFileSelect(file);
|
||||
if (file) void handleFileSelect(file);
|
||||
}}
|
||||
/>
|
||||
{isLoading ? (
|
||||
@@ -123,7 +123,7 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
|
||||
{formatBytes(info.size)} · {info.type}
|
||||
</span>
|
||||
<span className="text-[11px] font-medium text-primary/80 mt-1">
|
||||
{'点击或拖拽以替换文件'}
|
||||
点击或拖拽以替换文件
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
@@ -158,17 +158,17 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
|
||||
<div className="p-4 rounded-2xl bg-card border border-border shadow-sm flex flex-col space-y-3">
|
||||
<div className="flex justify-between items-center select-none">
|
||||
<span className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground/90">
|
||||
{'Base64 编码结果'}
|
||||
Base64 编码结果
|
||||
</span>
|
||||
<div className="flex gap-2">
|
||||
<CopyButton
|
||||
text={result.rawBase64}
|
||||
tooltip={'复制纯 Base64'}
|
||||
tooltip="复制纯 Base64"
|
||||
className="h-6 px-2 rounded-md border text-[10px] font-bold"
|
||||
/>
|
||||
<CopyButton
|
||||
text={result.output}
|
||||
tooltip={'复制 Data URI'}
|
||||
tooltip="复制 Data URI"
|
||||
className="h-6 px-2 rounded-md border text-[10px] font-bold"
|
||||
/>
|
||||
</div>
|
||||
@@ -186,14 +186,14 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
|
||||
<div className="flex items-center justify-between font-mono text-[10px] text-muted-foreground/70 select-none pt-1">
|
||||
<div className="flex gap-4 items-center tabular-nums">
|
||||
<span>
|
||||
{'原始大小'}:{' '}
|
||||
原始大小:{' '}
|
||||
<span className="font-semibold text-foreground/80">
|
||||
{formatBytes(result.originalBytes)}
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-border/60">|</span>
|
||||
<span>
|
||||
{'编码大小'}:{' '}
|
||||
编码大小:{' '}
|
||||
<span className="font-semibold text-foreground/80">
|
||||
{formatBytes(result.outputBytes)}
|
||||
</span>
|
||||
@@ -206,7 +206,7 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
|
||||
className="h-7 rounded-md text-muted-foreground hover:text-destructive text-[11px] gap-1 px-2"
|
||||
>
|
||||
<Trash2 className="w-3.5 h-3.5" />
|
||||
{'清空'}
|
||||
清空
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -215,7 +215,7 @@ export default function Base64ConverterSection({ mode }: Base64ConverterSectionP
|
||||
) : (
|
||||
<div className="flex flex-col space-y-4">
|
||||
<TextInputArea
|
||||
placeholder={'输入需要解码的 Base64 或 data URI...'}
|
||||
placeholder="输入需要解码的 Base64 或 data URI..."
|
||||
value={decodeInput}
|
||||
onChange={setDecodeInput}
|
||||
externalError={decodeError || undefined}
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
/**
|
||||
* DecodeResultPaper
|
||||
*
|
||||
* FileMode 与 ImageMode 通用的 decode 结果展示组件。
|
||||
* 提取了二者 decode 输出区完全一致的结构:
|
||||
* 标题 → 可选预览(children)→ 文件信息 → 文件名输入 → 下载按钮
|
||||
*
|
||||
* FileMode 直接使用,ImageMode 通过 children 传入图片预览。
|
||||
*/
|
||||
import { Download } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
@@ -14,19 +5,12 @@ import { Label } from '@/components/ui/label';
|
||||
import { formatBytes } from '@/utils/format';
|
||||
|
||||
interface DecodeResultPaperProps {
|
||||
/** 标题文案 */
|
||||
title: string;
|
||||
/** 解码后推断的 MIME 类型 */
|
||||
mimeType: string;
|
||||
/** 解码后 Blob 的大小(字节) */
|
||||
blobSize: number;
|
||||
/** 当前文件名 */
|
||||
fileName: string;
|
||||
/** 文件名变更回调 */
|
||||
onFileNameChange: (name: string) => void;
|
||||
/** 下载按钮点击回调 */
|
||||
onDownload: () => void;
|
||||
/** 可选的预览内容,ImageMode 用于渲染图片预览 */
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
@@ -41,31 +25,20 @@ export default function DecodeResultPaper({
|
||||
}: DecodeResultPaperProps) {
|
||||
return (
|
||||
<div className="p-4 rounded-xl bg-primary/10 border border-primary/30">
|
||||
{/* 标题 */}
|
||||
<span className="block mb-2 text-xs font-bold text-muted-foreground">{title}</span>
|
||||
|
||||
{/* 可选预览内容(ImageMode 的图片) */}
|
||||
{children}
|
||||
|
||||
{/* 文件信息 */}
|
||||
<div className="flex gap-4 mb-3">
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{'推断的 MIME 类型'}: {mimeType}
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{'解码大小'}: {formatBytes(blobSize)}
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">推断的 MIME 类型: {mimeType}</span>
|
||||
<span className="text-xs text-muted-foreground">解码大小: {formatBytes(blobSize)}</span>
|
||||
</div>
|
||||
|
||||
{/* 文件名输入 */}
|
||||
<div className="mb-3">
|
||||
<Label className="block text-xs font-medium text-muted-foreground mb-1">
|
||||
{'解码后文件名'}
|
||||
</Label>
|
||||
<Label className="block text-xs font-medium text-muted-foreground mb-1">解码后文件名</Label>
|
||||
<Input value={fileName} onChange={(e) => onFileNameChange(e.target.value)} />
|
||||
</div>
|
||||
|
||||
{/* 下载按钮 */}
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={onDownload}
|
||||
@@ -73,7 +46,7 @@ export default function DecodeResultPaper({
|
||||
className="w-full rounded-lg font-bold"
|
||||
>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
{'下载'}
|
||||
下载
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -8,7 +8,7 @@ interface TextModeProps {
|
||||
onSwitchToImageMode?: () => void;
|
||||
}
|
||||
|
||||
export default function TextMode({ onSwitchToImageMode }: TextModeProps = {}) {
|
||||
export default function TextMode({ onSwitchToImageMode }: TextModeProps) {
|
||||
const {
|
||||
input,
|
||||
setInput,
|
||||
|
||||
Reference in New Issue
Block a user