diff --git a/go.work.sum b/go.work.sum index 132842daf..f41591a7f 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,3 +1,4 @@ +github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11 h1:3/gm/JTX9bX8CpzTgIlrtYpB3EVBDxyg/GY/QdcIEZw= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= diff --git a/src/app/app.less b/src/app/app.less index d7429b8dc..32e1d3359 100644 --- a/src/app/app.less +++ b/src/app/app.less @@ -8,6 +8,10 @@ } :root { + /* updated by GlobalModel to user's preferred fontsize */ + --termfontsize: 12px; + --termlineheight: 15px; + --fa-style-family: "Font Awesome 6 Sharp"; } diff --git a/src/app/line/linecomps.tsx b/src/app/line/linecomps.tsx index 306b03588..477d852d1 100644 --- a/src/app/line/linecomps.tsx +++ b/src/app/line/linecomps.tsx @@ -753,32 +753,6 @@ class LineCmd extends React.Component< /> - - - - state unchanged - - - - new state - - - {this.rtnStateDiff.get()} - - - - - - - focus line ({renderCmdText("L")}) - - ); diff --git a/src/app/line/lines.less b/src/app/line/lines.less index 520eee0aa..20d908dc7 100644 --- a/src/app/line/lines.less +++ b/src/app/line/lines.less @@ -23,18 +23,9 @@ .line.line-cmd { flex-direction: column; - scroll-margin-bottom: 20px; + scroll-margin-bottom: var(--termlineheight); position: relative; - .plus { - opacity: 0.5; - } - &:hover { - .plus { - opacity: 1; - } - } - .sidebar-message { color: @term-yellow; } @@ -45,13 +36,14 @@ padding-bottom: 0.7rem; width: 100%; line-height: 1.2; + height: calc(var(--termlineheight) * 2); &.is-expanded { height: auto; } &.hide-prompt { - height: 32px; + height: calc(var(--termlineheight) * 2); } .line-icon { @@ -81,16 +73,12 @@ display: block; opacity: 1; } - } - .meta.meta-line1 { - margin-left: 2px; - color: rgba(@base-color, 0.6) !important; - font-size: 11px; - } - - &.has-rtnstate .terminal-wrapper { - padding-bottom: 0; + .meta.meta-line1 { + margin-left: 2px; + color: rgba(@base-color, 0.6) !important; + font-size: var(--termfontsize); + } } .image-wrapper { @@ -113,11 +101,6 @@ overflow-x: hidden; } - .terminal { - margin-right: 8px; - padding: 0.25rem; - } - &.cmd-done .terminal .xterm-cursor { display: none; } @@ -208,7 +191,6 @@ .simple-line-header { display: flex; - margin-top: 5px; flex-direction: row; } @@ -350,14 +332,9 @@ display: flex; flex-direction: row; - .simple-line-status { - margin-top: 5px; - } - .user { color: lighten(@soft-blue, 10%); font-weight: bold; - margin-top: 1px; margin-right: 10px; } @@ -365,12 +342,10 @@ .termopts, .renderer { display: flex; - margin-top: 5px; } .renderer { margin-left: 3px; - margin-top: 5px; svg { width: 1em; margin-right: 0.5em; @@ -381,7 +356,6 @@ .settings { display: none; margin-left: 0.5em; - margin-top: 0.65em; cursor: pointer; width: 1em; height: 1em; @@ -396,7 +370,6 @@ } .termopts { - margin-top: 5px; display: none; .resize-button { cursor: pointer; @@ -407,7 +380,6 @@ .metapart-mono { margin-left: 8px; - margin-top: 4px; white-space: nowrap; } @@ -482,10 +454,6 @@ } } - .line:nth-child(2) { - padding-top: 1px; - } - .lines-spacer { flex-grow: 1; } @@ -493,7 +461,8 @@ .line-sep { display: flex; align-items: center; - margin-top: 1em; + height: var(--termlineheight); + font-size: var(--termfontsize); color: rgba(@base-color, 0.5); } diff --git a/src/index.ts b/src/index.ts index 7b415a4b0..ef9e638cb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,7 @@ import { sprintf } from "sprintf-js"; import { App } from "@/app/app"; import * as DOMPurify from "dompurify"; import { loadFonts } from "./util/util"; +import * as textmeasure from "./util/textmeasure"; // @ts-ignore let VERSION = __WAVETERM_VERSION__; @@ -33,5 +34,6 @@ document.addEventListener("DOMContentLoaded", () => { (window as any).mobx = mobx; (window as any).sprintf = sprintf; (window as any).DOMPurify = DOMPurify; +(window as any).textmeasure = textmeasure; console.log("WaveTerm", VERSION, BUILD); diff --git a/src/models/model.ts b/src/models/model.ts index d3f5841d9..f5cabc64c 100644 --- a/src/models/model.ts +++ b/src/models/model.ts @@ -189,6 +189,10 @@ class Model { } return fontSize; }); + mobx.autorun(() => { + const fontSize = this.termFontSize.get(); + this._setCssTermFontSize(fontSize); + }); getApi().onTCmd(this.onTCmd.bind(this)); getApi().onICmd(this.onICmd.bind(this)); getApi().onLCmd(this.onLCmd.bind(this)); @@ -345,16 +349,10 @@ class Model { return appconst.ProdServerEndpoint; } - setTermFontSize(fontSize: number) { - if (fontSize < appconst.MinFontSize) { - fontSize = appconst.MinFontSize; - } - if (fontSize > appconst.MaxFontSize) { - fontSize = appconst.MaxFontSize; - } - mobx.action(() => { - this.termFontSize.set(fontSize); - })(); + _setCssTermFontSize(fontSize: number) { + const root = document.documentElement; + root.style.setProperty("--termfontsize", fontSize + "px"); + root.style.setProperty("--termlinehight", Math.ceil(fontSize * 1.2) + "px"); } getBaseWsHostPort(): string { diff --git a/wavesrv/pkg/sstore/disp.go b/wavesrv/pkg/sstore/disp.go new file mode 100644 index 000000000..72d343c7a --- /dev/null +++ b/wavesrv/pkg/sstore/disp.go @@ -0,0 +1,76 @@ +// Copyright 2023, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +package sstore + +import "sync" + +// This file contains structures related to holding display state for screens / UI + +const ( + // ideal sizes for Sections/Zone + // we allow these to drift a bit to deal with adding/removing lines + DispZoneLines = 16 * 16 + DispSectionLines = 16 + DispMaxRatio = 1.6 +) + +// this will be a map at some point when we have multiple windows, singleton for now +var GlobalDisplayState *DispWindowInfo + +// (row, px) <- we use this format so JS is +type DispHeight [2]int +type DispLineRange [2]int // [start, end] (inclusive). set to [0,0] if no lines + +// this struct comes from the FE +type DispWindowInfo struct { + Lock *sync.Mutex `json:"-"` + ActiveSessionId string `json:"activesessionid"` + ActiveScreenId string `json:"activescreenid"` + Screens map[string]DispScreenInfo `json:"screens"` // key is "sessionid:screenid" (not a struct for JS integration) +} + +type DispScreenInfo struct { + SessionId string `json:"sessionid"` + ScreenId string `json:"screenid"` + SelectedLine int `json:"selectedline"` + AnchorLine int `json:"anchorline"` + AnchorOffset int `json:"anchoroffset"` +} + +type DispZoneInfo struct { + ScreenId string `json:"screenid"` + ZoneId int `json:"zoneid"` + Height DispHeight `json:"height"` + NumLines int `json:"numlines"` + LineRange DispLineRange `json:"linerange"` +} + +type DispSectionInfo struct { + ScreenId string `json:"screenid"` + ZoneId int `json:"zoneid"` + SectionId int `json:"sectionid"` + Height DispHeight `json:"height"` + LineRange DispLineRange `json:"linerange"` + Parts []DispLineInfo `json:"parts"` +} + +// includes separators. combined into one struct for efficiency / JS transport +type DispLineInfo struct { + // for separators + IsSep bool `json:"issep,omitempty"` + SepString string `json:"sepstring,omitempty"` + + // for lines + LineId string `json:"lineid,omitempty"` + LineNum int `json:"linenum,omitempty"` + LineType string `json:"linetype,omitempty"` + Ts int64 `json:"ts,omitempty"` + Status string `json:"status,omitempty"` + Renderer string `json:"renderer,omitempty"` + Prompt string `json:"prompt,omitempty"` + CmdStr string `json:"cmdstr,omitempty"` + Min bool `json:"min,omitempty"` + TermOpts string `json:"termopts,omitempty"` + Height DispHeight `json:"height,omitempty"` +}