mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
Add indicator to tabs and workspaces to show when commands are running (#254)
* save * not working yet but close * logic is working, just need to do styling * save work * save * save work * ta da! * fix line height * format files * remove running commands on hangup. also don't allow numrunning to be less than 0 * remove < 0 check (safer without for concurrency)
This commit is contained in:
+4
-4
@@ -121,7 +121,7 @@ svg.icon {
|
||||
|
||||
.hideScrollbarUntillHover {
|
||||
overflow: scroll;
|
||||
|
||||
|
||||
&::-webkit-scrollbar-thumb,
|
||||
&::-webkit-scrollbar-track {
|
||||
display: none;
|
||||
@@ -630,13 +630,13 @@ a.a-block {
|
||||
|
||||
.spin {
|
||||
animation: infiniteRotate 2s linear infinite;
|
||||
|
||||
|
||||
@keyframes infiniteRotate {
|
||||
from {
|
||||
transform:rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform:rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg width="440" height="440" version="1.1" viewBox="0 0 116.42 116.42" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="spinner" transform="matrix(1 -.0017046 0 1 0 0)" d="m111.01 58.273a52.939 52.939 0 0 1-52.939 52.939" fill="none" stroke="#000" stroke-width="9.0869"/>
|
||||
<circle id="indicator" cx="58.208" cy="58.208" r="39.688" stroke-width=".26657"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 458 B |
@@ -405,7 +405,7 @@
|
||||
padding: 6px 6px 6px 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
|
||||
pre.selected {
|
||||
outline: 2px solid @term-green;
|
||||
}
|
||||
|
||||
@@ -288,7 +288,8 @@ class Button extends React.Component<ButtonProps> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { leftIcon, rightIcon, theme, children, disabled, variant, color, style, autoFocus, className } = this.props;
|
||||
const { leftIcon, rightIcon, theme, children, disabled, variant, color, style, autoFocus, className } =
|
||||
this.props;
|
||||
|
||||
return (
|
||||
<button
|
||||
|
||||
@@ -30,7 +30,10 @@
|
||||
line-height: inherit;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
& > div,i,.svg-icon,span {
|
||||
& > div,
|
||||
i,
|
||||
.svg-icon,
|
||||
span {
|
||||
width: 20px;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
@@ -46,13 +49,28 @@
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
.error {
|
||||
color: @term-red;
|
||||
svg {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
.success {
|
||||
color: @term-green;
|
||||
#spinner,
|
||||
#indicator {
|
||||
visibility: hidden;
|
||||
}
|
||||
.output {
|
||||
color: @term-white;
|
||||
.spin #spinner {
|
||||
visibility: visible;
|
||||
stroke: @term-white;
|
||||
}
|
||||
&.error #indicator {
|
||||
visibility: visible;
|
||||
fill: @term-red;
|
||||
}
|
||||
&.success #indicator {
|
||||
visibility: visible;
|
||||
fill: @term-green;
|
||||
}
|
||||
&.output #indicator {
|
||||
visibility: visible;
|
||||
fill: @term-white;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from "react";
|
||||
import { StatusIndicatorLevel } from "../../../types/types";
|
||||
import cn from "classnames";
|
||||
import { ReactComponent as SpinnerIndicator } from "../../assets/icons/spinner-indicator.svg";
|
||||
|
||||
interface PositionalIconProps {
|
||||
children?: React.ReactNode;
|
||||
@@ -45,28 +46,29 @@ export class ActionsIcon extends React.Component<ActionsIconProps> {
|
||||
interface StatusIndicatorProps {
|
||||
level: StatusIndicatorLevel;
|
||||
className?: string;
|
||||
runningCommands?: boolean;
|
||||
}
|
||||
|
||||
export class StatusIndicator extends React.Component<StatusIndicatorProps> {
|
||||
render() {
|
||||
const statusIndicatorLevel = this.props.level;
|
||||
const { level, className, runningCommands } = this.props;
|
||||
let statusIndicator = null;
|
||||
if (statusIndicatorLevel != StatusIndicatorLevel.None) {
|
||||
let statusIndicatorClass = null;
|
||||
switch (statusIndicatorLevel) {
|
||||
if (level != StatusIndicatorLevel.None || runningCommands) {
|
||||
let levelClass = null;
|
||||
switch (level) {
|
||||
case StatusIndicatorLevel.Output:
|
||||
statusIndicatorClass = "output";
|
||||
levelClass = "output";
|
||||
break;
|
||||
case StatusIndicatorLevel.Success:
|
||||
statusIndicatorClass = "success";
|
||||
levelClass = "success";
|
||||
break;
|
||||
case StatusIndicatorLevel.Error:
|
||||
statusIndicatorClass = "error";
|
||||
levelClass = "error";
|
||||
break;
|
||||
}
|
||||
statusIndicator = (
|
||||
<CenteredIcon className={cn(this.props.className, "status-indicator")}>
|
||||
<div className={cn(statusIndicatorClass, "fa-sharp", "fa-solid", "fa-circle-small")}></div>
|
||||
<CenteredIcon className={cn(className, levelClass, "status-indicator")}>
|
||||
<SpinnerIndicator className={runningCommands ? "spin" : null} />
|
||||
</CenteredIcon>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -206,6 +206,10 @@
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.end-icons {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.fa-discord {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
@@ -187,13 +187,18 @@ class MainSideBar extends React.Component<{}, {}> {
|
||||
const isActive = GlobalModel.activeMainView.get() == "session" && activeSessionId == session.sessionId;
|
||||
const sessionScreens = GlobalModel.getSessionScreens(session.sessionId);
|
||||
const sessionIndicator = Math.max(...sessionScreens.map((screen) => screen.statusIndicator.get()));
|
||||
const sessionRunningCommands = sessionScreens.some((screen) => screen.numRunningCmds.get() > 0);
|
||||
return (
|
||||
<SideBarItem
|
||||
className={`${isActive ? "active" : ""}`}
|
||||
frontIcon={<span className="index">{index + 1}</span>}
|
||||
contents={session.name.get()}
|
||||
endIcons={[
|
||||
<StatusIndicator key="statusindicator" level={sessionIndicator} />,
|
||||
<StatusIndicator
|
||||
key="statusindicator"
|
||||
level={sessionIndicator}
|
||||
runningCommands={sessionRunningCommands}
|
||||
/>,
|
||||
<ActionsIcon key="actions" onClick={(e) => this.openSessionSettings(e, session)} />,
|
||||
]}
|
||||
onClick={() => this.handleSessionClick(session.sessionId)}
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
.cmd-input-filter {
|
||||
opacity: 0.5;
|
||||
&:hover {
|
||||
opacity: 1.0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
@@ -198,14 +198,14 @@
|
||||
opacity: 0.5;
|
||||
|
||||
&:hover {
|
||||
opacity: 1.0;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cmd-aichat {
|
||||
|
||||
.cmd-aichat {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
flex-flow: column nowrap;
|
||||
@@ -219,7 +219,7 @@
|
||||
flex-shrink: 1;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
|
||||
.chat-textarea {
|
||||
color: @term-bright-white;
|
||||
background-color: @textarea-background;
|
||||
@@ -242,29 +242,27 @@
|
||||
}
|
||||
|
||||
.chat-msg {
|
||||
margin-top:5px;
|
||||
margin-bottom:5px;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.chat-msg-assistant {
|
||||
color: @term-white;
|
||||
}
|
||||
|
||||
.chat-msg-user {
|
||||
|
||||
.chat-msg-user {
|
||||
.msg-text {
|
||||
font-family: @markdown-font;
|
||||
font-size: 14px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.chat-msg-error {
|
||||
color: @term-bright-red;
|
||||
font-family: @markdown-font;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
||||
.grow-spacer {
|
||||
flex: 1 0 10px;
|
||||
|
||||
@@ -95,6 +95,7 @@ class ScreenTab extends React.Component<
|
||||
) : null;
|
||||
|
||||
const statusIndicatorLevel = screen.statusIndicator.get();
|
||||
const runningCommands = screen.numRunningCmds.get() > 0;
|
||||
|
||||
return (
|
||||
<Reorder.Item
|
||||
@@ -121,7 +122,7 @@ class ScreenTab extends React.Component<
|
||||
{screen.name.get()}
|
||||
</div>
|
||||
<div className="end-icons">
|
||||
<StatusIndicator level={statusIndicatorLevel} />
|
||||
<StatusIndicator level={statusIndicatorLevel} runningCommands={runningCommands} />
|
||||
{tabIndex}
|
||||
<ActionsIcon onClick={(e) => this.openScreenSettings(e, screen)} />
|
||||
</div>
|
||||
|
||||
@@ -279,14 +279,14 @@
|
||||
.end-icons {
|
||||
// This adjusts the position of the icon to account for the default 8px margin on the parent. We want the positional calculations for this icon to assume it is flush with the edge of the screen tab.
|
||||
margin: 0 -8px 0 0;
|
||||
|
||||
line-height: normal;
|
||||
.tab-index {
|
||||
font-size: 12.5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:hover) .status-indicator{
|
||||
&:not(:hover) .status-indicator {
|
||||
.positional-icon-visible;
|
||||
}
|
||||
|
||||
|
||||
+38
-3
@@ -373,6 +373,7 @@ class Screen {
|
||||
webShareOpts: OV<WebShareOpts>;
|
||||
filterRunning: OV<boolean>;
|
||||
statusIndicator: OV<StatusIndicatorLevel>;
|
||||
numRunningCmds: OV<number>;
|
||||
|
||||
constructor(sdata: ScreenDataType) {
|
||||
this.sessionId = sdata.sessionid;
|
||||
@@ -416,6 +417,9 @@ class Screen {
|
||||
this.statusIndicator = mobx.observable.box(StatusIndicatorLevel.None, {
|
||||
name: "screen-status-indicator",
|
||||
});
|
||||
this.numRunningCmds = mobx.observable.box(0, {
|
||||
name: "screen-num-running-cmds",
|
||||
});
|
||||
}
|
||||
|
||||
dispose() {}
|
||||
@@ -811,6 +815,16 @@ class Screen {
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of running commands for the screen.
|
||||
* @param numRunning The number of running commands.
|
||||
*/
|
||||
setNumRunningCmds(numRunning: number): void {
|
||||
mobx.action(() => {
|
||||
this.numRunningCmds.set(numRunning);
|
||||
})();
|
||||
}
|
||||
|
||||
termCustomKeyHandlerInternal(e: any, termWrap: TermWrap): void {
|
||||
let waveEvent = adaptFromReactOrNativeKeyEvent(e);
|
||||
if (checkKeyPressed(waveEvent, "ArrowUp")) {
|
||||
@@ -1049,21 +1063,37 @@ class ScreenLines {
|
||||
return this.cmds[lineId];
|
||||
}
|
||||
|
||||
getRunningCmdLines(): LineType[] {
|
||||
/**
|
||||
* Get all running cmds in the screen.
|
||||
* @param returnFirst If true, return the first running cmd found.
|
||||
* @returns An array of running cmds, or the first running cmd if returnFirst is true.
|
||||
*/
|
||||
getRunningCmdLines(returnFirst?: boolean): LineType[] {
|
||||
let rtn: LineType[] = [];
|
||||
for (const line of this.lines) {
|
||||
let cmd = this.getCmd(line.lineid);
|
||||
const cmd = this.getCmd(line.lineid);
|
||||
if (cmd == null) {
|
||||
continue;
|
||||
}
|
||||
let status = cmd.getStatus();
|
||||
const status = cmd.getStatus();
|
||||
if (cmdStatusIsRunning(status)) {
|
||||
if (returnFirst) {
|
||||
return [line];
|
||||
}
|
||||
rtn.push(line);
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are any running cmds in the screen.
|
||||
* @returns True if there are any running cmds.
|
||||
*/
|
||||
hasRunningCmdLines(): boolean {
|
||||
return this.getRunningCmdLines(true).length > 0;
|
||||
}
|
||||
|
||||
updateCmd(cmd: CmdDataType): void {
|
||||
if (cmd.remove) {
|
||||
throw new Error("cannot remove cmd with updateCmd call [" + cmd.lineid + "]");
|
||||
@@ -4075,6 +4105,11 @@ class Model {
|
||||
update.screenstatusindicator.status
|
||||
);
|
||||
}
|
||||
if ("screennumrunningcommands" in update) {
|
||||
this.getScreenById_single(update.screennumrunningcommands.screenid)?.setNumRunningCmds(
|
||||
update.screennumrunningcommands.num
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
updateRemotes(remotes: RemoteType[]): void {
|
||||
|
||||
+8
-4
@@ -297,7 +297,12 @@ enum StatusIndicatorLevel {
|
||||
type ScreenStatusIndicatorUpdateType = {
|
||||
screenid: string;
|
||||
status: StatusIndicatorLevel;
|
||||
}
|
||||
};
|
||||
|
||||
type ScreenNumRunningCommandsUpdateType = {
|
||||
screenid: string;
|
||||
num: number;
|
||||
};
|
||||
|
||||
type ModelUpdateType = {
|
||||
interactive: boolean;
|
||||
@@ -322,6 +327,7 @@ type ModelUpdateType = {
|
||||
openaicmdinfochat?: OpenAICmdInfoChatMessageType[];
|
||||
alertmessage?: AlertMessageType;
|
||||
screenstatusindicator?: ScreenStatusIndicatorUpdateType;
|
||||
screennumrunningcommands?: ScreenNumRunningCommandsUpdateType;
|
||||
};
|
||||
|
||||
type HistoryViewDataType = {
|
||||
@@ -803,6 +809,4 @@ export type {
|
||||
ScreenStatusIndicatorUpdateType,
|
||||
};
|
||||
|
||||
export {
|
||||
StatusIndicatorLevel,
|
||||
};
|
||||
export { StatusIndicatorLevel };
|
||||
|
||||
@@ -3004,11 +3004,10 @@ func SessionCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (ssto
|
||||
}
|
||||
err = sstore.ResetStatusIndicator_Update(update, session.ActiveScreenId)
|
||||
if err != nil {
|
||||
log.Printf("error resetting status indicator: %v\n", err)
|
||||
// this is not a fatal error, just log it
|
||||
log.Printf("error resetting status indicator after session command: %v\n", err)
|
||||
}
|
||||
|
||||
log.Printf("session command update: %v\n", update)
|
||||
|
||||
return update, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1885,6 +1885,8 @@ func RunCommand(ctx context.Context, rcOpts RunCommandOpts, runPacket *packet.Ru
|
||||
RemotePtr: remotePtr,
|
||||
RunPacket: runPacket,
|
||||
})
|
||||
|
||||
go pushNumRunningCmdsUpdate(&runPacket.CK, 1)
|
||||
return cmd, func() { removeCmdWait(runPacket.CK) }, nil
|
||||
}
|
||||
|
||||
@@ -1988,6 +1990,7 @@ func (msh *MShellProc) notifyHangups_nolock() {
|
||||
}
|
||||
update := &sstore.ModelUpdate{Cmd: cmd}
|
||||
sstore.MainBus.SendScreenUpdate(ck.GetGroupId(), update)
|
||||
go pushNumRunningCmdsUpdate(&ck, -1)
|
||||
}
|
||||
msh.RunningCmds = make(map[base.CommandKey]RunCmdType)
|
||||
msh.PendingStateCmds = make(map[pendingStateKey]base.CommandKey)
|
||||
@@ -2061,6 +2064,8 @@ func (msh *MShellProc) handleCmdDonePacket(donePk *packet.CmdDonePacketType) {
|
||||
// fall-through (nothing to do)
|
||||
}
|
||||
}
|
||||
|
||||
go pushNumRunningCmdsUpdate(&donePk.CK, -1)
|
||||
sstore.MainBus.SendUpdate(update)
|
||||
return
|
||||
}
|
||||
@@ -2094,6 +2099,7 @@ func (msh *MShellProc) handleCmdFinalPacket(finalPk *packet.CmdFinalPacketType)
|
||||
if screen != nil {
|
||||
update.Screens = []*sstore.ScreenType{screen}
|
||||
}
|
||||
go pushNumRunningCmdsUpdate(&finalPk.CK, -1)
|
||||
sstore.MainBus.SendUpdate(update)
|
||||
}
|
||||
|
||||
@@ -2463,5 +2469,13 @@ func (msh *MShellProc) GetDisplayName() string {
|
||||
// Identify the screen for a given CommandKey and push the given status indicator update for that screen
|
||||
func pushStatusIndicatorUpdate(ck *base.CommandKey, level sstore.StatusIndicatorLevel) {
|
||||
screenId := ck.GetGroupId()
|
||||
sstore.SetStatusIndicatorLevel(context.Background(), screenId, level, false)
|
||||
err := sstore.SetStatusIndicatorLevel(context.Background(), screenId, level, false)
|
||||
if err != nil {
|
||||
log.Printf("error setting status indicator level: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func pushNumRunningCmdsUpdate(ck *base.CommandKey, delta int) {
|
||||
screenId := ck.GetGroupId()
|
||||
sstore.IncrementNumRunningCmds(screenId, delta)
|
||||
}
|
||||
|
||||
@@ -944,7 +944,12 @@ func UpdateCmdDoneInfo(ctx context.Context, ck base.CommandKey, donePk *packet.C
|
||||
} else {
|
||||
indicator = StatusIndicatorLevel_Error
|
||||
}
|
||||
SetStatusIndicatorLevel_Update(ctx, update, screenId, indicator, false)
|
||||
|
||||
err := SetStatusIndicatorLevel_Update(ctx, update, screenId, indicator, false)
|
||||
if err != nil {
|
||||
// This is not a fatal error, so just log it
|
||||
log.Printf("error setting status indicator level after done packet: %v\n", err)
|
||||
}
|
||||
|
||||
return update, nil
|
||||
}
|
||||
@@ -1102,7 +1107,11 @@ func SwitchScreenById(ctx context.Context, sessionId string, screenId string) (*
|
||||
update.OpenAICmdInfoChat = ScreenMemGetCmdInfoChat(screenId).Messages
|
||||
|
||||
// Clear any previous status indicator for this screen
|
||||
ResetStatusIndicator_Update(update, screenId)
|
||||
err := ResetStatusIndicator_Update(update, screenId)
|
||||
if err != nil {
|
||||
// This is not a fatal error, so just log it
|
||||
log.Printf("error resetting status indicator when switching screens: %v\n", err)
|
||||
}
|
||||
}
|
||||
return update, nil
|
||||
}
|
||||
|
||||
@@ -153,13 +153,15 @@ func ScreenMemSetCmdInputText(screenId string, sp utilfn.StrWithPos, seqNum int)
|
||||
ScreenMemStore[screenId].CmdInputSeqNum = seqNum
|
||||
}
|
||||
|
||||
func ScreenMemSetNumRunningCommands(screenId string, num int) {
|
||||
func ScreenMemIncrementNumRunningCommands(screenId string, delta int) int {
|
||||
MemLock.Lock()
|
||||
defer MemLock.Unlock()
|
||||
if ScreenMemStore[screenId] == nil {
|
||||
ScreenMemStore[screenId] = &ScreenMemState{}
|
||||
}
|
||||
ScreenMemStore[screenId].NumRunningCommands = num
|
||||
newNum := ScreenMemStore[screenId].NumRunningCommands + delta
|
||||
ScreenMemStore[screenId].NumRunningCommands = newNum
|
||||
return newNum
|
||||
}
|
||||
|
||||
// If the new indicator level is higher than the current indicator, update the current indicator. Returns the new indicator level.
|
||||
|
||||
@@ -1514,14 +1514,14 @@ func SetStatusIndicatorLevel_Update(ctx context.Context, update *ModelUpdate, sc
|
||||
}
|
||||
|
||||
// Sets the in-memory status indicator for the given screenId to the given value and pushes the new value to the FE
|
||||
func SetStatusIndicatorLevel(ctx context.Context, screenId string, level StatusIndicatorLevel, force bool) {
|
||||
func SetStatusIndicatorLevel(ctx context.Context, screenId string, level StatusIndicatorLevel, force bool) error {
|
||||
update := &ModelUpdate{}
|
||||
err := SetStatusIndicatorLevel_Update(ctx, update, screenId, level, false)
|
||||
if err != nil {
|
||||
log.Printf("error setting status indicator level: %v\n", err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
MainBus.SendUpdate(update)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resets the in-memory status indicator for the given screenId to StatusIndicatorLevel_None and adds it to the ModelUpdate
|
||||
@@ -1531,7 +1531,23 @@ func ResetStatusIndicator_Update(update *ModelUpdate, screenId string) error {
|
||||
}
|
||||
|
||||
// Resets the in-memory status indicator for the given screenId to StatusIndicatorLevel_None and pushes the new value to the FE
|
||||
func ResetStatusIndicator(screenId string) {
|
||||
func ResetStatusIndicator(screenId string) error {
|
||||
// We do not need to set context when resetting the status indicator because we will not need to call the DB
|
||||
SetStatusIndicatorLevel(context.TODO(), screenId, StatusIndicatorLevel_None, true)
|
||||
return SetStatusIndicatorLevel(context.TODO(), screenId, StatusIndicatorLevel_None, true)
|
||||
}
|
||||
|
||||
func IncrementNumRunningCmds_Update(update *ModelUpdate, screenId string, delta int) {
|
||||
newNum := ScreenMemIncrementNumRunningCommands(screenId, delta)
|
||||
log.Printf("IncrementNumRunningCmds_Update: screenId=%s, newNum=%d\n", screenId, newNum)
|
||||
update.ScreenNumRunningCommands = &ScreenNumRunningCommandsType{
|
||||
ScreenId: screenId,
|
||||
Num: newNum,
|
||||
}
|
||||
}
|
||||
|
||||
func IncrementNumRunningCmds(screenId string, delta int) {
|
||||
log.Printf("IncrementNumRunningCmds: screenId=%s, delta=%d\n", screenId, delta)
|
||||
update := &ModelUpdate{}
|
||||
IncrementNumRunningCmds_Update(update, screenId, delta)
|
||||
MainBus.SendUpdate(update)
|
||||
}
|
||||
|
||||
@@ -39,31 +39,32 @@ func (*PtyDataUpdate) UpdateType() string {
|
||||
func (pdu *PtyDataUpdate) Clean() {}
|
||||
|
||||
type ModelUpdate struct {
|
||||
Sessions []*SessionType `json:"sessions,omitempty"`
|
||||
ActiveSessionId string `json:"activesessionid,omitempty"`
|
||||
Screens []*ScreenType `json:"screens,omitempty"`
|
||||
ScreenLines *ScreenLinesType `json:"screenlines,omitempty"`
|
||||
Line *LineType `json:"line,omitempty"`
|
||||
Lines []*LineType `json:"lines,omitempty"`
|
||||
Cmd *CmdType `json:"cmd,omitempty"`
|
||||
CmdLine *utilfn.StrWithPos `json:"cmdline,omitempty"`
|
||||
Info *InfoMsgType `json:"info,omitempty"`
|
||||
ClearInfo bool `json:"clearinfo,omitempty"`
|
||||
Remotes []RemoteRuntimeState `json:"remotes,omitempty"`
|
||||
History *HistoryInfoType `json:"history,omitempty"`
|
||||
Interactive bool `json:"interactive"`
|
||||
Connect bool `json:"connect,omitempty"`
|
||||
MainView string `json:"mainview,omitempty"`
|
||||
Bookmarks []*BookmarkType `json:"bookmarks,omitempty"`
|
||||
SelectedBookmark string `json:"selectedbookmark,omitempty"`
|
||||
HistoryViewData *HistoryViewData `json:"historyviewdata,omitempty"`
|
||||
ClientData *ClientData `json:"clientdata,omitempty"`
|
||||
RemoteView *RemoteViewType `json:"remoteview,omitempty"`
|
||||
ScreenTombstones []*ScreenTombstoneType `json:"screentombstones,omitempty"`
|
||||
SessionTombstones []*SessionTombstoneType `json:"sessiontombstones,omitempty"`
|
||||
OpenAICmdInfoChat []*packet.OpenAICmdInfoChatMessage `json:"openaicmdinfochat,omitempty"`
|
||||
AlertMessage *AlertMessageType `json:"alertmessage,omitempty"`
|
||||
ScreenStatusIndicator *ScreenStatusIndicatorType `json:"screenstatusindicator,omitempty"`
|
||||
Sessions []*SessionType `json:"sessions,omitempty"`
|
||||
ActiveSessionId string `json:"activesessionid,omitempty"`
|
||||
Screens []*ScreenType `json:"screens,omitempty"`
|
||||
ScreenLines *ScreenLinesType `json:"screenlines,omitempty"`
|
||||
Line *LineType `json:"line,omitempty"`
|
||||
Lines []*LineType `json:"lines,omitempty"`
|
||||
Cmd *CmdType `json:"cmd,omitempty"`
|
||||
CmdLine *utilfn.StrWithPos `json:"cmdline,omitempty"`
|
||||
Info *InfoMsgType `json:"info,omitempty"`
|
||||
ClearInfo bool `json:"clearinfo,omitempty"`
|
||||
Remotes []RemoteRuntimeState `json:"remotes,omitempty"`
|
||||
History *HistoryInfoType `json:"history,omitempty"`
|
||||
Interactive bool `json:"interactive"`
|
||||
Connect bool `json:"connect,omitempty"`
|
||||
MainView string `json:"mainview,omitempty"`
|
||||
Bookmarks []*BookmarkType `json:"bookmarks,omitempty"`
|
||||
SelectedBookmark string `json:"selectedbookmark,omitempty"`
|
||||
HistoryViewData *HistoryViewData `json:"historyviewdata,omitempty"`
|
||||
ClientData *ClientData `json:"clientdata,omitempty"`
|
||||
RemoteView *RemoteViewType `json:"remoteview,omitempty"`
|
||||
ScreenTombstones []*ScreenTombstoneType `json:"screentombstones,omitempty"`
|
||||
SessionTombstones []*SessionTombstoneType `json:"sessiontombstones,omitempty"`
|
||||
OpenAICmdInfoChat []*packet.OpenAICmdInfoChatMessage `json:"openaicmdinfochat,omitempty"`
|
||||
AlertMessage *AlertMessageType `json:"alertmessage,omitempty"`
|
||||
ScreenStatusIndicator *ScreenStatusIndicatorType `json:"screenstatusindicator,omitempty"`
|
||||
ScreenNumRunningCommands *ScreenNumRunningCommandsType `json:"screennumrunningcommands,omitempty"`
|
||||
}
|
||||
|
||||
func (*ModelUpdate) UpdateType() string {
|
||||
@@ -267,3 +268,8 @@ type ScreenStatusIndicatorType struct {
|
||||
ScreenId string `json:"screenid"`
|
||||
Status StatusIndicatorLevel `json:"status"`
|
||||
}
|
||||
|
||||
type ScreenNumRunningCommandsType struct {
|
||||
ScreenId string `json:"screenid"`
|
||||
Num int `json:"num"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user