@@ -7,6 +7,14 @@ import { Card, CardContent, CardHeader } from "@/components/ui/card";
7
7
import { Select , SelectContent , SelectItem , SelectTrigger , SelectValue } from "@/components/ui/select" ;
8
8
import { db } from '../lib/db' ;
9
9
import { useSerialPorts } from '../hooks/useSerialPorts' ;
10
+ import { RefreshCw } from 'lucide-react' ;
11
+ import { invoke } from '@tauri-apps/api' ;
12
+
13
+ interface Device {
14
+ deviceId : string ;
15
+ screenSize : string ;
16
+ lastSeen : number ;
17
+ }
10
18
11
19
interface SettingsPanelProps {
12
20
setIsConfigured ?: ( value : boolean ) => void ;
@@ -27,6 +35,10 @@ export const SettingsPanel: React.FC<SettingsPanelProps> = ({ setIsConfigured })
27
35
phoneSerialNumber : '' ,
28
36
} ) ;
29
37
38
+ const [ devices , setDevices ] = useState < Device [ ] > ( [ ] ) ;
39
+ const [ loadingDevices , setLoadingDevices ] = useState ( false ) ;
40
+ const [ deviceError , setDeviceError ] = useState < string | null > ( null ) ;
41
+
30
42
const { ports, loading, error } = useSerialPorts ( ) ;
31
43
32
44
useEffect ( ( ) => {
@@ -42,6 +54,13 @@ export const SettingsPanel: React.FC<SettingsPanelProps> = ({ setIsConfigured })
42
54
loadSettings ( ) ;
43
55
} , [ ] ) ;
44
56
57
+
58
+ useEffect ( ( ) => {
59
+ if ( settings . wsEndpoint ) {
60
+ handleRefreshDevices ( ) ;
61
+ }
62
+ } , [ settings . wsEndpoint ] ) ;
63
+
45
64
const handleChange = ( key : keyof typeof settings , value : string ) => {
46
65
setSettings ( prev => ( { ...prev , [ key ] : value } ) ) ;
47
66
} ;
@@ -50,7 +69,7 @@ export const SettingsPanel: React.FC<SettingsPanelProps> = ({ setIsConfigured })
50
69
setSettings ( prev => ( {
51
70
...prev ,
52
71
serialPort : value ,
53
- deviceName : value // Extract the last part of the path as device name
72
+ deviceName : value
54
73
} ) ) ;
55
74
} ;
56
75
@@ -69,6 +88,55 @@ export const SettingsPanel: React.FC<SettingsPanelProps> = ({ setIsConfigured })
69
88
alert ( '设置已保存' ) ;
70
89
} ;
71
90
91
+ async function refreshPorts ( ) : Promise < void > {
92
+ try {
93
+ // Call Rust's get_serial_ports command
94
+ const portsResult = await invoke ( 'get_serial_ports' ) ;
95
+ // Update the ports state through the useSerialPorts hook
96
+ if ( Array . isArray ( portsResult ) ) {
97
+ // The ports will automatically update through the useSerialPorts hook
98
+ // No need to manually clear/update the dropdown since it's handled by the hook
99
+ }
100
+ } catch ( error ) {
101
+ console . error ( 'Failed to refresh ports:' , error ) ;
102
+ }
103
+ }
104
+
105
+ const handleRefreshDevices = async ( ) => {
106
+ console . log ( '开始刷新设备列表...' ) ;
107
+ setLoadingDevices ( true ) ;
108
+ setDeviceError ( null ) ;
109
+ try {
110
+ const requestConfig = {
111
+ targetUrl : `${ settings . wsEndpoint } /api/device/list` ,
112
+ method : 'GET' ,
113
+ body : [ ] as number [ ]
114
+ } ;
115
+
116
+ console . log ( '发送请求配置:' , requestConfig ) ;
117
+
118
+ const response = await invoke ( 'proxy_request' , requestConfig ) ;
119
+ console . log ( '收到原始响应:' , response ) ;
120
+
121
+ const data = JSON . parse ( response as string ) ;
122
+ console . log ( '解析后的数据:' , data ) ;
123
+
124
+ if ( data . success ) {
125
+ console . log ( '成功获取设备列表:' , data . devices ) ;
126
+ setDevices ( data . devices ) ;
127
+ } else {
128
+ console . error ( 'API返回错误:' , data . error ) ;
129
+ setDeviceError ( data . error || '获取设备列表失败' ) ;
130
+ }
131
+ } catch ( err ) {
132
+ console . error ( '请求过程出错:' , err ) ;
133
+ setDeviceError ( '获取设备列表失败' ) ;
134
+ } finally {
135
+ console . log ( '设备列表刷新完成' ) ;
136
+ setLoadingDevices ( false ) ;
137
+ }
138
+ } ;
139
+
72
140
return (
73
141
< div className = "container mx-auto p-4" >
74
142
< h1 className = "text-2xl font-bold mb-4" > 设置</ h1 >
@@ -122,7 +190,17 @@ export const SettingsPanel: React.FC<SettingsPanelProps> = ({ setIsConfigured })
122
190
< CardContent >
123
191
< div className = "space-y-4" >
124
192
< div >
125
- < label className = "block mb-1" > 串口</ label >
193
+ < div className = "flex justify-between items-center mb-1" >
194
+ < label className = "block" > 串口</ label >
195
+ < Button
196
+ variant = "outline"
197
+ size = "sm"
198
+ onClick = { ( ) => refreshPorts ( ) }
199
+ disabled = { loading }
200
+ >
201
+ < RefreshCw className = "h-4 w-4" />
202
+ </ Button >
203
+ </ div >
126
204
< Select
127
205
value = { settings . serialPort }
128
206
onValueChange = { handleSerialPortChange }
@@ -158,12 +236,42 @@ export const SettingsPanel: React.FC<SettingsPanelProps> = ({ setIsConfigured })
158
236
/>
159
237
</ div >
160
238
< div >
161
- < label className = "block mb-1" > 手机串号</ label >
162
- < Input
163
- value = { settings . phoneSerialNumber }
164
- onChange = { ( e ) => handleChange ( 'phoneSerialNumber' , e . target . value ) }
165
- placeholder = "请输入手机唯一标识符,在手机屏幕连续单机3下获取"
166
- />
239
+ < div className = "flex justify-between items-center mb-1" >
240
+ < label className = "block" > 手机设备</ label >
241
+ < Button
242
+ variant = "outline"
243
+ size = "sm"
244
+ onClick = { handleRefreshDevices }
245
+ disabled = { loadingDevices }
246
+ >
247
+ < RefreshCw className = "h-4 w-4" />
248
+ </ Button >
249
+ </ div >
250
+ < div className = "space-y-2" >
251
+ < Select
252
+ value = { settings . phoneSerialNumber }
253
+ onValueChange = { ( value ) => handleChange ( 'phoneSerialNumber' , value ) }
254
+ disabled = { loadingDevices }
255
+ >
256
+ < SelectTrigger >
257
+ < SelectValue placeholder = "选择设备" />
258
+ </ SelectTrigger >
259
+ < SelectContent >
260
+ { loadingDevices && < SelectItem value = "loading" > 加载中...</ SelectItem > }
261
+ { deviceError && < SelectItem value = "error" > 错误: { deviceError } </ SelectItem > }
262
+ { devices . map ( ( device ) => (
263
+ < SelectItem key = { device . deviceId } value = { device . deviceId } >
264
+ { device . deviceId } ({ device . screenSize } )
265
+ </ SelectItem >
266
+ ) ) }
267
+ </ SelectContent >
268
+ </ Select >
269
+ < Input
270
+ value = { settings . phoneSerialNumber }
271
+ onChange = { ( e ) => handleChange ( 'phoneSerialNumber' , e . target . value ) }
272
+ placeholder = "或手动输入设备串号"
273
+ />
274
+ </ div >
167
275
</ div >
168
276
</ div >
169
277
</ CardContent >
0 commit comments