@@ -13,7 +13,6 @@ import { Base64 } from "js-base64"
13
13
import { useResizeObserver , useWebSocket } from " @vueuse/core"
14
14
import { ws_uri } from " @/utils/const"
15
15
import { webttyRx , webttyTx } from " @/utils/webtty"
16
-
17
16
import { ActionEvent , actionBus } from " @/utils/action"
18
17
import " xterm/css/xterm.css"
19
18
@@ -22,23 +21,18 @@ const props = withDefaults(
22
21
/** The command to execute */
23
22
cmd: string
24
23
connected: boolean
24
+ rows? : number
25
+ backgroundColor? : string
25
26
}>(),
26
- { connected: true }
27
+ { connected: true , rows: 24 , backgroundColor: " #000 " }
27
28
)
28
29
const emit = defineEmits <{
29
30
(e : " update:connected" , connected : boolean ): void
30
31
}>()
31
- defineExpose ({ focus , fit })
32
+ defineExpose ({ focus })
32
33
33
34
const terminal = ref ()
34
35
35
- function fit() {
36
- fitAddon .fit ()
37
-
38
- term .refresh (0 , term .rows - 1 )
39
- console .log (" fit" )
40
- }
41
-
42
36
const term = new Terminal ({
43
37
rows: 24 ,
44
38
cols: 80 ,
@@ -51,25 +45,54 @@ const term = new Terminal({
51
45
})
52
46
const fitAddon = new FitAddon ()
53
47
54
- const { status, data, close, send, open } = useWebSocket (ws_uri + " pty" , {
48
+ const {
49
+ status : wsStatus,
50
+ data : wsData,
51
+ close : wsClose,
52
+ send : wsSend,
53
+ open : wsOpen,
54
+ } = useWebSocket (ws_uri + " pty" , {
55
55
immediate: false ,
56
56
})
57
57
58
+ onMounted (() => {
59
+ wsOpen ()
60
+ term .resize (80 , props .rows )
61
+ if (props .backgroundColor !== " " ) {
62
+ if (! term .options .theme ) {
63
+ term .options .theme = {}
64
+ }
65
+ term .options .theme .background = props .backgroundColor
66
+ }
67
+ term .loadAddon (fitAddon )
68
+ term .loadAddon (new WebglAddon ())
69
+ term .open (terminal .value )
70
+ term .writeln (` $ \x1B [1;3;31m${props .cmd }\x1B [0m ` )
71
+ focus ()
72
+ })
73
+
74
+ onBeforeUnmount (() => {
75
+ wsClose ()
76
+ if (term ) {
77
+ term .dispose ()
78
+ }
79
+ })
80
+
58
81
watch (
59
82
() => props .connected ,
60
83
(c : boolean ) => {
61
- if (c == false && status .value !== " CLOSED" ) {
62
- close () // the websocket
84
+ if (c == false && wsStatus .value !== " CLOSED" ) {
85
+ wsClose () // the websocket
63
86
return
64
87
}
65
- if (c && status .value === " CLOSED" ) {
66
- open ()
88
+ if (c && wsStatus .value === " CLOSED" ) {
89
+ wsOpen ()
67
90
term .writeln (` \n $ \x1B [1;3;31m${props .cmd }\x1B [0m` )
68
91
}
69
92
}
70
93
)
71
94
72
- watch (status , (value ) => {
95
+ watch (wsStatus , (value ) => {
73
96
if (value == " CLOSED" ) {
74
97
termDispose .map ((v ) => v .dispose ())
75
98
termDispose .splice (0 , termDispose .length )
@@ -82,7 +105,7 @@ watch(status, (value) => {
82
105
}
83
106
})
84
107
85
- watch (data , (val : string ) => {
108
+ watch (wsData , (val : string ) => {
86
109
const code = val .slice (0 , 1 )
87
110
const data = Base64 .decode (val .slice (1 ))
88
111
switch (code ) {
@@ -97,11 +120,11 @@ const termDispose: IDisposable[] = []
97
120
98
121
function termAttach(cmd : string ) {
99
122
// Send connection parameters
100
- send (JSON .stringify ({ cmd: cmd }))
123
+ wsSend (JSON .stringify ({ cmd: cmd }))
101
124
102
125
termDispose .push (
103
126
term .onResize ((size ) => {
104
- send (
127
+ wsSend (
105
128
webttyTx .ResizeTerminal +
106
129
JSON .stringify ({ Columns: size .cols , Rows: size .rows })
107
130
)
@@ -120,22 +143,22 @@ function termAttach(cmd: string) {
120
143
} else {
121
144
bufData = data
122
145
setTimeout (() => {
123
- send (webttyTx .Input + bufData )
146
+ wsSend (webttyTx .Input + bufData )
124
147
if (bufData .length > 1 ) {
125
148
console .log (` send ${bufData } ` )
126
149
}
127
150
bufData = " "
128
151
}, bufTime )
129
152
}
130
153
} else {
131
- send (webttyTx .Input + data )
154
+ wsSend (webttyTx .Input + data )
132
155
}
133
156
})
134
157
)
135
158
136
159
// send heartbeat to avoid server closing webSocket (i.e. nginx)
137
160
const heartBeatTimer = setInterval (function () {
138
- send (webttyTx .Ping )
161
+ wsSend (webttyTx .Ping )
139
162
}, 20 * 1000 )
140
163
termDispose .push ({
141
164
dispose : () => {
@@ -149,22 +172,6 @@ useResizeObserver(terminal, (el) => {
149
172
fitAddon .fit ()
150
173
})
151
174
152
- onMounted (() => {
153
- open ()
154
- term .loadAddon (fitAddon )
155
- term .loadAddon (new WebglAddon ())
156
- term .open (terminal .value )
157
- term .writeln (` $ \x1B [1;3;31m${props .cmd }\x1B [0m ` )
158
- focus ()
159
- })
160
-
161
- onBeforeUnmount (() => {
162
- close ()
163
- if (term ) {
164
- term .dispose ()
165
- }
166
- })
167
-
168
175
function focus() {
169
176
terminal .value ?.scrollIntoView ()
170
177
term .focus ()
0 commit comments