1+ import { SideButton } from './SideButton' ;
12import { ignoreHref } from '@extension/shared' ;
23import { useState , useEffect } from 'react' ;
34import { FaPlay , FaStop , FaEye , FaEyeSlash , FaMousePointer , FaExpand , FaBan , FaDesktop , FaBug } from 'react-icons/fa' ;
45import type { SetState } from '@extension/shared' ;
56import type React from 'react' ;
67
7- // --- Status Item Component ---
8- const StatusItem : React . FC < { icon : React . ReactNode ; title : string ; value : string ; onClick ?: ( ) => void } > = ( {
9- icon,
10- title,
11- value,
12- onClick,
13- } ) => {
14- const [ isDarkMode , setIsDarkMode ] = useState ( window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ) ;
15-
16- useEffect ( ( ) => {
17- const mediaQuery = window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
18- const handleChange = ( e : MediaQueryListEvent ) => {
19- setIsDarkMode ( e . matches ) ;
20- } ;
21- mediaQuery . addEventListener ( 'change' , handleChange ) ;
22- return ( ) => {
23- mediaQuery . removeEventListener ( 'change' , handleChange ) ;
24- } ;
25- } , [ ] ) ;
26-
27- const style : React . CSSProperties = {
28- display : 'flex' ,
29- alignItems : 'center' ,
30- backdropFilter : 'blur(8px)' ,
31- borderRadius : '8px' ,
32- padding : '2px 4px' ,
33- ...( isDarkMode
34- ? {
35- backgroundColor : 'rgba(0, 0, 0, 0.5)' ,
36- border : '1px solid rgba(255, 255, 255, 0.5)' ,
37- color : '#fff' ,
38- }
39- : {
40- backgroundColor : 'rgba(255, 255, 255, 0.5)' ,
41- border : '1px solid rgba(0, 0, 0, 0.5)' ,
42- color : '#111' ,
43- } ) ,
44- } ;
45-
46- if ( onClick ) {
47- style . pointerEvents = 'auto' ;
48- style . cursor = 'pointer' ;
49- }
50- return (
51- // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
52- < div onClick = { onClick } style = { style } >
53- < div
54- style = { {
55- width : '24px' ,
56- height : '24px' ,
57- marginRight : '2px' ,
58- flexShrink : 0 ,
59- display : 'flex' ,
60- alignItems : 'center' ,
61- justifyContent : 'center' ,
62- } } >
63- { icon }
64- </ div >
65- < div style = { { display : 'flex' , flexDirection : 'column' } } >
66- < div style = { { fontSize : '0.9rem' , fontWeight : 600 , lineHeight : '1.3' } } > { title } </ div >
67- < div style = { { fontSize : '0.8rem' , opacity : 0.7 } } > { value } </ div >
68- </ div >
69- </ div >
70- ) ;
71- } ;
72-
738export const Dashboard : React . FC = ( ) => {
749 // 是否运行中, websocket 是否处于链接状态?
7510 const [ running , setRunning ] = useState ( false ) ;
@@ -79,6 +14,10 @@ export const Dashboard: React.FC = () => {
7914 const [ interactionMode , setInteractionMode ] = useState < 'hover' | 'full' > ( 'hover' ) ;
8015 // 演示模式
8116 const [ demoMode , setDemoMode ] = useState ( false ) ;
17+ // 是否显示其他状态项
18+ const [ hoverd , setHoverd ] = useState ( false ) ;
19+ // 是否正在hover其他状态项
20+ const [ hoveringOthers , setHoveringOthers ] = useState ( false ) ;
8221
8322 const [ inspecting , setInspecting ] = useState ( false ) ;
8423
@@ -150,42 +89,94 @@ export const Dashboard: React.FC = () => {
15089 const dashboardStyle : React . CSSProperties = {
15190 position : 'fixed' ,
15291 bottom : 0 ,
153- left : 0 ,
92+ right : 0 ,
15493 top : 0 ,
155- width : 180 ,
15694 zIndex : 2147483647 ,
15795 pointerEvents : 'none' ,
15896 display : 'flex' ,
15997 flexDirection : 'column' ,
160- alignItems : 'flex-start ' ,
98+ alignItems : 'flex-end ' ,
16199 justifyContent : 'center' ,
162- padding : '20px 20px 20px 4px' ,
100+ paddingTop : 0 ,
101+ paddingBottom : 0 ,
102+ paddingLeft : 0 ,
103+ paddingRight : 0 ,
163104 gap : '4px' ,
105+ userSelect : 'none' ,
106+ backgroundColor : 'rgba(0, 0, 0, 0.1)' ,
164107 } ;
165108
109+ // 计算是否应该显示其他状态项
110+ const shouldShowOthers = hoverd || hoveringOthers ;
111+
166112 return (
167113 < div style = { dashboardStyle } >
168- < StatusItem
169- icon = { running ? < FaPlay /> : < FaStop /> }
170- title = "RWKV 运行状态"
171- value = { running ? '运行中' : '未运行' }
172- />
173- < StatusItem icon = { ignored ? < FaEyeSlash /> : < FaEye /> } title = "页面被忽略了" value = { ignored ? '是' : '否' } />
174- < StatusItem
175- icon = { getInteractionModeIcon ( ) }
176- title = "交互模式"
177- // value={interactionMode ?? 'None'}
178- value = { '未实现' }
179- onClick = { toggleInteractionMode }
180- />
181- < StatusItem
182- icon = { < FaDesktop /> }
183- title = "演示模式"
184- // value={demoMode ? '是' : '否'}
185- value = { '未实现' }
186- onClick = { toggleDemoMode }
187- />
188- < StatusItem icon = { < FaBug /> } title = "诊断模式" value = { inspecting ? '是' : '否' } onClick = { toggleDiagnoseMode } />
114+ < div onMouseEnter = { ( ) => setHoverd ( true ) } onMouseLeave = { ( ) => setHoverd ( false ) } >
115+ < SideButton
116+ icon = { running ? < FaPlay /> : < FaStop /> }
117+ title = "??"
118+ value = { running ? '运行中' : '未运行' }
119+ style = { {
120+ transform : shouldShowOthers || hoverd ? 'translateX(0)' : 'translateX(67%)' ,
121+ opacity : shouldShowOthers || hoverd ? 1 : 0.5 ,
122+ transition : 'transform 0.1s ease-out, opacity 0.1s ease-out' ,
123+ } }
124+ />
125+ </ div >
126+
127+ < div
128+ style = { {
129+ display : 'flex' ,
130+ flexDirection : 'column' ,
131+ gap : '4px' ,
132+ pointerEvents : shouldShowOthers ? 'auto' : 'none' ,
133+ } }
134+ onMouseEnter = { ( ) => setHoveringOthers ( true ) }
135+ onMouseLeave = { ( ) => setHoveringOthers ( false ) } >
136+ < SideButton
137+ icon = { ignored ? < FaEyeSlash /> : < FaEye /> }
138+ title = "页面被忽略了"
139+ value = { ignored ? '是' : '否' }
140+ style = { {
141+ transform : shouldShowOthers ? 'translateX(0)' : 'translateX(100%)' ,
142+ opacity : shouldShowOthers ? 1 : 0 ,
143+ transition : 'transform 0.1s ease-out, opacity 0.1s ease-out' ,
144+ } }
145+ />
146+ < SideButton
147+ icon = { getInteractionModeIcon ( ) }
148+ title = "交互模式"
149+ value = { '未实现' }
150+ onClick = { toggleInteractionMode }
151+ style = { {
152+ transform : shouldShowOthers ? 'translateX(0)' : 'translateX(100%)' ,
153+ opacity : shouldShowOthers ? 1 : 0 ,
154+ transition : 'transform 0.1s ease-out, opacity 0.1s ease-out' ,
155+ } }
156+ />
157+ < SideButton
158+ icon = { < FaDesktop /> }
159+ title = "演示模式"
160+ value = { '未实现' }
161+ onClick = { toggleDemoMode }
162+ style = { {
163+ transform : shouldShowOthers ? 'translateX(0)' : 'translateX(100%)' ,
164+ opacity : shouldShowOthers ? 1 : 0 ,
165+ transition : 'transform 0.1s ease-out, opacity 0.1s ease-out' ,
166+ } }
167+ />
168+ < SideButton
169+ icon = { < FaBug /> }
170+ title = "诊断模式"
171+ value = { inspecting ? '是' : '否' }
172+ onClick = { toggleDiagnoseMode }
173+ style = { {
174+ transform : shouldShowOthers ? 'translateX(0)' : 'translateX(100%)' ,
175+ opacity : shouldShowOthers ? 1 : 0 ,
176+ transition : 'transform 0.1s ease-out, opacity 0.1s ease-out' ,
177+ } }
178+ />
179+ </ div >
189180 </ div >
190181 ) ;
191182} ;
0 commit comments