mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
checkpoint, getting screens integrated
This commit is contained in:
parent
4666ee8832
commit
059c98d1e0
91
src/main.tsx
91
src/main.tsx
@ -9,7 +9,7 @@ import cn from "classnames"
|
||||
import {TermWrap} from "./term";
|
||||
import type {SessionDataType, LineType, CmdDataType, RemoteType} from "./types";
|
||||
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
||||
import {GlobalModel, Session, Cmd, Window} from "./model";
|
||||
import {GlobalModel, Session, Cmd, Window, Screen, ScreenWindow} from "./model";
|
||||
|
||||
dayjs.extend(localizedFormat)
|
||||
|
||||
@ -340,7 +340,7 @@ class CmdInput extends React.Component<{}, {}> {
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class WindowView extends React.Component<{windowId : string}, {}> {
|
||||
class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
|
||||
mutObs : any;
|
||||
|
||||
scrollToBottom() {
|
||||
@ -352,11 +352,11 @@ class WindowView extends React.Component<{windowId : string}, {}> {
|
||||
|
||||
@boundMethod
|
||||
scrollHandler(event : any) {
|
||||
let {sw} = this.props;
|
||||
let target = event.target;
|
||||
let atBottom = (target.scrollTop + 30 > (target.scrollHeight - target.offsetHeight));
|
||||
let win = this.getWindow();
|
||||
if (win.shouldFollow.get() != atBottom) {
|
||||
mobx.action(() => win.shouldFollow.set(atBottom));
|
||||
if (sw && sw.shouldFollow.get() != atBottom) {
|
||||
mobx.action(() => sw.shouldFollow.set(atBottom));
|
||||
}
|
||||
// console.log("scroll-handler>", atBottom, target.scrollTop, target.scrollHeight);
|
||||
}
|
||||
@ -376,42 +376,37 @@ class WindowView extends React.Component<{windowId : string}, {}> {
|
||||
}
|
||||
|
||||
handleDomMutation(mutations, mutObs) {
|
||||
let win = this.getWindow();
|
||||
if (win && win.shouldFollow.get()) {
|
||||
let {sw} = this.props;
|
||||
if (sw && sw.shouldFollow.get()) {
|
||||
setTimeout(() => this.scrollToBottom(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
getWindow() : Window {
|
||||
let {windowId} = this.props;
|
||||
if (windowId == null) {
|
||||
return null;
|
||||
}
|
||||
let model = GlobalModel;
|
||||
let session = model.getActiveSession();
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
let win = session.getWindowById(windowId);
|
||||
return win;
|
||||
let {sw} = this.props;
|
||||
return GlobalModel.getWindowById(sw.sessionId, sw.windowId);
|
||||
}
|
||||
|
||||
getLinesId() {
|
||||
let {windowId} = this.props;
|
||||
return "window-lines-" + windowId;
|
||||
let {sw} = this.props;
|
||||
return "window-lines-" + sw.windowId;
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleTermResize(e : any) {
|
||||
let win = this.getWindow();
|
||||
if (win && win.shouldFollow.get()) {
|
||||
let {sw} = this.props;
|
||||
if (sw && sw.shouldFollow.get()) {
|
||||
setTimeout(() => this.scrollToBottom(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
getWindowViewStyle() : any {
|
||||
return {width: "100%", height: "100%"};
|
||||
}
|
||||
|
||||
renderError(message : string) {
|
||||
return (
|
||||
<div className="window-view">
|
||||
<div className="window-view" style={this.getWindowViewStyle()}>
|
||||
<div className="lines" onScroll={this.scrollHandler} id={this.getLinesId()}>
|
||||
{message}
|
||||
</div>
|
||||
@ -420,17 +415,18 @@ class WindowView extends React.Component<{windowId : string}, {}> {
|
||||
}
|
||||
|
||||
render() {
|
||||
let win = this.getWindow();
|
||||
if (win == null) {
|
||||
return this.renderError("(no window)");
|
||||
let {sw} = this.props;
|
||||
if (sw == null) {
|
||||
return this.renderError("(no screen window)");
|
||||
}
|
||||
let win = this.getWindow();
|
||||
if (!win.linesLoaded.get()) {
|
||||
return this.renderError("(loading)");
|
||||
}
|
||||
let idx = 0;
|
||||
let line : LineType = null;
|
||||
return (
|
||||
<div className="window-view">
|
||||
<div className="window-view" style={this.getWindowViewStyle()}>
|
||||
<div className="lines" onScroll={this.scrollHandler} id={this.getLinesId()}>
|
||||
<For each="line" of={win.lines} index="idx">
|
||||
<Line key={line.lineid} line={line}/>
|
||||
@ -441,6 +437,42 @@ class WindowView extends React.Component<{windowId : string}, {}> {
|
||||
}
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class ScreenView extends React.Component<{screen : Screen}, {}> {
|
||||
render() {
|
||||
let {screen} = this.props;
|
||||
if (screen == null) {
|
||||
return (
|
||||
<div className="screen-view">
|
||||
(no screen)
|
||||
</div>
|
||||
);
|
||||
}
|
||||
let sw = screen.getActiveSW();
|
||||
return (
|
||||
<div className="screen-view">
|
||||
<ScreenWindowView sw={sw}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class ScreenTabs extends React.Component<{}, {}> {
|
||||
render() {
|
||||
let model = GlobalModel;
|
||||
let session = model.getActiveSession();
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className="screen-tabs">
|
||||
tabs!
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class SessionView extends React.Component<{}, {}> {
|
||||
render() {
|
||||
@ -449,10 +481,11 @@ class SessionView extends React.Component<{}, {}> {
|
||||
if (session == null) {
|
||||
return <div className="session-view">(no active session)</div>;
|
||||
}
|
||||
let curWindowId = session.curWindowId.get();
|
||||
let activeScreen = session.getActiveScreen();
|
||||
return (
|
||||
<div className="session-view">
|
||||
<WindowView windowId={curWindowId}/>
|
||||
<ScreenView screen={activeScreen}/>
|
||||
<ScreenTabs/>
|
||||
<CmdInput/>
|
||||
</div>
|
||||
);
|
||||
|
144
src/model.ts
144
src/model.ts
@ -4,7 +4,7 @@ import {boundMethod} from "autobind-decorator";
|
||||
import {handleJsonFetchResponse} from "./util";
|
||||
import {TermWrap} from "./term";
|
||||
import {v4 as uuidv4} from "uuid";
|
||||
import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, RemoteInstanceType, CmdDataType, FeCmdPacketType, TermOptsType, RemoteStateType} from "./types";
|
||||
import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, RemoteInstanceType, CmdDataType, FeCmdPacketType, TermOptsType, RemoteStateType, ScreenDataType, ScreenWindowType, ScreenOptsType, LayoutType} from "./types";
|
||||
import {WSControl} from "./ws";
|
||||
|
||||
var GlobalUser = "sawka";
|
||||
@ -26,6 +26,14 @@ function getApi() : ElectronApi {
|
||||
return (window as any).api;
|
||||
}
|
||||
|
||||
// clean empty string
|
||||
function ces(s : string) {
|
||||
if (s == "") {
|
||||
return null;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
class Cmd {
|
||||
sessionId : string;
|
||||
windowId : string;
|
||||
@ -199,23 +207,90 @@ class Cmd {
|
||||
}
|
||||
};
|
||||
|
||||
class Screen {
|
||||
sessionId : string;
|
||||
screenId : string;
|
||||
opts : OV<ScreenOptsType>;
|
||||
name : OV<string>;
|
||||
activeWindowId : OV<string>;
|
||||
windows : OArr<ScreenWindow>;
|
||||
|
||||
constructor(sdata : ScreenDataType) {
|
||||
this.sessionId = sdata.sessionid;
|
||||
this.screenId = sdata.screenid;
|
||||
this.name = mobx.observable.box(sdata.name);
|
||||
this.opts = mobx.observable.box(sdata.screenopts);
|
||||
this.activeWindowId = mobx.observable.box(ces(sdata.activewindowid));
|
||||
let swArr : ScreenWindow[] = [];
|
||||
let wins = sdata.windows || [];
|
||||
for (let i=0; i<wins.length; i++) {
|
||||
let sw = new ScreenWindow(wins[i]);
|
||||
swArr.push(sw);
|
||||
}
|
||||
this.windows = mobx.observable.array(swArr, {deep: false})
|
||||
}
|
||||
|
||||
getActiveWindow() : Window {
|
||||
let session = GlobalModel.getSessionById(this.sessionId);
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
return session.getWindowById(this.activeWindowId.get());
|
||||
}
|
||||
|
||||
getActiveSW() : ScreenWindow {
|
||||
return this.getSW(this.activeWindowId.get());
|
||||
}
|
||||
|
||||
getSW(windowId : string) : ScreenWindow {
|
||||
if (windowId == null) {
|
||||
return null;
|
||||
}
|
||||
for (let i=0; i<this.windows.length; i++) {
|
||||
if (this.windows[i].windowId == windowId) {
|
||||
return this.windows[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class ScreenWindow {
|
||||
sessionId : string;
|
||||
screenId : string;
|
||||
windowId : string;
|
||||
name : OV<string>;
|
||||
layout : OV<LayoutType>;
|
||||
shouldFollow : OV<boolean> = mobx.observable.box(true);
|
||||
|
||||
constructor(swdata : ScreenWindowType) {
|
||||
this.sessionId = swdata.sessionid;
|
||||
this.screenId = swdata.screenid;
|
||||
this.windowId = swdata.windowid;
|
||||
this.name = mobx.observable.box(swdata.name);
|
||||
this.layout = mobx.observable.box(swdata.layout);
|
||||
}
|
||||
|
||||
getWindow() : Window {
|
||||
return GlobalModel.getWindowById(this.sessionId, this.windowId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Window {
|
||||
sessionId : string;
|
||||
windowId : string;
|
||||
name : OV<string>;
|
||||
curRemote : OV<string>;
|
||||
loaded : OV<boolean> = mobx.observable.box(false);
|
||||
lines : OArr<LineType> = mobx.observable.array([]);
|
||||
lines : OArr<LineType> = mobx.observable.array([], {deep: false});
|
||||
linesLoaded : OV<boolean> = mobx.observable.box(false);
|
||||
history : any[] = [];
|
||||
cmds : Record<string, Cmd> = {};
|
||||
shouldFollow : OV<boolean> = mobx.observable.box(true);
|
||||
remoteInstances : OArr<RemoteInstanceType> = mobx.observable.array([]);
|
||||
|
||||
constructor(wdata : WindowDataType) {
|
||||
this.sessionId = wdata.sessionid;
|
||||
this.windowId = wdata.windowid;
|
||||
this.name = mobx.observable.box(wdata.name);
|
||||
this.curRemote = mobx.observable.box(wdata.curremote);
|
||||
}
|
||||
|
||||
@ -229,9 +304,6 @@ class Window {
|
||||
|
||||
updateWindow(win : WindowDataType, isActive : boolean) {
|
||||
mobx.action(() => {
|
||||
if (!isBlank(win.name)) {
|
||||
this.name.set(win.name)
|
||||
}
|
||||
if (!isBlank(win.curremote)) {
|
||||
this.curRemote.set(win.curremote);
|
||||
}
|
||||
@ -277,7 +349,7 @@ class Window {
|
||||
let remote = GlobalModel.getRemoteByName(rname);
|
||||
if (remote != null) {
|
||||
return {riid: "", sessionid: this.sessionId, windowid: this.windowId, remoteid: remote.remoteid,
|
||||
name: rname, state: remote.defaultstate, sessionscope: false, version: 0};
|
||||
name: rname, state: remote.defaultstate, sessionscope: false};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -314,7 +386,8 @@ class Window {
|
||||
class Session {
|
||||
sessionId : string;
|
||||
name : OV<string>;
|
||||
curWindowId : OV<string>;
|
||||
activeScreenId : OV<string>;
|
||||
screens : OArr<Screen>;
|
||||
windows : OArr<Window>;
|
||||
notifyNum : OV<number> = mobx.observable.box(0);
|
||||
remoteInstances : OArr<RemoteInstanceType> = mobx.observable.array([]);
|
||||
@ -328,8 +401,15 @@ class Session {
|
||||
let win = new Window(winData[i]);
|
||||
wins.push(win);
|
||||
}
|
||||
this.windows = mobx.observable.array(wins);
|
||||
this.curWindowId = mobx.observable.box((wins.length == 0 ? null : wins[0].windowId));
|
||||
this.windows = mobx.observable.array(wins, {deep: false});
|
||||
let screenData = sdata.screens || [];
|
||||
let screens : Screen[] = [];
|
||||
for (let i=0; i<screenData.length; i++) {
|
||||
let screen = new Screen(screenData[i]);
|
||||
screens.push(screen);
|
||||
}
|
||||
this.screens = mobx.observable.array(screens, {deep: false});
|
||||
this.activeScreenId = mobx.observable.box(ces(sdata.activescreenid));
|
||||
}
|
||||
|
||||
updateWindow(win : WindowDataType, isActive : boolean) {
|
||||
@ -364,8 +444,20 @@ class Session {
|
||||
return null;
|
||||
}
|
||||
|
||||
getActiveWindow() : Window {
|
||||
return this.getWindowById(this.curWindowId.get());
|
||||
getActiveScreen() : Screen {
|
||||
return this.getScreenById(this.activeScreenId.get());
|
||||
}
|
||||
|
||||
getScreenById(screenId : string) : Screen {
|
||||
if (screenId == null) {
|
||||
return null;
|
||||
}
|
||||
for (let i=0; i<this.screens.length; i++) {
|
||||
if (this.screens[i].screenId == screenId) {
|
||||
return this.screens[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getRemoteInstance(rname : string) : RemoteInstanceType {
|
||||
@ -378,7 +470,7 @@ class Session {
|
||||
let remote = GlobalModel.getRemoteByName(rname);
|
||||
if (remote != null) {
|
||||
return {riid: "", sessionid: this.sessionId, windowid: null, remoteid: remote.remoteid,
|
||||
name: rname, state: remote.defaultstate, sessionscope: true, version: 0};
|
||||
name: rname, state: remote.defaultstate, sessionscope: true};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -395,7 +487,7 @@ class Model {
|
||||
clientId : string;
|
||||
curSessionId : OV<string> = mobx.observable.box(null);
|
||||
sessionListLoaded : OV<boolean> = mobx.observable.box(false);
|
||||
sessionList : OArr<Session> = mobx.observable.array([], {name: "SessionList"});
|
||||
sessionList : OArr<Session> = mobx.observable.array([], {name: "SessionList", deep: false});
|
||||
ws : WSControl;
|
||||
remotes : OArr<RemoteType> = mobx.observable.array([], {deep: false});
|
||||
remotesLoaded : OV<boolean> = mobx.observable.box(false);
|
||||
@ -442,12 +534,28 @@ class Model {
|
||||
return null;
|
||||
}
|
||||
|
||||
getWindowById(sessionId : string, windowId : string) : Window {
|
||||
let session = this.getSessionById(sessionId);
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
return session.getWindowById(windowId);
|
||||
}
|
||||
|
||||
getActiveWindow() : Window {
|
||||
let screen = this.getActiveScreen();
|
||||
if (screen == null) {
|
||||
return null;
|
||||
}
|
||||
return screen.getActiveWindow();
|
||||
}
|
||||
|
||||
getActiveScreen() : Screen {
|
||||
let session = this.getActiveSession();
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
return session.getActiveWindow();
|
||||
return session.getActiveScreen();
|
||||
}
|
||||
|
||||
addLineCmd(line : LineType, cmd : CmdDataType, interactive : boolean) {
|
||||
@ -592,6 +700,6 @@ if ((window as any).GlobalModal == null) {
|
||||
}
|
||||
GlobalModel = (window as any).GlobalModel;
|
||||
|
||||
export {Model, Session, Window, GlobalModel, Cmd};
|
||||
export {Model, Session, Window, GlobalModel, Cmd, Screen, ScreenWindow};
|
||||
|
||||
|
||||
|
18
src/sh2.less
18
src/sh2.less
@ -17,12 +17,20 @@ html, body, #main {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.window-view {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.screen-tabs {
|
||||
height: 50px;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.screen-view {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.window-view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
45
src/types.ts
45
src/types.ts
@ -3,7 +3,10 @@ import * as mobx from "mobx";
|
||||
type SessionDataType = {
|
||||
sessionid : string,
|
||||
name : string,
|
||||
activescreenid : string,
|
||||
windows : WindowDataType[],
|
||||
screens : ScreenDataType[],
|
||||
screenwindows : ScreenWindowType[],
|
||||
cmds : CmdDataType[],
|
||||
remove : boolean,
|
||||
};
|
||||
@ -19,6 +22,41 @@ type LineType = {
|
||||
cmdid : string,
|
||||
};
|
||||
|
||||
type ScreenOptsType = {
|
||||
tabcolor? : string,
|
||||
}
|
||||
|
||||
type ScreenDataType = {
|
||||
sessionid : string,
|
||||
screenid : string,
|
||||
screenidx : number,
|
||||
activewindowid : string,
|
||||
name : string,
|
||||
windows : ScreenWindowType[],
|
||||
screenopts : ScreenOptsType,
|
||||
};
|
||||
|
||||
type LayoutType = {
|
||||
type : string,
|
||||
parent? : string,
|
||||
zindex? : number,
|
||||
float? : boolean,
|
||||
top? : string,
|
||||
bottom? : string,
|
||||
left? : string,
|
||||
right? : string,
|
||||
width? : string,
|
||||
height? : string,
|
||||
};
|
||||
|
||||
type ScreenWindowType = {
|
||||
sessionid : string,
|
||||
screenid : string,
|
||||
windowid : string,
|
||||
name : string,
|
||||
layout : LayoutType,
|
||||
};
|
||||
|
||||
type RemoteType = {
|
||||
remotetype : string,
|
||||
remoteid : string,
|
||||
@ -40,19 +78,16 @@ type RemoteInstanceType = {
|
||||
remoteid : string,
|
||||
sessionscope : boolean,
|
||||
state : RemoteStateType,
|
||||
version : number,
|
||||
}
|
||||
|
||||
type WindowDataType = {
|
||||
sessionid : string,
|
||||
windowid : string,
|
||||
name : string,
|
||||
curremote : string,
|
||||
lines : LineType[],
|
||||
history : HistoryItem[],
|
||||
cmds : CmdDataType[],
|
||||
remotes : RemoteInstanceType[],
|
||||
version : number,
|
||||
remove : boolean,
|
||||
};
|
||||
|
||||
@ -78,7 +113,7 @@ type FeCmdPacketType = {
|
||||
type TermOptsType = {
|
||||
rows : number,
|
||||
cols : number,
|
||||
flexrows : boolean,
|
||||
flexrows? : boolean,
|
||||
};
|
||||
|
||||
type CmdStartPacketType = {
|
||||
@ -112,4 +147,4 @@ type CmdDataType = {
|
||||
usedrows : number,
|
||||
};
|
||||
|
||||
export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDonePacketType, CmdDataType};
|
||||
export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDonePacketType, CmdDataType, ScreenDataType, ScreenOptsType, ScreenWindowType, LayoutType};
|
||||
|
Loading…
Reference in New Issue
Block a user