termfontsize override (#1118)

This commit is contained in:
Mike Sawka 2024-10-24 11:01:39 -07:00 committed by GitHub
parent bf5bf6f00c
commit d65eabe494
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 83 additions and 7 deletions

View File

@ -36,7 +36,7 @@ type FullBlockProps = {
function makeViewModel(blockId: string, blockView: string, nodeModel: NodeModel): ViewModel {
if (blockView === "term") {
return makeTerminalModel(blockId);
return makeTerminalModel(blockId, nodeModel);
}
if (blockView === "preview") {
return makePreviewModel(blockId, nodeModel);

View File

@ -6,7 +6,16 @@ import { waveEventSubscribe } from "@/app/store/wps";
import { RpcApi } from "@/app/store/wshclientapi";
import { WindowRpcClient } from "@/app/store/wshrpcutil";
import { VDomView } from "@/app/view/term/vdom";
import { WOS, atoms, getConnStatusAtom, getSettingsKeyAtom, globalStore, useSettingsPrefixAtom } from "@/store/global";
import { NodeModel } from "@/layout/index";
import {
WOS,
atoms,
getConnStatusAtom,
getSettingsKeyAtom,
globalStore,
useBlockAtom,
useSettingsPrefixAtom,
} from "@/store/global";
import * as services from "@/store/services";
import * as keyutil from "@/util/keyutil";
import * as util from "@/util/util";
@ -106,15 +115,19 @@ class TermViewModel {
termMode: jotai.Atom<string>;
htmlElemFocusRef: React.RefObject<HTMLInputElement>;
blockId: string;
nodeModel: NodeModel;
viewIcon: jotai.Atom<string>;
viewName: jotai.Atom<string>;
blockBg: jotai.Atom<MetaType>;
manageConnection: jotai.Atom<boolean>;
connStatus: jotai.Atom<ConnStatus>;
fontSizeAtom: jotai.Atom<number>;
termThemeNameAtom: jotai.Atom<string>;
constructor(blockId: string) {
constructor(blockId: string, nodeModel: NodeModel) {
this.viewType = "term";
this.blockId = blockId;
this.nodeModel = nodeModel;
this.blockAtom = WOS.getWaveObjectAtom<Block>(`block:${blockId}`);
this.termMode = jotai.atom((get) => {
const blockData = get(this.blockAtom);
@ -150,6 +163,25 @@ class TermViewModel {
const connAtom = getConnStatusAtom(connName);
return get(connAtom);
});
this.fontSizeAtom = useBlockAtom(blockId, "fontsizeatom", () => {
return jotai.atom<number>((get) => {
const blockData = get(this.blockAtom);
const fsSettingsAtom = getSettingsKeyAtom("term:fontsize");
const settingsFontSize = get(fsSettingsAtom);
const rtnFontSize = blockData?.meta?.["term:fontsize"] ?? settingsFontSize ?? 12;
if (typeof rtnFontSize != "number" || isNaN(rtnFontSize) || rtnFontSize < 4 || rtnFontSize > 64) {
return 12;
}
return rtnFontSize;
});
});
this.termThemeNameAtom = useBlockAtom(blockId, "termthemeatom", () => {
return jotai.atom<string>((get) => {
const blockData = get(this.blockAtom);
const settingsKeyAtom = getSettingsKeyAtom("term:theme");
return blockData?.meta?.["term:theme"] ?? get(settingsKeyAtom) ?? "default-dark";
});
});
}
giveFocus(): boolean {
@ -179,6 +211,10 @@ class TermViewModel {
const fullConfig = globalStore.get(atoms.fullConfigAtom);
const termThemes = fullConfig?.termthemes ?? {};
const termThemeKeys = Object.keys(termThemes);
const curThemeName = globalStore.get(this.termThemeNameAtom);
const defaultFontSize = globalStore.get(getSettingsKeyAtom("term:fontsize")) ?? 12;
const blockData = globalStore.get(this.blockAtom);
const overrideFontSize = blockData?.meta?.["term:fontsize"];
termThemeKeys.sort((a, b) => {
return termThemes[a]["display:order"] - termThemes[b]["display:order"];
@ -187,13 +223,45 @@ class TermViewModel {
const submenu: ContextMenuItem[] = termThemeKeys.map((themeName) => {
return {
label: termThemes[themeName]["display:name"] ?? themeName,
type: "checkbox",
checked: curThemeName == themeName,
click: () => this.setTerminalTheme(themeName),
};
});
const fontSizeSubMenu: ContextMenuItem[] = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18].map(
(fontSize: number) => {
return {
label: fontSize.toString() + "px",
type: "checkbox",
checked: overrideFontSize == fontSize,
click: () => {
RpcApi.SetMetaCommand(WindowRpcClient, {
oref: WOS.makeORef("block", this.blockId),
meta: { "term:fontsize": fontSize },
});
},
};
}
);
fontSizeSubMenu.unshift({
label: "Default (" + defaultFontSize + "px)",
type: "checkbox",
checked: overrideFontSize == null,
click: () => {
RpcApi.SetMetaCommand(WindowRpcClient, {
oref: WOS.makeORef("block", this.blockId),
meta: { "term:fontsize": null },
});
},
});
fullMenu.push({
label: "Themes",
submenu: submenu,
});
fullMenu.push({
label: "Font Size",
submenu: fontSizeSubMenu,
});
fullMenu.push({ type: "separator" });
fullMenu.push({
label: "Force Restart Controller",
@ -215,8 +283,8 @@ class TermViewModel {
}
}
function makeTerminalModel(blockId: string): TermViewModel {
return new TermViewModel(blockId);
function makeTerminalModel(blockId: string, nodeModel: NodeModel): TermViewModel {
return new TermViewModel(blockId, nodeModel);
}
interface TerminalViewProps {
@ -258,6 +326,8 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
const termSettingsAtom = useSettingsPrefixAtom("term");
const termSettings = jotai.useAtomValue(termSettingsAtom);
const termFontSize = jotai.useAtomValue(model.fontSizeAtom);
React.useEffect(() => {
function handleTerminalKeydown(event: KeyboardEvent): boolean {
const waveEvent = keyutil.adaptFromReactOrNativeKeyEvent(event);
@ -321,12 +391,13 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
if (termScrollback > 10000) {
termScrollback = 10000;
}
const wasFocused = termRef.current != null && globalStore.get(model.nodeModel.isFocused);
const termWrap = new TermWrap(
blockId,
connectElemRef.current,
{
theme: themeCopy,
fontSize: termSettings?.["term:fontsize"] ?? 12,
fontSize: termFontSize,
fontFamily: termSettings?.["term:fontfamily"] ?? "Hack",
drawBoldTextInBrightColors: false,
fontWeight: "normal",
@ -346,11 +417,16 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
});
rszObs.observe(connectElemRef.current);
termWrap.initTerminal();
if (wasFocused) {
setTimeout(() => {
model.giveFocus();
}, 10);
}
return () => {
termWrap.dispose();
rszObs.disconnect();
};
}, [blockId, termSettings]);
}, [blockId, termSettings, termFontSize]);
const handleHtmlKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
const waveEvent = keyutil.adaptFromReactOrNativeKeyEvent(event);