From bec7cd39799581e62dde6cba040e2a37d6a44bbe Mon Sep 17 00:00:00 2001 From: wdvipa Date: Sun, 15 Feb 2026 18:51:03 +0800 Subject: [PATCH] =?UTF-8?q?style:=20DeviceScreen.tsx=E6=B8=85=E7=90=86?= =?UTF-8?q?=E5=85=A8=E9=83=A8emoji=E7=AC=A6=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除注释中所有emoji标记(checkmark/new/wrench/search等) - 移除日志输出中的emoji(控制权/警告/错误等) - 移除UI文本中的emoji(操作已禁用/丢帧警告/全屏按钮) - 清理Vite缓存解决pendingSizeRef旧代码残留问题 --- src/components/Device/DeviceScreen.tsx | 102 ++++++++++++------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/components/Device/DeviceScreen.tsx b/src/components/Device/DeviceScreen.tsx index 1ea81f8..287af65 100644 --- a/src/components/Device/DeviceScreen.tsx +++ b/src/components/Device/DeviceScreen.tsx @@ -27,12 +27,12 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang const [imageSize, setImageSize] = useState<{ width: number, height: number } | null>(null) const [isFullscreen, setIsFullscreen] = useState(false) - // ✅ FPS 计算:使用滑动窗口统计真实帧率 + // FPS 计算:使用滑动窗口统计真实帧率 const fpsFrameTimesRef = useRef([]) const [displayFps, setDisplayFps] = useState(0) const lastFpsUpdateRef = useRef(0) - // ✅ 帧渲染控制:只保留最新帧,用 rAF 驱动渲染 + // 帧渲染控制:只保留最新帧,用 rAF 驱动渲染 const latestFrameRef = useRef(null) const rafIdRef = useRef(0) const isRenderingRef = useRef(false) @@ -42,7 +42,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang // 避免不同采集模式(MediaProjection/无障碍截图)帧尺寸不一致导致闪烁 const lockedCanvasSizeRef = useRef<{ width: number, height: number } | null>(null) - // ✅ 添加控制权状态跟踪,避免重复申请 + // 添加控制权状态跟踪,避免重复申请 const [isControlRequested, setIsControlRequested] = useState(false) const [currentWebSocket, setCurrentWebSocket] = useState(null) const [lastControlRequestTime, setLastControlRequestTime] = useState(0) @@ -53,7 +53,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang const device = connectedDevices.find(d => d.id === deviceId) - // 📊 画质控制状态 + // 画质控制状态 const [currentProfile, setCurrentProfile] = useState('medium') const [showQualityPanel, setShowQualityPanel] = useState(false) const [networkStats, setNetworkStats] = useState({ fps: 0, dropRate: 0, avgFrameSize: 0 }) @@ -62,14 +62,14 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang const feedbackTimerRef = useRef(0) const lastFeedbackTimeRef = useRef(0) - // ✅ 安全地通知父组件屏幕尺寸变化(在 useEffect 中而非渲染期间) + // 安全地通知父组件屏幕尺寸变化(在 useEffect 中而非渲染期间) useEffect(() => { if (imageSize && onScreenSizeChange) { onScreenSizeChange(imageSize) } }, [imageSize, onScreenSizeChange]) - // 📊 画质反馈:定期向服务端报告网络质量 + // 画质反馈:定期向服务端报告网络质量 useEffect(() => { if (!webSocket || !deviceId) return @@ -112,23 +112,23 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang } }, [webSocket, deviceId, displayFps]) - // 📊 切换画质档位 + // 切换画质档位 const handleSetProfile = useCallback((profileKey: string) => { if (!webSocket) return webSocket.emit('set_quality_profile', { deviceId, profile: profileKey }) setCurrentProfile(profileKey) }, [webSocket, deviceId]) - // ✅ 监听屏幕数据的独立useEffect,避免与控制权逻辑混合 + // 监听屏幕数据的独立useEffect,避免与控制权逻辑混合 useEffect(() => { if (!webSocket) return const handleScreenData = (data: any) => { if (data.deviceId === deviceId) { - // 📊 帧计数用于质量反馈 + // 帧计数用于质量反馈 frameCountRef.current++ - // ✅ 过滤黑屏帧:Base64长度<4000字符(≈3KB JPEG)几乎肯定是黑屏/空白帧 + // 过滤黑屏帧:Base64长度<4000字符(约3KB JPEG)几乎肯定是黑屏/空白帧 // 正常480×854 JPEG即使最低质量也>8000字符 const dataLen = typeof data.data === 'string' ? data.data.length : 0 const MIN_VALID_FRAME_LENGTH = 4000 @@ -142,18 +142,18 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang return } - // 🔍 诊断:记录数据到达频率 + // 诊断:记录数据到达频率 if (frameCountRef.current % 30 === 0) { console.log(`[屏幕数据] 已收到 ${frameCountRef.current} 帧, 数据大小: ${dataLen}, 渲染中: ${isRenderingRef.current}, 解码中: ${decodingRef.current}`) } - // ✅ 只保存最新帧引用,不立即解码 + // 只保存最新帧引用,不立即解码 latestFrameRef.current = data // 只在首帧时更新loading状态,避免每帧触发重渲染 if (isLoading) setIsLoading(false) - // ✅ 如果没有正在进行的渲染循环,启动一个 + // 如果没有正在进行的渲染循环,启动一个 if (!isRenderingRef.current) { isRenderingRef.current = true renderLatestFrame() @@ -176,7 +176,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang } }, [webSocket, deviceId]) - // ✅ 控制权管理的独立useEffect,只在必要时申请/释放 + // 控制权管理的独立useEffect,只在必要时申请/释放 useEffect(() => { if (!webSocket || !deviceId) return @@ -189,13 +189,13 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang // 只在未申请过控制权时申请,且防止重复发送 if (!isControlRequested) { const now = Date.now() - // 🔧 防止短时间内重复发送请求(2秒内只能发送一次) + // 防止短时间内重复发送请求(2秒内只能发送一次) if (now - lastControlRequestTime < 2000) { - console.log('⚠️ 控制权请求过于频繁,跳过') + console.log('控制权请求过于频繁,跳过') return } - console.log('🎮 申请设备控制权:', deviceId) + console.log('申请设备控制权:', deviceId) setLastControlRequestTime(now) webSocket.emit('client_event', { type: 'REQUEST_DEVICE_CONTROL', @@ -208,19 +208,19 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang const handleControlResponse = (data: any) => { if (data.deviceId === deviceId) { if (data.success) { - console.log('✅ 控制权获取成功:', deviceId) + console.log('控制权获取成功:', deviceId) } else { - console.warn('❌ 控制权获取失败:', data.message) + console.warn('控制权获取失败:', data.message) // 如果失败,允许重新申请 setIsControlRequested(false) } } } - // ✅ 监听控制错误,自动重新申请控制权 + // 监听控制错误,自动重新申请控制权 const handleControlError = (data: any) => { if (data.deviceId === deviceId && data.error === 'NO_PERMISSION') { - console.warn('⚠️ 检测到权限丢失,重新申请控制权:', deviceId) + console.warn('检测到权限丢失,重新申请控制权:', deviceId) setIsControlRequested(false) } } @@ -235,16 +235,16 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang // 只有在已申请过控制权时才释放 if (isControlRequested) { - console.log('🔓 释放设备控制权:', deviceId) + console.log('释放设备控制权:', deviceId) webSocket.emit('client_event', { type: 'RELEASE_DEVICE_CONTROL', data: { deviceId } }) } } - }, [webSocket, deviceId, isControlRequested, currentWebSocket]) // 🔧 不包含lastControlRequestTime避免重复执行 + }, [webSocket, deviceId, isControlRequested, currentWebSocket]) // 不包含lastControlRequestTime避免重复执行 - // ✅ 高性能渲染:createImageBitmap 离屏解码 + 持续 rAF 循环 + // 高性能渲染:createImageBitmap 离屏解码 + 持续 rAF 循环 const decodingRef = useRef(false) const renderLatestFrame = useCallback(() => { @@ -564,7 +564,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang } } - // 🆕 显示长按拖拽开始指示器 + // 显示长按拖拽开始指示器 const showLongPressDragStartIndicator = (x: number, y: number) => { const container = canvasRef.current?.parentElement if (!container) return @@ -603,7 +603,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang return indicator } - // 🆕 显示长按拖拽路径指示器 + // 显示长按拖拽路径指示器 const showLongPressDragPath = (startX: number, startY: number, endX: number, endY: number) => { const container = canvasRef.current?.parentElement if (!container) return @@ -687,15 +687,15 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang const [isDragging, setIsDragging] = useState(false) const [dragStart, setDragStart] = useState<{x: number, y: number} | null>(null) - // 🆕 添加长按处理 + // 添加长按处理 const [isLongPressTriggered, setIsLongPressTriggered] = useState(false) const longPressTimerRef = useRef(null) - // 🆕 添加长按拖拽处理状态 + // 添加长按拖拽处理状态 const [isLongPressDragging, setIsLongPressDragging] = useState(false) const [longPressDragStartPos, setLongPressDragStartPos] = useState<{x: number, y: number} | null>(null) - // 🆕 添加拖拽路径收集状态 + // 添加拖拽路径收集状态 const [dragPath, setDragPath] = useState>([]) const lastMoveTimeRef = useRef(0) @@ -738,7 +738,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang }, [webSocket, device, deviceId, screenDisplay.showTouchIndicator, convertCanvasToDeviceCoords, operationEnabled]) - // 🆕 处理长按操作 + // 处理长按操作 const performLongPress = useCallback((canvasX: number, canvasY: number) => { if (!webSocket || !device) return @@ -787,14 +787,14 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang setDragStart({ x: startX, y: startY }) - // 🆕 启动长按计时器 + // 启动长按计时器 setIsLongPressTriggered(false) setIsLongPressDragging(false) setLongPressDragStartPos(null) - setDragPath([]) // 🔧 清理拖拽路径 + setDragPath([]) // 清理拖拽路径 longPressTimerRef.current = window.setTimeout(() => { setIsLongPressTriggered(true) - // 🆕 长按触发后不立即执行操作,而是准备进入拖拽模式 + // 长按触发后不立即执行操作,而是准备进入拖拽模式 console.log('长按触发,准备进入拖拽模式') }, 500) // 500ms 后触发长按 }, [performLongPress]) @@ -804,7 +804,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang event.preventDefault() - // 🆕 处理长按拖拽逻辑 - 优化为连续手势 + // 处理长按拖拽逻辑 - 优化为连续手势 if (isLongPressTriggered && !isLongPressDragging) { // 长按已触发,用户开始拖拽,进入长按拖拽模式 if (!webSocket || !device || !operationEnabled) return @@ -819,17 +819,17 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang setIsLongPressDragging(true) setLongPressDragStartPos(startCoords) - // 🔧 优化:初始化拖拽路径,包含起始点 + // 优化:初始化拖拽路径,包含起始点 setDragPath([startCoords]) - // 🆕 显示长按拖拽开始指示器 + // 显示长按拖拽开始指示器 if (screenDisplay.showTouchIndicator) { showLongPressDragStartIndicator(dragStart.x, dragStart.y) } console.log(`长按拖拽开始: Device(${startCoords.x.toFixed(1)}, ${startCoords.y.toFixed(1)})`) } else if (isLongPressDragging) { - // 🔧 优化:收集拖拽路径点,而不是立即发送消息 + // 优化:收集拖拽路径点,而不是立即发送消息 const now = Date.now() // 频率控制:每50ms最多记录一个点,避免路径过密 @@ -863,16 +863,16 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang event.preventDefault() setIsDragging(false) - // 🆕 清理长按计时器 + // 清理长按计时器 if (longPressTimerRef.current) { clearTimeout(longPressTimerRef.current) longPressTimerRef.current = null } - // 🆕 处理长按相关操作 + // 处理长按相关操作 if (isLongPressTriggered) { if (isLongPressDragging) { - // 🔧 优化:执行完整的长按拖拽手势 + // 优化:执行完整的长按拖拽手势 if (webSocket && device && operationEnabled && longPressDragStartPos && dragPath.length > 0) { const canvas = canvasRef.current if (canvas) { @@ -902,7 +902,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang console.log(`长按拖拽完成: Device(${completePath[0].x.toFixed(1)}, ${completePath[0].y.toFixed(1)}) -> Device(${endCoords.x.toFixed(1)}, ${endCoords.y.toFixed(1)}), 路径点数: ${completePath.length}`) - // 🆕 显示长按拖拽路径指示器 + // 显示长按拖拽路径指示器 if (screenDisplay.showTouchIndicator) { showLongPressDragPath(dragStart.x, dragStart.y, endX, endY) } @@ -925,7 +925,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang setIsLongPressTriggered(false) setIsLongPressDragging(false) setLongPressDragStartPos(null) - setDragPath([]) // 🔧 清理拖拽路径 + setDragPath([]) // 清理拖拽路径 return } @@ -991,20 +991,20 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang setIsDragging(false) setDragStart(null) - // 🆕 清理长按计时器和状态 + // 清理长按计时器和状态 if (longPressTimerRef.current) { clearTimeout(longPressTimerRef.current) longPressTimerRef.current = null } setIsLongPressTriggered(false) - // 🆕 清理长按拖拽相关状态 + // 清理长按拖拽相关状态 setIsLongPressDragging(false) setLongPressDragStartPos(null) - setDragPath([]) // 🔧 清理拖拽路径 + setDragPath([]) // 清理拖拽路径 }, []) - // 🔍 全屏切换 + // 全屏切换 const toggleFullscreen = useCallback(() => { const container = fullscreenContainerRef.current if (!container) return @@ -1120,7 +1120,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang border: '2px solid #ff4d4f', animation: 'pulse 2s infinite' }}> - 🔒 操作已禁用 + [LOCKED] 操作已禁用 )} @@ -1158,7 +1158,7 @@ const DeviceScreen: React.FC = ({ deviceId, onScreenSizeChang /> - {/* 📊 画质控制面板 + 🔍 全屏按钮 */} + {/* 画质控制面板 + 全屏按钮 */}
= ({ deviceId, onScreenSizeChang borderRadius: '3px', fontFamily: 'monospace', }}> - {displayFps} FPS{networkStats.dropRate > 0.05 ? ` ⚠${(networkStats.dropRate * 100).toFixed(0)}%丢帧` : ''} + {displayFps} FPS{networkStats.dropRate > 0.05 ? ` [!]${(networkStats.dropRate * 100).toFixed(0)}%丢帧` : ''}
)}
- {/* 🔍 全屏/退出全屏按钮 */} + {/* 全屏/退出全屏按钮 */}