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:
@@ -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';
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user