Files
testing-tool/src/pages/JsonTools/useJsonTools.ts
T
雨霖铃 d38bafe237 refactor: 统一中文文案并简化组件结构,提升代码可读性
移除 chrome.i18n 后,将各功能页面、布局与工具模块的 UI 文案改为内联中文;
删除冗余注释与过度抽象(如 ToolCard、StatCard),精简 props 与状态管理;
同步优化 JsonTools、StorageCleaner、Timestamp、TestDataGenerator、Dashboard、
Base64Converter、RightClickRestorer、TextStatistics、TopBar、RouterProvider、
ThemeModeProvider 及生成器库与 utils 工具文件。
2026-06-27 17:26:19 +08:00

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,
};
}