mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-09 19:48:45 +01:00
disconnected modal
This commit is contained in:
parent
bba43c8540
commit
9027edc0e1
142
src/main.tsx
142
src/main.tsx
@ -2488,113 +2488,82 @@ function sortAndFilterRemotes(origRemotes : RemoteType[]) : RemoteType[] {
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class AddRemoteModal extends React.Component<{}, {}> {
|
||||
@boundMethod
|
||||
handleModalClose() : void {
|
||||
mobx.action(() => {
|
||||
GlobalModel.addRemoteModalOpen.set(false);
|
||||
})();
|
||||
}
|
||||
class DisconnectedModal extends React.Component<{}, {}> {
|
||||
logRef : any = React.createRef();
|
||||
showLog : mobx.IObservableValue<boolean> = mobx.observable.box(false)
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="sc-modal add-remote-modal modal is-active">
|
||||
<div onClick={this.handleModalClose} className="modal-background"></div>
|
||||
<div className="modal-content message">
|
||||
<div className="message-header">
|
||||
<p>Add Remote</p>
|
||||
</div>
|
||||
<div className="message-content">
|
||||
hello
|
||||
</div>
|
||||
<div className="message-footer">
|
||||
<button onClick={this.handleModalClose} className="button">Cancel</button>
|
||||
<div className="spacer"></div>
|
||||
<button className="button is-primary">
|
||||
<span className="icon">
|
||||
<i className="fa fa-plus"/>
|
||||
</span>
|
||||
<span>Add Remote</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class RemoteModal extends React.Component<{}, {}> {
|
||||
@boundMethod
|
||||
handleModalClose() : void {
|
||||
mobx.action(() => {
|
||||
GlobalModel.remotesModalOpen.set(false);
|
||||
})();
|
||||
restartServer() {
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleAddRemote() : void {
|
||||
tryReconnect() {
|
||||
GlobalModel.ws.connectNow("manual");
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.logRef.current != null) {
|
||||
this.logRef.current.scrollTop = this.logRef.current.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.logRef.current != null) {
|
||||
this.logRef.current.scrollTop = this.logRef.current.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleShowLog() : void {
|
||||
mobx.action(() => {
|
||||
GlobalModel.addRemoteModalOpen.set(true);
|
||||
this.showLog.set(!this.showLog.get());
|
||||
})();
|
||||
}
|
||||
|
||||
render() {
|
||||
let model = GlobalModel;
|
||||
let remotes = sortAndFilterRemotes(model.remotes);
|
||||
let remote : RemoteType = null;
|
||||
let logLine : string = null;
|
||||
let idx : number = 0;
|
||||
return (
|
||||
<div className="sc-modal remote-modal modal is-active">
|
||||
<div onClick={this.handleModalClose} className="modal-background"></div>
|
||||
<div className="sc-modal disconnected-modal modal is-active">
|
||||
<div className="modal-background"></div>
|
||||
<div className="modal-content message">
|
||||
<div className="message-header">
|
||||
<p>Remotes</p>
|
||||
<p>ScriptHaus Client Disconnected</p>
|
||||
</div>
|
||||
<If condition={this.showLog.get()}>
|
||||
<div className="message-content">
|
||||
<table className="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="status-header">Status</th>
|
||||
<th>Alias</th>
|
||||
<th>User@Host</th>
|
||||
<th>Connect</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<For each="remote" of={remotes}>
|
||||
<tr key={remote.remoteid}>
|
||||
<td className="status-cell">
|
||||
<div><RemoteStatusLight remote={remote}/></div>
|
||||
</td>
|
||||
<td>
|
||||
{remote.remotealias}
|
||||
<If condition={isBlank(remote.remotealias)}>
|
||||
-
|
||||
</If>
|
||||
</td>
|
||||
<td>
|
||||
{remote.remotecanonicalname}
|
||||
</td>
|
||||
<td>
|
||||
{remote.connectmode}
|
||||
</td>
|
||||
</tr>
|
||||
<div className="ws-log" ref={this.logRef}>
|
||||
<For each="logLine" index="idx" of={GlobalModel.ws.wsLog}>
|
||||
<div key={idx} className="ws-logline">{logLine}</div>
|
||||
</For>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</If>
|
||||
<div className="message-footer">
|
||||
<button onClick={this.handleAddRemote} className="button is-primary">
|
||||
<div className="footer-text-link" style={{marginLeft: 10}} onClick={this.handleShowLog}>
|
||||
<If condition={!this.showLog.get()}>
|
||||
<i className="fa fa-plus"/> Show Log
|
||||
</If>
|
||||
<If condition={this.showLog.get()}>
|
||||
<i className="fa fa-minus"/> Hide Log
|
||||
</If>
|
||||
</div>
|
||||
<div className="spacer"/>
|
||||
<button onClick={this.tryReconnect} className="button">
|
||||
<span className="icon">
|
||||
<i className="fa fa-plus"/>
|
||||
<i className="fa fa-refresh"/>
|
||||
</span>
|
||||
<span>Add Remote</span>
|
||||
<span>Try Reconnect</span>
|
||||
</button>
|
||||
<button onClick={this.restartServer} className="button is-danger" style={{marginLeft: 10}}>
|
||||
<span className="icon">
|
||||
<i className="fa fa-exclamation-triangle"/>
|
||||
</span>
|
||||
<span>Restart Server</span>
|
||||
</button>
|
||||
<div className="spacer"></div>
|
||||
<button onClick={this.handleModalClose} className="button">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<button onClick={this.handleModalClose} className="modal-close is-large" aria-label="close"></button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -2617,11 +2586,8 @@ class Main extends React.Component<{}, {}> {
|
||||
<MainSideBar/>
|
||||
<SessionView/>
|
||||
</div>
|
||||
<If condition={GlobalModel.addRemoteModalOpen.get()}>
|
||||
<AddRemoteModal/>
|
||||
</If>
|
||||
<If condition={GlobalModel.remotesModalOpen.get() && !GlobalModel.addRemoteModalOpen.get()}>
|
||||
<RemoteModal/>
|
||||
<If condition={!GlobalModel.ws.open.get()}>
|
||||
<DisconnectedModal/>
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
|
@ -1525,8 +1525,6 @@ class Model {
|
||||
windows : OMap<string, Window> = mobx.observable.map({}, {name: "windows", deep: false}); // key = "sessionid/windowid"
|
||||
inputModel : InputModel;
|
||||
termUsedRowsCache : Record<string, number> = {};
|
||||
remotesModalOpen : OV<boolean> = mobx.observable.box(false);
|
||||
addRemoteModalOpen : OV<boolean> = mobx.observable.box(false);
|
||||
debugCmds : number = 0;
|
||||
debugSW : OV<boolean> = mobx.observable.box(false);
|
||||
|
||||
@ -1653,7 +1651,7 @@ class Model {
|
||||
}
|
||||
|
||||
cmdStatusUpdate(sessionId : string, cmdId : string, origStatus : string, newStatus : string) {
|
||||
console.log("cmd status", sessionId, cmdId, origStatus, "=>", newStatus);
|
||||
// console.log("cmd status", sessionId, cmdId, origStatus, "=>", newStatus);
|
||||
let lines = this.getActiveLinesByCmdId(sessionId, cmdId);
|
||||
for (let ptr of lines) {
|
||||
let sw = ptr.sw;
|
||||
@ -2290,7 +2288,7 @@ function cmdPacketString(pk : FeCmdPacketType) : string {
|
||||
|
||||
let GlobalModel : Model = null;
|
||||
let GlobalCommandRunner : CommandRunner = null;
|
||||
if ((window as any).GlobalModal == null) {
|
||||
if ((window as any).GlobalModel == null) {
|
||||
(window as any).GlobalModel = new Model();
|
||||
(window as any).GlobalCommandRunner = new CommandRunner();
|
||||
}
|
||||
|
45
src/sh2.less
45
src/sh2.less
@ -1330,9 +1330,11 @@ input[type=checkbox] {
|
||||
.sc-modal {
|
||||
.modal-content {
|
||||
padding: 10px;
|
||||
background-color: #666;
|
||||
|
||||
.message-header {
|
||||
font-size: 20px;
|
||||
.mono-font();
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@ -1342,43 +1344,44 @@ input[type=checkbox] {
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.message-footer {
|
||||
border-top: 1px solid #666;
|
||||
padding-top: 15px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.footer-text-link {
|
||||
.mono-font(12px);
|
||||
color: @term-white;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
.mono-font();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remote-modal {
|
||||
.disconnected-modal {
|
||||
.message-content {
|
||||
.table {
|
||||
th.status-header {
|
||||
width: 40px;
|
||||
}
|
||||
.ws-log {
|
||||
padding: 5px;
|
||||
background-color: black;
|
||||
height: 250px;
|
||||
overflow: auto;
|
||||
|
||||
tbody td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.status-cell {
|
||||
.remote-status {
|
||||
font-size: 16px;
|
||||
top: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 12px;
|
||||
}
|
||||
.ws-logline {
|
||||
.mono-font(12px);
|
||||
color: @term-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
70
src/ws.ts
70
src/ws.ts
@ -2,6 +2,7 @@ import * as mobx from "mobx";
|
||||
import {sprintf} from "sprintf-js";
|
||||
import {boundMethod} from "autobind-decorator";
|
||||
import {WatchScreenPacketType} from "./types";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
class WSControl {
|
||||
wsConn : any;
|
||||
@ -13,6 +14,7 @@ class WSControl {
|
||||
messageCallback : (any) => void = null;
|
||||
watchSessionId : string = null;
|
||||
watchScreenId : string = null;
|
||||
wsLog : mobx.IObservableArray<string> = mobx.observable.array([], {name: "wsLog"})
|
||||
|
||||
constructor(clientId : string, messageCallback : (any) => void) {
|
||||
this.messageCallback = messageCallback;
|
||||
@ -21,19 +23,47 @@ class WSControl {
|
||||
setInterval(this.sendPing, 5000);
|
||||
}
|
||||
|
||||
@mobx.action
|
||||
setOpen(val : boolean) {
|
||||
this.open.set(val);
|
||||
log(str : string) {
|
||||
mobx.action(() => {
|
||||
let ts = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||
this.wsLog.push("[" + ts + "] " + str);
|
||||
if (this.wsLog.length > 50) {
|
||||
this.wsLog.splice(0, this.wsLog.length-50);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
reconnect() {
|
||||
@mobx.action
|
||||
setOpen(val : boolean) {
|
||||
mobx.action(() => {
|
||||
this.open.set(val);
|
||||
})();
|
||||
}
|
||||
|
||||
connectNow(desc : string) {
|
||||
if (this.open.get()) {
|
||||
return;
|
||||
}
|
||||
this.log(sprintf("try reconnect (%s)", desc));
|
||||
this.opening = true;
|
||||
this.wsConn = new WebSocket("ws://localhost:8081/ws?clientid=" + this.clientId);
|
||||
this.wsConn.onopen = this.onopen;
|
||||
this.wsConn.onmessage = this.onmessage;
|
||||
this.wsConn.onclose = this.onclose;
|
||||
// turns out onerror is not necessary (onclose always follows onerror)
|
||||
// this.wsConn.onerror = this.onerror;
|
||||
}
|
||||
|
||||
reconnect(forceClose? : boolean) {
|
||||
if (this.open.get()) {
|
||||
if (forceClose) {
|
||||
this.wsConn.close(); // this will force a reconnect
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.reconnectTimes++;
|
||||
if (this.reconnectTimes > 20) {
|
||||
console.log("websocket cannot connect, giving up");
|
||||
this.log("cannot connect, giving up");
|
||||
return;
|
||||
}
|
||||
let timeoutArr = [0, 0, 2, 5, 10, 10, 30, 60];
|
||||
@ -42,32 +72,22 @@ class WSControl {
|
||||
timeout = timeoutArr[this.reconnectTimes];
|
||||
}
|
||||
if (timeout > 0) {
|
||||
console.log(sprintf("websocket reconnect(%d), sleep %ds", this.reconnectTimes, timeout));
|
||||
this.log(sprintf("sleeping %ds", timeout));
|
||||
}
|
||||
setTimeout(() => {
|
||||
console.log(sprintf("websocket reconnect(%d)", this.reconnectTimes));
|
||||
this.opening = true;
|
||||
this.wsConn = new WebSocket("ws://localhost:8081/ws?clientid=" + this.clientId);
|
||||
this.wsConn.onopen = this.onopen;
|
||||
this.wsConn.onmessage = this.onmessage;
|
||||
this.wsConn.onerror = this.onerror;
|
||||
this.wsConn.onclose = this.onclose;
|
||||
this.connectNow(String(this.reconnectTimes));
|
||||
}, timeout*1000);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
onerror(event : any) {
|
||||
console.log("websocket error", event);
|
||||
if (this.open.get() || this.opening) {
|
||||
this.setOpen(false);
|
||||
this.opening = false;
|
||||
this.reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
onclose(event : any) {
|
||||
console.log("websocket closed", event);
|
||||
console.log("close", event);
|
||||
if (event.wasClean) {
|
||||
this.log("connection closed");
|
||||
}
|
||||
else {
|
||||
this.log("connection error/disconnected");
|
||||
}
|
||||
if (this.open.get() || this.opening) {
|
||||
this.setOpen(false);
|
||||
this.opening = false;
|
||||
@ -77,7 +97,7 @@ class WSControl {
|
||||
|
||||
@boundMethod
|
||||
onopen() {
|
||||
console.log("websocket open");
|
||||
this.log("connection open");
|
||||
this.setOpen(true);
|
||||
this.opening = false;
|
||||
this.runMsgQueue();
|
||||
|
Loading…
Reference in New Issue
Block a user