fix: 修复 ESLint 配置及组件弃用属性警告,优化代码格式

1. 工程配置:
- 更新 tsconfig.json include 规则,解决 eslint.config.ts 未被包含的问题。

2. 组件重构 (Material UI 适配):
- Navbar: 替换已弃用的 PaperProps 为 slotProps.paper。
- TimestampToDatetime / DatetimeToTimestamp: 替换已弃用的 InputProps 为 slotProps.input。

3. 类型与逻辑修复:
- utils/recordUtils.tsx: 引入缺失依赖,忽略 UNSAFE_replayCanvas 等类型报错,修复构建问题。
- utils/messages.tsx: 完善事件参数类型定义。

4. 其他优化:
- 统一 App.css 代码格式。
- 补充部分组件 (CopyButton, TimestampExecution) 的 React 导入和类型定义。
This commit is contained in:
雨霖铃
2026-02-13 23:46:16 +08:00
parent 50034331bc
commit 3ece5e2e96
9 changed files with 37 additions and 45 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
import { useState, useCallback, FC, ReactNode, useEffect } from 'react'; import React, { useState, useCallback, FC, ReactNode, useEffect } from 'react';
import Button, { ButtonProps } from '@mui/material/Button'; import Button, { ButtonProps } from '@mui/material/Button';
import Snackbar from '@mui/material/Snackbar'; import Snackbar from '@mui/material/Snackbar';
import Alert, { AlertColor } from '@mui/material/Alert'; import Alert, { AlertColor } from '@mui/material/Alert';
+6 -4
View File
@@ -70,7 +70,7 @@ export function DatetimeToTimestamp() {
}, [dateValue, selectedZone, unit, performConversion]); }, [dateValue, selectedZone, unit, performConversion]);
const handleUnitChange = useCallback( const handleUnitChange = useCallback(
(e: SelectChangeEvent<string>) => { (e: SelectChangeEvent) => {
const newUnit = e.target.value; const newUnit = e.target.value;
setUnit(newUnit); setUnit(newUnit);
if (result) { if (result) {
@@ -80,7 +80,7 @@ export function DatetimeToTimestamp() {
[dateValue, selectedZone, result, performConversion], [dateValue, selectedZone, result, performConversion],
); );
const handleZoneChange = useCallback((e: SelectChangeEvent<string>) => { const handleZoneChange = useCallback((e: SelectChangeEvent) => {
setSelectedZone(e.target.value); setSelectedZone(e.target.value);
}, []); }, []);
@@ -129,8 +129,10 @@ export function DatetimeToTimestamp() {
value={result} value={result}
fullWidth fullWidth
variant="outlined" variant="outlined"
InputProps={{ slotProps={{
readOnly: true, input: {
readOnly: true,
},
}} }}
/> />
<FormControl fullWidth> <FormControl fullWidth>
+6 -4
View File
@@ -88,10 +88,12 @@ function Navbar({ items = [] }: NavbarProps) {
anchorEl={anchorEl} anchorEl={anchorEl}
open={isMenuOpen} open={isMenuOpen}
onClose={handleMenuClose} onClose={handleMenuClose}
PaperProps={{ slotProps={{
style: { paper: {
maxHeight: 48 * 4.5, style: {
width: '20ch', maxHeight: 48 * 4.5,
width: '20ch',
},
}, },
}} }}
> >
+6 -23
View File
@@ -1,22 +1,12 @@
import { useEffect, useState, useCallback } from 'react'; import { useEffect, useState, useCallback, JSX } from 'react';
import CopyButton from './CopyButton'; import CopyButton from './CopyButton';
import { Button, Paper, Typography, Stack, Box } from '@mui/material'; import { Button, Paper, Typography, Stack, Box } from '@mui/material';
/** /**
* 时间戳显示和执行组件 * 时间戳显示和执行组件
*
* @component
* @example
* ```jsx
* <TimestampExecution />
* ```
*
* @returns {JSX.Element} 时间戳组件
*/ */
export function TimestampExecution() { export function TimestampExecution(): JSX.Element {
const [currentTimestamp, setCurrentTimestamp] = useState(() => const [currentTimestamp, setCurrentTimestamp] = useState(() => Math.floor(Date.now()));
Math.floor(Date.now()),
);
const [showMilliseconds, setShowMilliseconds] = useState(true); const [showMilliseconds, setShowMilliseconds] = useState(true);
const [isRunningTimestamp, setIsRunningTimestamp] = useState(true); const [isRunningTimestamp, setIsRunningTimestamp] = useState(true);
@@ -45,19 +35,12 @@ export function TimestampExecution() {
setIsRunningTimestamp((prev) => !prev); setIsRunningTimestamp((prev) => !prev);
}, []); }, []);
const unitButtonLabel = showMilliseconds const unitButtonLabel = showMilliseconds ? '切换为秒显示' : '切换为毫秒显示';
? '切换为秒显示' const toggleButtonLabel = isRunningTimestamp ? '停止时间戳自动更新' : '开始时间戳自动更新';
: '切换为毫秒显示';
const toggleButtonLabel = isRunningTimestamp
? '停止时间戳自动更新'
: '开始时间戳自动更新';
const toggleButtonText = isRunningTimestamp ? '停止' : '开始'; const toggleButtonText = isRunningTimestamp ? '停止' : '开始';
return ( return (
<Paper <Paper elevation={3} sx={{ p: 2, my: 2, borderRadius: 2, minWidth: 320, textAlign: 'center' }}>
elevation={3}
sx={{ p: 2, my: 2, borderRadius: 2, minWidth: 320, textAlign: 'center' }}
>
<Box <Box
sx={{ sx={{
display: 'flex', display: 'flex',
+7 -5
View File
@@ -1,4 +1,4 @@
import { useState, useCallback } from 'react'; import React, { useState, useCallback } from 'react';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { import {
Button, Button,
@@ -84,7 +84,7 @@ export function TimestampToDatetime() {
); );
const handleZoneChange = useCallback( const handleZoneChange = useCallback(
(e: SelectChangeEvent<string>) => { (e: SelectChangeEvent) => {
const newZone = e.target.value; const newZone = e.target.value;
setSelectedZone(newZone); setSelectedZone(newZone);
if (timestampResult) { if (timestampResult) {
@@ -96,7 +96,7 @@ export function TimestampToDatetime() {
); );
const handleUnitChange = useCallback( const handleUnitChange = useCallback(
(e: SelectChangeEvent<string>) => { (e: SelectChangeEvent) => {
const newUnit = e.target.value; const newUnit = e.target.value;
setUnit(newUnit); setUnit(newUnit);
if (timestampResult) { if (timestampResult) {
@@ -150,8 +150,10 @@ export function TimestampToDatetime() {
value={timestampResult} value={timestampResult}
fullWidth fullWidth
variant="outlined" variant="outlined"
InputProps={{ slotProps={{
readOnly: true, input: {
readOnly: true,
},
}} }}
/> />
<FormControl fullWidth> <FormControl fullWidth>
-1
View File
@@ -147,7 +147,6 @@ body {
.nav-collapse-content .nav-link { .nav-collapse-content .nav-link {
padding: 12px 20px; padding: 12px 20px;
border-bottom: 1px solid #f8f9fa;
width: 100%; width: 100%;
text-align: left; text-align: left;
box-sizing: border-box; box-sizing: border-box;
+3 -2
View File
@@ -49,7 +49,8 @@
"hooks/**/*", "hooks/**/*",
".wxt/types/**/*.ts", ".wxt/types/**/*.ts",
".wxt/types/*.d.ts", ".wxt/types/*.d.ts",
"components" "components",
"eslint.config.ts"
], ],
"exclude": ["node_modules", ".wxt", "eslint.config.ts"] "exclude": ["node_modules", ".wxt"]
} }
+1 -1
View File
@@ -41,7 +41,7 @@ interface ProtocolMap {
'popup:ready': () => void; 'popup:ready': () => void;
// --- Content 相关 --- // --- Content 相关 ---
'content:save-tracke-events': (event) => boolean; 'content:save-tracke-events': (event: unknown) => boolean;
'content:start-recording': () => { ok: boolean; error?: string }; 'content:start-recording': () => { ok: boolean; error?: string };
'content:stop-recording': () => { ok: boolean }; 'content:stop-recording': () => { ok: boolean };
'content:check-status': () => boolean; 'content:check-status': () => boolean;
+6 -3
View File
@@ -22,6 +22,7 @@ export const downloadHtmlInBackground = (events: unknown[]) => {
<script type="module"> <script type="module">
import { getReplayConsolePlugin } from 'https://esm.sh/@rrweb/rrweb-plugin-console-replay?bundle'; import { getReplayConsolePlugin } from 'https://esm.sh/@rrweb/rrweb-plugin-console-replay?bundle';
import rrwebPlayer from 'rrweb-player';
const events = JSON.parse(\`${safeEventsString}\`); const events = JSON.parse(\`${safeEventsString}\`);
@@ -37,14 +38,16 @@ export const downloadHtmlInBackground = (events: unknown[]) => {
// --- 👇 关键修复:添加下面这行 --- // --- 👇 关键修复:添加下面这行 ---
// 这会告诉 rrweb 关闭严格的 iframe 沙盒限制 // 这会告诉 rrweb 关闭严格的 iframe 沙盒限制
// 从而消除 "Blocked script execution" 错误 // 从而消除 "Blocked script execution" 错误
// @ts-ignore
UNSAFE_replayCanvas: true, UNSAFE_replayCanvas: true,
// ------------------------------ // ------------------------------
// @ts-ignore
plugins: [ plugins: [
getReplayConsolePlugin({ getReplayConsolePlugin({
level: ['info', 'log', 'warn', 'error'], level: ['info', 'log', 'warn', 'error'],
}) }),
] ],
}, },
}); });
</script> </script>
@@ -59,7 +62,7 @@ export const downloadHtmlInBackground = (events: unknown[]) => {
url: reader.result as string, url: reader.result as string,
filename: `replay-${Date.now()}.html`, filename: `replay-${Date.now()}.html`,
saveAs: true, saveAs: true,
}); }).then(r => console.log(r));
}; };
reader.readAsDataURL(blob); reader.readAsDataURL(blob);
}; };