checkpoint

This commit is contained in:
sawka 2024-12-03 15:30:39 -08:00
parent 90354cc3db
commit 1a57fee852
5 changed files with 84 additions and 10 deletions

View File

@ -6,11 +6,11 @@ import { ContextMenuModel } from "@/store/contextmenu";
import {
atoms,
createBlock,
getSettingsPrefixAtom,
globalStore,
isDev,
PLATFORM,
removeFlashError,
useSettingsPrefixAtom,
} from "@/store/global";
import { appHandleKeyDown } from "@/store/keymodel";
import { getElemAsStr } from "@/util/focusutil";
@ -123,7 +123,7 @@ async function handleContextMenu(e: React.MouseEvent<HTMLDivElement>) {
}
function AppSettingsUpdater() {
const windowSettingsAtom = useSettingsPrefixAtom("window");
const windowSettingsAtom = getSettingsPrefixAtom("window");
const windowSettings = useAtomValue(windowSettingsAtom);
useEffect(() => {
const isTransparentOrBlur =

View File

@ -35,7 +35,10 @@ export type TermWrapOptions = {
useWebGl?: boolean;
useWebLinksAddon?: boolean;
useSerializeAddon?: boolean;
termTheme: Atom<TermTypes.ITheme>;
termThemeAtom: Atom<TermTypes.ITheme>;
termFontSize: Atom<number>;
termFontFamily: Atom<string>;
termScrollback: Atom<number>;
onOpenLink?: (uri: string) => void;
onCwdChange?: (newCwd: string) => void;
handleInputData?: (data: string) => void;
@ -212,18 +215,27 @@ export class TermWrap {
export const TermElem = (props: { termOpts: TermWrapOptions }) => {
const connectElemRef = useRef<HTMLDivElement>(null);
const termWrapRef = useRef<TermWrap>(null);
const termTheme = useAtomValueSafe(props.termOpts.termTheme);
const termTheme = useAtomValueSafe(props.termOpts.termThemeAtom);
const termFontSize = useAtomValueSafe(props.termOpts.termFontSize) ?? 12;
const termFontFamily = useAtomValueSafe(props.termOpts.termFontFamily) ?? "Hack";
const termScrollback = useAtomValueSafe(props.termOpts.termScrollback) ?? 1000;
useEffect(() => {
if (termWrapRef.current == null || termTheme == null) {
return;
}
termWrapRef.current.terminal.options.theme = termTheme;
}, [termTheme]);
termWrapRef.current.terminal.options.fontSize = termFontSize;
termWrapRef.current.terminal.options.fontFamily = termFontFamily;
termWrapRef.current.terminal.options.scrollback = termScrollback;
}, [termTheme, termFontSize, termFontFamily, termScrollback]);
useEffect(() => {
termWrapRef.current = new TermWrap(props.termOpts);
if (termTheme != null) {
termWrapRef.current.terminal.options.theme = termTheme;
}
termWrapRef.current.terminal.options.fontSize = termFontSize;
termWrapRef.current.terminal.options.fontFamily = termFontFamily;
termWrapRef.current.terminal.options.scrollback = termScrollback;
termWrapRef.current.initTerminal(connectElemRef.current);
return () => {
termWrapRef.current.dispose();

View File

@ -293,7 +293,7 @@ function useSettingsKeyAtom<T extends keyof SettingsType>(key: T): SettingsType[
return useAtomValue(getSettingsKeyAtom(key));
}
function useSettingsPrefixAtom(prefix: string): Atom<SettingsType> {
function getSettingsPrefixAtom(prefix: string): Atom<SettingsType> {
// TODO: use a shallow equal here to make this more efficient
let settingsPrefixAtom = settingsAtomCache.get(prefix + ":") as Atom<SettingsType>;
if (settingsPrefixAtom == null) {
@ -638,6 +638,7 @@ export {
getObjectId,
getOverrideConfigAtom,
getSettingsKeyAtom,
getSettingsPrefixAtom,
getUserName,
globalStore,
initGlobal,
@ -663,6 +664,5 @@ export {
useBlockMetaKeyAtom,
useOverrideConfigAtom,
useSettingsKeyAtom,
useSettingsPrefixAtom,
WOS,
};

View File

@ -3,6 +3,7 @@
import { Block, SubBlock } from "@/app/block/block";
import { BlockNodeModel } from "@/app/block/blocktypes";
import { TermWrapOptions } from "@/app/element/termelem/termelem";
import { getAllGlobalKeyBindings } from "@/app/store/keymodel";
import { waveEventSubscribe } from "@/app/store/wps";
import { RpcApi } from "@/app/store/wshclientapi";
@ -17,13 +18,14 @@ import {
getConnStatusAtom,
getOverrideConfigAtom,
getSettingsKeyAtom,
getSettingsPrefixAtom,
globalStore,
useBlockAtom,
useSettingsPrefixAtom,
WOS,
} from "@/store/global";
import * as services from "@/store/services";
import * as keyutil from "@/util/keyutil";
import * as TermTypes from "@xterm/xterm";
import clsx from "clsx";
import debug from "debug";
import * as jotai from "jotai";
@ -64,6 +66,7 @@ class TermViewModel {
termThemeNameAtom: jotai.Atom<string>;
noPadding: jotai.PrimitiveAtom<boolean>;
endIconButtons: jotai.Atom<IconButtonDecl[]>;
termThemeAtom: jotai.Atom<TermTypes.ITheme>;
constructor(blockId: string, nodeModel: BlockNodeModel) {
this.viewType = "term";
@ -187,6 +190,32 @@ class TermViewModel {
},
];
});
this.termThemeAtom = jotai.atom((get) => {
const fullConfig = get(atoms.fullConfigAtom);
const termThemeName = get(this.termThemeNameAtom);
const [theme, _] = computeTheme(fullConfig, termThemeName);
return theme;
});
}
getTermScrollback(): number {
const settingsPrefixAtom = getSettingsPrefixAtom("term");
const termSettings = globalStore.get(settingsPrefixAtom);
const blockData = globalStore.get(this.blockAtom);
let termScrollback = 1000;
if (termSettings?.["term:scrollback"]) {
termScrollback = Math.floor(termSettings["term:scrollback"]);
}
if (blockData?.meta?.["term:scrollback"]) {
termScrollback = Math.floor(blockData.meta["term:scrollback"]);
}
if (termScrollback < 0) {
termScrollback = 0;
}
if (termScrollback > 10000) {
termScrollback = 10000;
}
return termScrollback;
}
setTermMode(mode: "term" | "vdom") {
@ -541,7 +570,7 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
const spstatusRef = React.useRef<string>(null);
model.shellProcStatusRef = spstatusRef;
const [blockData] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", blockId));
const termSettingsAtom = useSettingsPrefixAtom("term");
const termSettingsAtom = getSettingsPrefixAtom("term");
const termSettings = jotai.useAtomValue(termSettingsAtom);
let termMode = blockData?.meta?.["term:mode"] ?? "term";
if (termMode != "term" && termMode != "vdom") {
@ -549,7 +578,6 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
}
const termModeRef = React.useRef(termMode);
const termFontSize = jotai.useAtomValue(model.fontSizeAtom);
React.useEffect(() => {
const fullConfig = globalStore.get(atoms.fullConfigAtom);
@ -648,6 +676,7 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
cols: termRef.current?.terminal.cols ?? 80,
blockId: blockId,
};
return (
<div className={clsx("view-term", "term-mode-" + termMode)} ref={viewRef}>
<TermResyncHandler blockId={blockId} model={model} />

View File

@ -0,0 +1,33 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { getOverrideConfigAtom, getSettingsPrefixAtom, openLink } from "@/app/store/global";
import { TermViewModel } from "@/app/view/term/term";
import { TermElem, TermWrapOptions } from "@/element/termelem/termelem";
import { useAtomValue } from "jotai";
export function TermWrapElem({ blockId, model }: { blockId: string; model: TermViewModel }) {
const termFontSize = useAtomValue(model.fontSizeAtom);
const termSettingsAtom = getSettingsPrefixAtom("term");
const termSettings = useAtomValue(termSettingsAtom);
const termFontSizeAtom = getOverrideConfigAtom(blockId, "term:fontsize");
const termFontFamilyAtom = getOverrideConfigAtom(blockId, "term:fontfamily");
let termOpts: TermWrapOptions = {
xtermOpts: {
drawBoldTextInBrightColors: false,
fontWeight: "normal",
fontWeightBold: "bold",
allowTransparency: true,
},
useWebGl: !termSettings?.["term:disablewebgl"],
useWebLinksAddon: true,
useSerializeAddon: true,
onOpenLink: openLink,
keydownHandler: model.handleTerminalKeydown.bind(model),
termThemeAtom: model.termThemeAtom,
termFontFamily: termFontFamilyAtom,
termFontSize: termFontSizeAtom,
};
return <TermElem termOpts={termOpts} />;
}