1
1
<script setup lang="ts">
2
2
import { useI18n } from ' vue-i18n'
3
- import { ref , onUnmounted } from ' vue'
3
+ import { ref , onUnmounted , h } from ' vue'
4
4
5
- import { useBool } from ' @/hooks'
6
5
import { getKernelWS } from ' @/api/kernel'
7
- import { useKernelApiStore } from ' @/stores'
6
+ import { useModal } from ' @/components/Modal'
7
+ import { useEnvStore , useKernelApiStore } from ' @/stores'
8
8
import { ModeOptions } from ' @/constant/kernel'
9
- import { formatBytes , handleChangeMode , setIntervalImmediately } from ' @/utils'
9
+ import { formatBytes , handleChangeMode , message , setIntervalImmediately } from ' @/utils'
10
10
11
+ import LogsController from ' ./LogsController.vue'
12
+ import CommonController from ' ./CommonController.vue'
11
13
import ConnectionsController from ' ./ConnectionsController.vue'
12
14
13
15
const trafficHistory = ref <[number [], number []]>([[], []])
@@ -21,10 +23,88 @@ const statistics = ref({
21
23
})
22
24
23
25
const { t } = useI18n ()
26
+ const [Modal, modalApi] = useModal ({})
27
+ const envStore = useEnvStore ()
24
28
const kernelApiStore = useKernelApiStore ()
25
- const [showKernelConnections, toggleKernelConnections] = useBool (false )
26
29
27
- const isActiveMode = (mode : string ) => kernelApiStore .config .mode === mode
30
+ const handleRestartKernel = async () => {
31
+ try {
32
+ await kernelApiStore .restartKernel ()
33
+ } catch (error : any ) {
34
+ console .error (error )
35
+ message .error (error )
36
+ }
37
+ }
38
+
39
+ const handleStopKernel = async () => {
40
+ try {
41
+ await kernelApiStore .stopKernel ()
42
+ } catch (error : any ) {
43
+ console .error (error )
44
+ message .error (error )
45
+ }
46
+ }
47
+
48
+ const handleShowApiLogs = () => {
49
+ modalApi
50
+ .setProps ({
51
+ title: ' Logs' ,
52
+ cancelText: ' common.close' ,
53
+ width: ' 90' ,
54
+ height: ' 90' ,
55
+ submit: false ,
56
+ maskClosable: true ,
57
+ })
58
+ .setComponent (h (LogsController ))
59
+ .open ()
60
+ }
61
+
62
+ const handleShowApiConnections = () => {
63
+ modalApi
64
+ .setProps ({
65
+ title: ' home.overview.connections' ,
66
+ cancelText: ' common.close' ,
67
+ width: ' 90' ,
68
+ height: ' 90' ,
69
+ submit: false ,
70
+ maskClosable: true ,
71
+ })
72
+ .setComponent (h (ConnectionsController ))
73
+ .open ()
74
+ }
75
+
76
+ const handleShowSettings = () => {
77
+ modalApi
78
+ .setProps ({
79
+ title: ' home.overview.settings' ,
80
+ cancelText: ' common.close' ,
81
+ width: ' 90' ,
82
+ submit: false ,
83
+ maskClosable: true ,
84
+ })
85
+ .setComponent (h (CommonController ))
86
+ .open ()
87
+ }
88
+
89
+ const onTunSwitchChange = async (enable : boolean ) => {
90
+ try {
91
+ await kernelApiStore .updateConfig (' tun' , { enable })
92
+ } catch (error : any ) {
93
+ kernelApiStore .config .tun .enable = ! kernelApiStore .config .tun .enable
94
+ console .error (error )
95
+ message .error (error )
96
+ }
97
+ }
98
+
99
+ const onSystemProxySwitchChange = async (enable : boolean ) => {
100
+ try {
101
+ await envStore .switchSystemProxy (enable )
102
+ } catch (error : any ) {
103
+ console .error (error )
104
+ message .error (error )
105
+ envStore .systemProxy = ! envStore .systemProxy
106
+ }
107
+ }
28
108
29
109
const onConnections = (data : any ) => {
30
110
statistics .value .downloadTotal = data .downloadTotal
@@ -61,7 +141,50 @@ onUnmounted(() => {
61
141
62
142
<template >
63
143
<div class =" overview" >
64
- <div class =" statistics" >
144
+ <div class =" flex items-center rounded-8 px-8 py-2" style =" background-color : var (--card-bg )" >
145
+ <Button @click =" handleShowSettings" type =" text" size =" small" icon =" settings" />
146
+ <Switch
147
+ v-model =" envStore.systemProxy"
148
+ @change =" onSystemProxySwitchChange"
149
+ size =" small"
150
+ border =" square"
151
+ class =" ml-4"
152
+ >
153
+ {{ t('home.overview.systemProxy') }}
154
+ </Switch >
155
+ <Switch
156
+ v-model =" kernelApiStore.config.tun.enable"
157
+ @change =" onTunSwitchChange"
158
+ size =" small"
159
+ border =" square"
160
+ class =" ml-8"
161
+ >
162
+ {{ t('home.overview.tunMode') }}
163
+ </Switch >
164
+ <Button
165
+ @click =" handleShowApiLogs"
166
+ v-tips =" 'home.overview.viewlog'"
167
+ type =" text"
168
+ size =" small"
169
+ icon =" log"
170
+ class =" ml-auto"
171
+ />
172
+ <Button
173
+ @click =" handleRestartKernel"
174
+ v-tips =" 'home.overview.restart'"
175
+ type =" text"
176
+ size =" small"
177
+ icon =" restart"
178
+ />
179
+ <Button
180
+ @click =" handleStopKernel"
181
+ v-tips =" 'home.overview.stop'"
182
+ type =" text"
183
+ size =" small"
184
+ icon =" stop"
185
+ />
186
+ </div >
187
+ <div class =" flex justify-between" style =" margin-top : 20px ; gap : 12px " >
65
188
<Card :title =" t('home.overview.realtimeTraffic')" class =" statistics-card" >
66
189
<div class =" detail" >
67
190
↑ {{ formatBytes(statistics.upload) }}/s ↓ {{ formatBytes(statistics.download) }}/s
@@ -73,9 +196,9 @@ onUnmounted(() => {
73
196
</div >
74
197
</Card >
75
198
<Card
76
- @click =" toggleKernelConnections "
199
+ @click =" handleShowApiConnections "
77
200
:title =" t('home.overview.connections')"
78
- class =" statistics-card"
201
+ class =" statistics-card cursor-pointer "
79
202
>
80
203
<div class =" detail" >
81
204
{{ statistics.connections.length }}
@@ -100,48 +223,28 @@ onUnmounted(() => {
100
223
<Card
101
224
v-for =" mode in ModeOptions"
102
225
:key =" mode.value"
103
- :selected =" isActiveMode( mode.value) "
226
+ :selected =" kernelApiStore.config. mode === mode .value"
104
227
@click =" handleChangeMode(mode.value as any)"
105
228
:title =" t(mode.label)"
106
229
class =" mode-card"
107
230
>
108
- <div class =" desp " >{{ t(mode.desc) }}</div >
231
+ <div class =" desc " >{{ t(mode.desc) }}</div >
109
232
</Card >
110
233
</div >
111
234
</div >
112
235
</div >
113
236
114
- <Modal
115
- v-model:open =" showKernelConnections"
116
- :title =" t('home.overview.connections')"
117
- :submit =" false"
118
- mask-closable
119
- cancel-text =" common.close"
120
- width =" 90"
121
- height =" 90"
122
- >
123
- <div @wheel.stop =" ($event) => 0" style =" height : 100% " >
124
- <ConnectionsController />
125
- </div >
126
- </Modal >
237
+ <Modal />
127
238
</template >
128
239
129
240
<style lang="less" scoped>
130
241
.overview {
131
- margin-top : 20px ;
132
- .statistics {
133
- display : flex ;
134
- justify-content : space-between ;
135
- &-card {
136
- width : calc (100% / 4 - 8px );
137
- & :nth- child(3 ) {
138
- cursor : pointer ;
139
- }
140
- .detail {
141
- padding : 4px 0 ;
142
- font-size : 12px ;
143
- line-height : 2 ;
144
- }
242
+ .statistics-card {
243
+ flex : 1 ;
244
+ .detail {
245
+ padding : 4px 0 ;
246
+ font-size : 12px ;
247
+ line-height : 2 ;
145
248
}
146
249
}
147
250
@@ -163,7 +266,7 @@ onUnmounted(() => {
163
266
& :nth- child(3 ) {
164
267
margin : 12px 0 ;
165
268
}
166
- .desp {
269
+ .desc {
167
270
line-height : 20px ;
168
271
font-size : 12px ;
169
272
}
0 commit comments