统一简化多个页面里的CopyButton调用,删除不再需要的空回调参数

* feat: 添加clearCookies函数的单元测试并修复cookie域名处理逻辑

* feat: 增强 data URI 处理,支持带参数的前缀并更新相关测试

* fix: 修正 AGENTS.md 中 TypeScript 类型检查命令的描述

* feat: 添加 settings.local.json 文件以配置 Bash 权限

* perf: 预设背景色避免 Popup 弹窗白屏闪烁

* perf: 避免图标过早实例化,传递组件引用而非 JSX 节点

* feat: 添加 useLazyTranslation 和 preloadNamespaces 函数以支持动态加载 i18n 命名空间

* feat: 使用 useLazyTranslation 替换 useTranslation 以支持懒加载翻译

* feat: 添加 PageSkeleton 组件及其测试用例以支持页面加载骨架屏

* feat: 使用骨架屏替换加载状态指示器,优化用户体验

* feat: 优化 CopyButton 组件的复制功能,添加定时器管理复制状态

* feat: 调整 chunk 大小警告阈值以优化构建性能
This commit is contained in:
LingandRX
2026-05-20 20:07:44 +08:00
committed by GitHub
parent 7167a43763
commit 373fc0496c
24 changed files with 535 additions and 153 deletions
+2 -2
View File
@@ -2,7 +2,7 @@ import { Box, Container, Stack } from '@mui/material';
import TextFieldsIcon from '@mui/icons-material/TextFields';
import UploadFileIcon from '@mui/icons-material/UploadFile';
import ImageIcon from '@mui/icons-material/Image';
import { useTranslation } from 'react-i18next';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
import PageHeader from '@/components/PageHeader';
import { base64ConverterPageStyles } from '@/config/pageTheme';
import { useStorageState } from '@/utils/useStorageState';
@@ -20,7 +20,7 @@ const isValidPageMode = (val: unknown): val is Base64ConverterPageMode =>
type PageMode = Base64ConverterPageMode;
export default function Index() {
const { t } = useTranslation(['base64Converter']);
const { t } = useLazyTranslation('base64Converter');
const [pageMode, setPageMode] = useStorageState(
'base64Converter/pageMode',
'text',
+6 -5
View File
@@ -6,7 +6,8 @@
*/
import { alpha, Box, Card, CardActionArea, Stack, Typography, useTheme } from '@mui/material';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import React from 'react';
import type { SvgIconProps } from '@mui/material/SvgIcon';
import type { ComponentType } from 'react';
import type { PaletteColorKey } from '@/config/features';
/**
@@ -21,8 +22,8 @@ interface ToolCardProps {
snapshot?: React.ReactNode;
/** 主题色键,映射到 theme.palette[key].main */
colorKey: PaletteColorKey;
/** 工具图标元素 */
icon: React.ReactNode;
/** 图标组件引用 */
icon: ComponentType<SvgIconProps>;
/** 卡片点击事件处理函数 */
onClick: () => void;
}
@@ -38,7 +39,7 @@ export default function ToolCard({
description,
snapshot,
colorKey,
icon,
icon: IconComponent,
onClick,
}: ToolCardProps) {
const theme = useTheme();
@@ -93,7 +94,7 @@ export default function ToolCard({
color: colorCode,
}}
>
{icon}
<IconComponent sx={{ fontSize: 20 }} />
</Box>
<Box>
<Typography
+2 -2
View File
@@ -13,7 +13,7 @@ import {
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
import DownloadIcon from '@mui/icons-material/Download';
import CodeIcon from '@mui/icons-material/Code';
import { useTranslation } from 'react-i18next';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
import PageHeader from '@/components/PageHeader';
import CopyButton from '@/components/CopyButton';
import SwitchButtonGroup from '@/components/SwitchButtonGroup';
@@ -25,7 +25,7 @@ const isValidPreviewMode = (val: unknown): val is HtmlToMarkdownPreviewMode =>
typeof val === 'string' && ['split', 'preview', 'markdown'].includes(val);
export default function HtmlToMarkdownPage() {
const { t } = useTranslation('htmlToMarkdown');
const { t } = useLazyTranslation('htmlToMarkdown');
const [previewMode, setPreviewMode] = useStorageState(
'htmlToMarkdown/previewMode',
'split' as HtmlToMarkdownPreviewMode,
+2 -2
View File
@@ -4,7 +4,7 @@ import CompareArrowsIcon from '@mui/icons-material/CompareArrows';
import DataObjectIcon from '@mui/icons-material/DataObject';
import TransformIcon from '@mui/icons-material/Transform';
import CompressIcon from '@mui/icons-material/Compress';
import { useTranslation } from 'react-i18next';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
import PageHeader from '@/components/PageHeader';
import { jsonDiffPageStyles } from '@/config/pageTheme';
import JsonDiffInput from './JsonDiffInput';
@@ -46,7 +46,7 @@ const isValidPageMode = (val: unknown): val is JsonToolsPageMode =>
type PageMode = JsonToolsPageMode;
export default function Index() {
const { t } = useTranslation(['jsonDiff', 'jsonFormat']);
const { t } = useLazyTranslation(['jsonDiff', 'jsonFormat']);
const [pageMode, setPageMode] = useStorageState('jsonTools/pageMode', 'diff', isValidPageMode);
const [leftInput, setLeftInput] = useState('');
const [rightInput, setRightInput] = useState('');
+3 -3
View File
@@ -6,7 +6,7 @@ import PageHeader from '@/components/PageHeader';
import { stringifyJson, parseJwt } from '@/utils/jwt';
import CopyButton from '@/components/CopyButton';
import TextInputArea from '@/components/TextInputArea';
import { useTranslation } from 'react-i18next';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
interface SectionProps {
title: string;
@@ -15,7 +15,7 @@ interface SectionProps {
}
const Section = ({ title, content, color }: SectionProps) => {
const { t } = useTranslation(['jwt']);
const { t } = useLazyTranslation('jwt');
return (
<Paper
variant="outlined"
@@ -58,7 +58,7 @@ const Section = ({ title, content, color }: SectionProps) => {
export default function Index() {
const { showMessage } = useSnackbar();
const { t } = useTranslation(['jwt']);
const { t } = useLazyTranslation('jwt');
const [jwtInput, setJwtInput] = useState('');
const result = useMemo(() => {
+2 -2
View File
@@ -14,7 +14,7 @@ import CodeIcon from '@mui/icons-material/Code';
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
import PrintIcon from '@mui/icons-material/Print';
import DownloadIcon from '@mui/icons-material/Download';
import { useTranslation } from 'react-i18next';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
import PageHeader from '@/components/PageHeader';
import CopyButton from '@/components/CopyButton';
import SwitchButtonGroup from '@/components/SwitchButtonGroup';
@@ -109,7 +109,7 @@ const PREVIEW_STYLES = `
`;
export default function MarkdownToHtmlPage() {
const { t } = useTranslation('markdownToHtml');
const { t } = useLazyTranslation('markdownToHtml');
const [previewMode, setPreviewMode] = useStorageState(
'markdownToHtml/previewMode',
'split' as MarkdownToHtmlPreviewMode,
+2 -2
View File
@@ -5,10 +5,10 @@ import QrCodeToUrlSection from '@/pages/QrCode/QrCodeToUrlSection';
import { useStorageState } from '@/utils/useStorageState';
import { qrCodePageStyles } from '@/config/pageTheme';
import PageHeader from '@/components/PageHeader';
import { useTranslation } from 'react-i18next';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
export default function Index() {
const { t } = useTranslation(['qrCode']);
const { t } = useLazyTranslation('qrCode');
const theme = useTheme();
const isDesktop = useMediaQuery(theme.breakpoints.up('md'));
+2 -2
View File
@@ -9,11 +9,11 @@ import StorageOptionsGrid from './StorageOptionsGrid';
import AutoRefreshToggle from './AutoRefreshToggle';
import ErrorDisplay from './ErrorDisplay';
import CleaningResult from './CleaningResult';
import { useTranslation } from 'react-i18next';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
export default function Index() {
const { showMessage } = useSnackbar();
const { t } = useTranslation(['storageCleaner']);
const { t } = useLazyTranslation('storageCleaner');
const {
domain,
error,
+2 -2
View File
@@ -5,7 +5,7 @@ import TextInputArea from '@/components/TextInputArea';
import DescriptionIcon from '@mui/icons-material/Description';
import { formatByteSize, getTextStats } from '@/utils/textStatistics';
import { textStatisticsPageStyles } from '@/config/pageTheme';
import { useTranslation } from 'react-i18next';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
/**
* 文本统计页面组件
@@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next';
* 提供实时的文本分析功能,包括字符数、单词数、行数和字节大小。
*/
export default function Index() {
const { t } = useTranslation(['textStatistics']);
const { t } = useLazyTranslation('textStatistics');
const [text, setText] = useState('');
// 实时计算统计信息,使用 useMemo 优化性能
+2 -2
View File
@@ -7,10 +7,10 @@ import { timestampPageStyles, ZONES } from '@/config/pageTheme';
import LiveClock from './LiveClock';
import ResultView from './ResultView';
import { useTimestampConverter } from './useTimestampConverter';
import { useTranslation } from 'react-i18next';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
export default function Index() {
const { t } = useTranslation(['timestamp']);
const { t } = useLazyTranslation('timestamp');
const {
mode,
tsInput,