d38bafe237
移除 chrome.i18n 后,将各功能页面、布局与工具模块的 UI 文案改为内联中文; 删除冗余注释与过度抽象(如 ToolCard、StatCard),精简 props 与状态管理; 同步优化 JsonTools、StorageCleaner、Timestamp、TestDataGenerator、Dashboard、 Base64Converter、RightClickRestorer、TextStatistics、TopBar、RouterProvider、 ThemeModeProvider 及生成器库与 utils 工具文件。
128 lines
4.0 KiB
TypeScript
128 lines
4.0 KiB
TypeScript
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
import { useStorageState } from '@/utils/useStorageState';
|
|
import { diffJson } from '@/utils/diffEngine';
|
|
import { jsonToYaml } from '@/utils/jsonToYaml';
|
|
import { jsonToToml } from '@/utils/jsonToToml';
|
|
import { minifyJson } from '@/utils/jsonFormatter';
|
|
import { isValidPageMode, tryParse } from './constants';
|
|
import type { JsonToolsPageMode } from '@/types/storage';
|
|
import type { ConvertFunction, ViewMode } from './types';
|
|
|
|
export interface UseJsonToolsReturn {
|
|
pageMode: JsonToolsPageMode;
|
|
setPageMode: (mode: JsonToolsPageMode) => void;
|
|
leftInput: string;
|
|
rightInput: string;
|
|
setLeftInput: (val: string) => void;
|
|
setRightInput: (val: string) => void;
|
|
leftError: string | null;
|
|
rightError: string | null;
|
|
viewMode: ViewMode;
|
|
setViewMode: (mode: ViewMode) => void;
|
|
diffResult: ReturnType<typeof diffJson> | null;
|
|
total: number;
|
|
currentDiffIndex: number;
|
|
handlePrev: () => void;
|
|
handleNext: () => void;
|
|
activePath: string | undefined;
|
|
yamlConvert: ConvertFunction;
|
|
tomlConvert: ConvertFunction;
|
|
minifyConvert: ConvertFunction;
|
|
}
|
|
|
|
export function useJsonTools(): UseJsonToolsReturn {
|
|
const [pageMode, setPageMode] = useStorageState('jsonTools/pageMode', 'diff', isValidPageMode);
|
|
|
|
const [leftInput, setLeftInput] = useState('');
|
|
const [rightInput, setRightInput] = useState('');
|
|
const [debouncedLeft, setDebouncedLeft] = useState('');
|
|
const [debouncedRight, setDebouncedRight] = useState('');
|
|
|
|
useEffect(() => {
|
|
const handle = setTimeout(() => {
|
|
setDebouncedLeft(leftInput);
|
|
setDebouncedRight(rightInput);
|
|
}, 250);
|
|
return () => clearTimeout(handle);
|
|
}, [leftInput, rightInput]);
|
|
|
|
const parseState = useMemo(() => {
|
|
const invalidMsg = '无效的 JSON 格式';
|
|
return {
|
|
left: tryParse(debouncedLeft, invalidMsg),
|
|
right: tryParse(debouncedRight, invalidMsg),
|
|
};
|
|
}, [debouncedLeft, debouncedRight]);
|
|
|
|
const leftError = parseState.left.error;
|
|
const rightError = parseState.right.error;
|
|
|
|
const [viewMode, setViewMode] = useState<ViewMode>('sideBySide');
|
|
const [currentDiffIndex, setCurrentDiffIndex] = useState(0);
|
|
|
|
const diffResult = useMemo(() => {
|
|
const { left, right } = parseState;
|
|
if (left.error || right.error || debouncedLeft.trim() === '' || debouncedRight.trim() === '') {
|
|
return null;
|
|
}
|
|
return diffJson(left.value, right.value);
|
|
}, [parseState, debouncedLeft, debouncedRight]);
|
|
|
|
const total = diffResult?.diffPaths.length ?? 0;
|
|
|
|
const handlePrev = useCallback(() => {
|
|
if (total === 0) return;
|
|
setCurrentDiffIndex((idx) => (idx - 1 + total) % total);
|
|
}, [total]);
|
|
|
|
const handleNext = useCallback(() => {
|
|
if (total === 0) return;
|
|
setCurrentDiffIndex((idx) => (idx + 1) % total);
|
|
}, [total]);
|
|
|
|
const activePath = diffResult && total > 0 ? diffResult.diffPaths[currentDiffIndex] : undefined;
|
|
|
|
const yamlConvert: ConvertFunction = useCallback((text: string) => {
|
|
const r = jsonToYaml(text);
|
|
return { output: r.output, originalBytes: r.originalBytes, outputBytes: r.outputBytes };
|
|
}, []);
|
|
|
|
const tomlConvert: ConvertFunction = useCallback((text: string) => {
|
|
const r = jsonToToml(text);
|
|
return { output: r.output, originalBytes: r.originalBytes, outputBytes: r.outputBytes };
|
|
}, []);
|
|
|
|
const minifyConvert: ConvertFunction = useCallback((text: string) => {
|
|
const r = minifyJson(text);
|
|
return { output: r.minified, originalBytes: r.originalBytes, outputBytes: r.minifiedBytes };
|
|
}, []);
|
|
|
|
return {
|
|
pageMode,
|
|
setPageMode,
|
|
leftInput,
|
|
rightInput,
|
|
setLeftInput: (val: string) => {
|
|
setLeftInput(val);
|
|
setCurrentDiffIndex(0);
|
|
},
|
|
setRightInput: (val: string) => {
|
|
setRightInput(val);
|
|
setCurrentDiffIndex(0);
|
|
},
|
|
leftError,
|
|
rightError,
|
|
viewMode,
|
|
setViewMode,
|
|
diffResult,
|
|
total,
|
|
currentDiffIndex,
|
|
handlePrev,
|
|
handleNext,
|
|
activePath,
|
|
yamlConvert,
|
|
tomlConvert,
|
|
minifyConvert,
|
|
};
|
|
}
|