mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-03-12 13:29:15 +01:00
working
This commit is contained in:
parent
e4d353b5c1
commit
97595a7718
@ -125,6 +125,7 @@ class App extends React.Component<{}, {}> {
|
|||||||
const activeMainView = GlobalModel.activeMainView.get();
|
const activeMainView = GlobalModel.activeMainView.get();
|
||||||
const lightDarkClass = GlobalModel.isDarkTheme.get() ? "is-dark" : "is-light";
|
const lightDarkClass = GlobalModel.isDarkTheme.get() ? "is-dark" : "is-light";
|
||||||
const termTheme = GlobalModel.getTermTheme();
|
const termTheme = GlobalModel.getTermTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={`version- + ${renderVersion}`}
|
key={`version- + ${renderVersion}`}
|
||||||
@ -152,7 +153,12 @@ class App extends React.Component<{}, {}> {
|
|||||||
</div>
|
</div>
|
||||||
</If>
|
</If>
|
||||||
<div ref={this.mainContentRef} className="main-content">
|
<div ref={this.mainContentRef} className="main-content">
|
||||||
<StyleBlock termTheme={termTheme} themeSrcEl={this.mainContentRef.current} themeKey="global" />
|
<StyleBlock
|
||||||
|
scope="main"
|
||||||
|
termTheme={termTheme}
|
||||||
|
themeSrcEl={this.mainContentRef.current}
|
||||||
|
themeKey="main"
|
||||||
|
/>
|
||||||
<MainSideBar parentRef={this.mainContentRef} />
|
<MainSideBar parentRef={this.mainContentRef} />
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<PluginsView />
|
<PluginsView />
|
||||||
|
@ -76,14 +76,14 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
|||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
handleChangeTermTheme(theme: string): void {
|
handleChangeTermTheme(theme: string): void {
|
||||||
// For global terminal theme, the key is global, otherwise it's either
|
// For main terminal theme, the key is main, otherwise it's either
|
||||||
// sessionId or screenId.
|
// sessionId or screenId.
|
||||||
const currTheme = GlobalModel.getTermTheme()["global"];
|
const currTheme = GlobalModel.getTermTheme()["main"];
|
||||||
if (currTheme == theme) {
|
if (currTheme == theme) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prtn = GlobalCommandRunner.setGlobalTermTheme(theme, false);
|
const prtn = GlobalCommandRunner.setMainTermTheme(theme, false);
|
||||||
commandRtnHandler(prtn, this.errorMessage);
|
commandRtnHandler(prtn, this.errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
|||||||
const curFontFamily = GlobalModel.getTermFontFamily();
|
const curFontFamily = GlobalModel.getTermFontFamily();
|
||||||
const curTheme = GlobalModel.getThemeSource();
|
const curTheme = GlobalModel.getThemeSource();
|
||||||
const termThemes = getTermThemes(GlobalModel.termThemes, "Wave Default");
|
const termThemes = getTermThemes(GlobalModel.termThemes, "Wave Default");
|
||||||
const currTermTheme = GlobalModel.getTermTheme()["global"] ?? termThemes[0].label;
|
const currTermTheme = GlobalModel.getTermTheme()["main"] ?? termThemes[0].label;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MainView className="clientsettings-view" title="Client Settings" onClose={this.handleClose}>
|
<MainView className="clientsettings-view" title="Client Settings" onClose={this.handleClose}>
|
||||||
|
@ -9,14 +9,13 @@ import { isBlank } from "@/util/util";
|
|||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class StyleBlock extends React.Component<
|
class StyleBlock extends React.Component<
|
||||||
{ themeSrcEl: HTMLElement; themeKey: string; termTheme: TermThemeType },
|
{ scope: "main" | "session" | "screen"; themeSrcEl: HTMLElement; themeKey: string; termTheme: TermThemeType },
|
||||||
{ styleRules: string }
|
{ styleRules: string }
|
||||||
> {
|
> {
|
||||||
styleRules: OV<string> = mobx.observable.box("", { name: "StyleBlock-styleRules" });
|
styleRules: OV<string> = mobx.observable.box("", { name: "StyleBlock-styleRules" });
|
||||||
theme: string;
|
theme: string;
|
||||||
|
|
||||||
componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
GlobalModel.termThemeSrcEl.set(this.props.themeSrcEl);
|
|
||||||
this.loadThemeStyles();
|
this.loadThemeStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,13 +25,10 @@ class StyleBlock extends React.Component<
|
|||||||
if (themeKey !== prevProps.themeKey || currTheme !== this.theme) {
|
if (themeKey !== prevProps.themeKey || currTheme !== this.theme) {
|
||||||
this.loadThemeStyles();
|
this.loadThemeStyles();
|
||||||
}
|
}
|
||||||
if (this.props.themeSrcEl !== prevProps.themeSrcEl) {
|
|
||||||
GlobalModel.termThemeSrcEl.set(this.props.themeSrcEl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadThemeStyles() {
|
async loadThemeStyles() {
|
||||||
const { themeKey, termTheme } = this.props;
|
const { themeKey, termTheme, scope } = this.props;
|
||||||
const currTheme = termTheme[themeKey];
|
const currTheme = termTheme[themeKey];
|
||||||
|
|
||||||
if (currTheme && currTheme !== this.theme && currTheme) {
|
if (currTheme && currTheme !== this.theme && currTheme) {
|
||||||
@ -43,7 +39,10 @@ class StyleBlock extends React.Component<
|
|||||||
.map(([key, value]) => `--term-${key}: ${value};`)
|
.map(([key, value]) => `--term-${key}: ${value};`)
|
||||||
.join(" ");
|
.join(" ");
|
||||||
|
|
||||||
this.styleRules.set(`:root { ${styleProperties} }`);
|
mobx.action(() => {
|
||||||
|
this.styleRules.set(`:root { ${styleProperties} }`);
|
||||||
|
GlobalModel.termThemeSrcEls.set(scope, this.props.themeSrcEl);
|
||||||
|
})();
|
||||||
GlobalModel.bumpTermRenderVersion();
|
GlobalModel.bumpTermRenderVersion();
|
||||||
this.theme = currTheme;
|
this.theme = currTheme;
|
||||||
} else {
|
} else {
|
||||||
@ -53,7 +52,12 @@ class StyleBlock extends React.Component<
|
|||||||
console.error("error loading theme styles:", error);
|
console.error("error loading theme styles:", error);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.styleRules.set("");
|
mobx.action(() => {
|
||||||
|
this.styleRules.set("");
|
||||||
|
GlobalModel.termThemeSrcEls.set(scope, null);
|
||||||
|
})();
|
||||||
|
this.theme = currTheme;
|
||||||
|
GlobalModel.bumpTermRenderVersion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,11 +185,18 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
|
|||||||
sidebarWidth = realWidth - MagicLayout.ScreenSidebarWidthPadding + "px";
|
sidebarWidth = realWidth - MagicLayout.ScreenSidebarWidthPadding + "px";
|
||||||
}
|
}
|
||||||
const termTheme = GlobalModel.getTermTheme();
|
const termTheme = GlobalModel.getTermTheme();
|
||||||
|
const termRenderVersion = GlobalModel.termRenderVersion.get();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="screen-view" data-screenid={screen.screenId} ref={this.screenViewRef}>
|
<div className="screen-view" data-screenid={screen.screenId} ref={this.screenViewRef}>
|
||||||
{/* <StyleBlock termTheme={termTheme} themeSrcEl={} /> */}
|
<StyleBlock
|
||||||
|
scope="screen"
|
||||||
|
termTheme={termTheme}
|
||||||
|
themeSrcEl={this.screenViewRef.current}
|
||||||
|
themeKey={screen.screenId}
|
||||||
|
/>
|
||||||
<ScreenWindowView
|
<ScreenWindowView
|
||||||
key={screen.screenId + ":" + fontSize + ":" + dprStr}
|
key={screen.screenId + ":" + fontSize + ":" + dprStr + ":" + termRenderVersion}
|
||||||
session={session}
|
session={session}
|
||||||
screen={screen}
|
screen={screen}
|
||||||
width={winWidth}
|
width={winWidth}
|
||||||
|
45
src/app/workspace/screen/tabs2.less
Normal file
45
src/app/workspace/screen/tabs2.less
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
.screen-tabs-container {
|
||||||
|
position: relative;
|
||||||
|
height: var(--screentabs-height);
|
||||||
|
|
||||||
|
.screen-tabs-container-inner {
|
||||||
|
position: relative; // Needed for absolute positioning of child tabs
|
||||||
|
white-space: nowrap;
|
||||||
|
height: 100%;
|
||||||
|
margin-right: 42px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-screen {
|
||||||
|
width: 42px;
|
||||||
|
height: 40px;
|
||||||
|
background-color: var(--app-bg-color);
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 20px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 38px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This ensures the tab bar does not collide with the floating logo. The floating logo sits above the sidebar when it is not collapsed, so no additional margin is needed in that case.
|
||||||
|
// More margin is given on macOS to account for the traffic light buttons
|
||||||
|
#app.platform-darwin.mainsidebar-collapsed .screen-tabs-container {
|
||||||
|
margin-left: var(--floating-logo-width-darwin);
|
||||||
|
}
|
||||||
|
|
||||||
|
#app:not(.platform-darwin).mainsidebar-collapsed .screen-tabs-container {
|
||||||
|
margin-left: var(--floating-logo-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This ensures the tab bar does not collide with the right sidebar triggers.
|
||||||
|
#app.platform-darwin.rightsidebar-collapsed .screen-tabs-container {
|
||||||
|
margin-right: var(--floating-right-sidebar-triggers-width-darwin);
|
||||||
|
}
|
||||||
|
|
||||||
|
#app:not(.platform-darwin).rightsidebar-collapsed .screen-tabs-container {
|
||||||
|
margin-left: var(--floating-right-sidebar-triggers-width);
|
||||||
|
}
|
@ -287,7 +287,6 @@ class WorkspaceView extends React.Component<{}, {}> {
|
|||||||
const mainSidebarModel = GlobalModel.mainSidebarModel;
|
const mainSidebarModel = GlobalModel.mainSidebarModel;
|
||||||
const showTabSettings = GlobalModel.tabSettingsOpen.get();
|
const showTabSettings = GlobalModel.tabSettingsOpen.get();
|
||||||
const termTheme = GlobalModel.getTermTheme();
|
const termTheme = GlobalModel.getTermTheme();
|
||||||
const termRenderVersion = GlobalModel.termRenderVersion.get();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -300,6 +299,7 @@ class WorkspaceView extends React.Component<{}, {}> {
|
|||||||
>
|
>
|
||||||
<If condition={session != null}>
|
<If condition={session != null}>
|
||||||
<StyleBlock
|
<StyleBlock
|
||||||
|
scope="session"
|
||||||
themeSrcEl={this.sessionRef.current}
|
themeSrcEl={this.sessionRef.current}
|
||||||
themeKey={session.sessionId}
|
themeKey={session.sessionId}
|
||||||
termTheme={termTheme}
|
termTheme={termTheme}
|
||||||
@ -321,11 +321,7 @@ class WorkspaceView extends React.Component<{}, {}> {
|
|||||||
</div>
|
</div>
|
||||||
</If>
|
</If>
|
||||||
<ErrorBoundary key="eb">
|
<ErrorBoundary key="eb">
|
||||||
<ScreenView
|
<ScreenView key={`screenview-${sessionId}`} session={session} screen={activeScreen} />
|
||||||
key={`screenview-${sessionId}-${termRenderVersion}`}
|
|
||||||
session={session}
|
|
||||||
screen={activeScreen}
|
|
||||||
/>
|
|
||||||
<div className="cmdinput-height-placeholder" style={{ height: cmdInputHeight }}></div>
|
<div className="cmdinput-height-placeholder" style={{ height: cmdInputHeight }}></div>
|
||||||
<If condition={activeScreen != null}>
|
<If condition={activeScreen != null}>
|
||||||
<CmdInput key={"cmdinput-" + sessionId} />
|
<CmdInput key={"cmdinput-" + sessionId} />
|
||||||
|
@ -377,7 +377,7 @@ class CommandRunner {
|
|||||||
return GlobalModel.submitCommand("client", "set", null, kwargs, interactive);
|
return GlobalModel.submitCommand("client", "set", null, kwargs, interactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
setGlobalTermTheme(theme: string, interactive: boolean): Promise<CommandRtnType> {
|
setMainTermTheme(theme: string, interactive: boolean): Promise<CommandRtnType> {
|
||||||
let kwargs = {
|
let kwargs = {
|
||||||
nohist: "1",
|
nohist: "1",
|
||||||
termtheme: theme,
|
termtheme: theme,
|
||||||
@ -386,7 +386,6 @@ class CommandRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setSessionTermTheme(sessionId: string, name: string, interactive: boolean): Promise<CommandRtnType> {
|
setSessionTermTheme(sessionId: string, name: string, interactive: boolean): Promise<CommandRtnType> {
|
||||||
console.log("setSessionTermTheme-------");
|
|
||||||
let kwargs = {
|
let kwargs = {
|
||||||
nohist: "1",
|
nohist: "1",
|
||||||
id: sessionId,
|
id: sessionId,
|
||||||
|
@ -144,13 +144,15 @@ class Model {
|
|||||||
name: "terminalThemes",
|
name: "terminalThemes",
|
||||||
deep: false,
|
deep: false,
|
||||||
});
|
});
|
||||||
termThemeSrcEl: OV<HTMLElement> = mobx.observable.box(null, {
|
termThemeSrcEls: OMap<string, HTMLElement> = mobx.observable.map(
|
||||||
name: "termThemeSrcEl",
|
{},
|
||||||
});
|
{
|
||||||
|
name: "termThemeSrcEls",
|
||||||
|
}
|
||||||
|
);
|
||||||
termRenderVersion: OV<number> = mobx.observable.box(0, {
|
termRenderVersion: OV<number> = mobx.observable.box(0, {
|
||||||
name: "termRenderVersion",
|
name: "termRenderVersion",
|
||||||
});
|
});
|
||||||
currGlobalTermTheme: string;
|
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
this.clientId = getApi().getId();
|
this.clientId = getApi().getId();
|
||||||
@ -214,6 +216,16 @@ class Model {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getThemeSrcElForScope() {
|
||||||
|
const scopes = ["screen", "session", "main"];
|
||||||
|
for (let scope of scopes) {
|
||||||
|
if (this.termThemeSrcEls.get(scope)) {
|
||||||
|
return this.termThemeSrcEls.get(scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return document.documentElement;
|
||||||
|
}
|
||||||
|
|
||||||
readConfigKeybindings() {
|
readConfigKeybindings() {
|
||||||
const url = new URL(this.getBaseHostPort() + "/config/keybindings.json");
|
const url = new URL(this.getBaseHostPort() + "/config/keybindings.json");
|
||||||
let prtn = fetch(url, { method: "get", body: null, headers: this.getFetchHeaders() });
|
let prtn = fetch(url, { method: "get", body: null, headers: this.getFetchHeaders() });
|
||||||
@ -1331,7 +1343,7 @@ class Model {
|
|||||||
// Only for global terminal theme. For session and screen terminal theme,
|
// Only for global terminal theme. For session and screen terminal theme,
|
||||||
// they are handled in workspace view.
|
// they are handled in workspace view.
|
||||||
if (ttUpdated) {
|
if (ttUpdated) {
|
||||||
this.bumpTermRenderVersion();
|
// this.bumpTermRenderVersion();
|
||||||
// const el = document.documentElement;
|
// const el = document.documentElement;
|
||||||
// const globaltt = newTermTheme["global"] ?? this.currGlobalTermTheme;
|
// const globaltt = newTermTheme["global"] ?? this.currGlobalTermTheme;
|
||||||
// const reset = newTermTheme["global"] == null;
|
// const reset = newTermTheme["global"] == null;
|
||||||
|
@ -169,6 +169,7 @@ class RemotesModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createTermWrap(elem: HTMLElement): void {
|
createTermWrap(elem: HTMLElement): void {
|
||||||
|
console.log("createTermWrap", elem);
|
||||||
this.disposeTerm();
|
this.disposeTerm();
|
||||||
let remoteId = this.selectedRemoteId.get();
|
let remoteId = this.selectedRemoteId.get();
|
||||||
if (remoteId == null) {
|
if (remoteId == null) {
|
||||||
|
@ -53,6 +53,7 @@ type TermWrapOpts = {
|
|||||||
|
|
||||||
function getThemeFromCSSVars(themeSrcEl: HTMLElement): ITheme {
|
function getThemeFromCSSVars(themeSrcEl: HTMLElement): ITheme {
|
||||||
const theme: ITheme = {};
|
const theme: ITheme = {};
|
||||||
|
console.log("themeSrcEl", themeSrcEl);
|
||||||
const tse = themeSrcEl ?? document.documentElement;
|
const tse = themeSrcEl ?? document.documentElement;
|
||||||
let rootStyle = getComputedStyle(tse);
|
let rootStyle = getComputedStyle(tse);
|
||||||
theme.foreground = rootStyle.getPropertyValue("--term-foreground");
|
theme.foreground = rootStyle.getPropertyValue("--term-foreground");
|
||||||
@ -131,7 +132,7 @@ class TermWrap {
|
|||||||
let cols = windowWidthToCols(opts.winSize.width, opts.fontSize);
|
let cols = windowWidthToCols(opts.winSize.width, opts.fontSize);
|
||||||
this.termSize = { rows: opts.termOpts.rows, cols: cols };
|
this.termSize = { rows: opts.termOpts.rows, cols: cols };
|
||||||
}
|
}
|
||||||
const themeSrcEl = GlobalModel.termThemeSrcEl.get();
|
const themeSrcEl = GlobalModel.getThemeSrcElForScope();
|
||||||
let theme = getThemeFromCSSVars(themeSrcEl);
|
let theme = getThemeFromCSSVars(themeSrcEl);
|
||||||
this.terminal = new Terminal({
|
this.terminal = new Terminal({
|
||||||
rows: this.termSize.rows,
|
rows: this.termSize.rows,
|
||||||
|
@ -5811,9 +5811,9 @@ func ClientSetCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sc
|
|||||||
feOpts.TermTheme = make(map[string]string)
|
feOpts.TermTheme = make(map[string]string)
|
||||||
}
|
}
|
||||||
if termthemeStr == "" {
|
if termthemeStr == "" {
|
||||||
delete(feOpts.TermTheme, "global")
|
delete(feOpts.TermTheme, "main")
|
||||||
} else {
|
} else {
|
||||||
feOpts.TermTheme["global"] = termthemeStr
|
feOpts.TermTheme["main"] = termthemeStr
|
||||||
}
|
}
|
||||||
err = sstore.UpdateClientFeOpts(ctx, feOpts)
|
err = sstore.UpdateClientFeOpts(ctx, feOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user