This commit is contained in:
Mike Sawka 2024-10-25 18:36:09 -07:00 committed by GitHub
parent da57427e8c
commit a782d83628
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 85 additions and 40 deletions

View File

@ -1,7 +1,14 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { BlockComponentModel2, BlockProps } from "@/app/block/blocktypes";
import {
BlockComponentModel2,
BlockNodeModel,
BlockProps,
FullBlockProps,
FullSubBlockProps,
SubBlockProps,
} from "@/app/block/blocktypes";
import { PlotView } from "@/app/view/plotview/plotview";
import { PreviewModel, PreviewView, makePreviewModel } from "@/app/view/preview/preview";
import { SysinfoView, SysinfoViewModel, makeSysinfoViewModel } from "@/app/view/sysinfo/sysinfo";
@ -9,7 +16,7 @@ import { VDomView, makeVDomModel } from "@/app/view/vdom/vdom";
import { VDomModel } from "@/app/view/vdom/vdom-model";
import { ErrorBoundary } from "@/element/errorboundary";
import { CenteredDiv } from "@/element/quickelems";
import { NodeModel, useDebouncedNodeInnerRect } from "@/layout/index";
import { useDebouncedNodeInnerRect } from "@/layout/index";
import {
counterInc,
getBlockComponentModel,
@ -30,14 +37,7 @@ import "./block.less";
import { BlockFrame } from "./blockframe";
import { blockViewToIcon, blockViewToName } from "./blockutil";
type FullBlockProps = {
isSubBlock?: boolean;
preview: boolean;
nodeModel: NodeModel;
viewModel: ViewModel;
};
function makeViewModel(blockId: string, blockView: string, nodeModel: NodeModel): ViewModel {
function makeViewModel(blockId: string, blockView: string, nodeModel: BlockNodeModel): ViewModel {
if (blockView === "term") {
return makeTerminalModel(blockId, nodeModel);
}
@ -146,7 +146,7 @@ const BlockPreview = memo(({ nodeModel, viewModel }: FullBlockProps) => {
);
});
const BlockSubBlock = memo(({ nodeModel, viewModel }: FullBlockProps) => {
const BlockSubBlock = memo(({ nodeModel, viewModel }: FullSubBlockProps) => {
const [blockData] = useWaveObjectValue<Block>(makeORef("block", nodeModel.blockId));
const blockRef = useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement>(null);
@ -304,10 +304,29 @@ const Block = memo((props: BlockProps) => {
if (props.preview) {
return <BlockPreview {...props} viewModel={viewModel} />;
}
if (props.isSubBlock) {
return <BlockSubBlock {...props} viewModel={viewModel} />;
}
return <BlockFull {...props} viewModel={viewModel} />;
});
export { Block };
const SubBlock = memo((props: SubBlockProps) => {
counterInc("render-Block");
counterInc("render-Block-" + props.nodeModel?.blockId?.substring(0, 8));
const [blockData, loading] = useWaveObjectValue<Block>(makeORef("block", props.nodeModel.blockId));
const bcm = getBlockComponentModel(props.nodeModel.blockId);
let viewModel = bcm?.viewModel;
if (viewModel == null || viewModel.viewType != blockData?.meta?.view) {
viewModel = makeViewModel(props.nodeModel.blockId, blockData?.meta?.view, props.nodeModel);
registerBlockComponentModel(props.nodeModel.blockId, { viewModel });
}
useEffect(() => {
return () => {
unregisterBlockComponentModel(props.nodeModel.blockId);
viewModel?.dispose?.();
};
}, []);
if (loading || isBlank(props.nodeModel.blockId) || blockData == null) {
return null;
}
return <BlockSubBlock {...props} viewModel={viewModel} />;
});
export { Block, SubBlock };

View File

@ -2,10 +2,33 @@
// SPDX-License-Identifier: Apache-2.0
import { NodeModel } from "@/layout/index";
export interface BlockProps {
isSubBlock?: boolean;
import { Atom } from "jotai";
export interface BlockNodeModel {
blockId: string;
isFocused: Atom<boolean>;
onClose: () => void;
focusNode: () => void;
}
export type FullBlockProps = {
preview: boolean;
nodeModel: NodeModel;
viewModel: ViewModel;
};
export interface BlockProps {
preview: boolean;
nodeModel: NodeModel;
}
export type FullSubBlockProps = {
nodeModel: BlockNodeModel;
viewModel: ViewModel;
};
export interface SubBlockProps {
nodeModel: BlockNodeModel;
}
export interface BlockComponentModel2 {

View File

@ -54,7 +54,7 @@
font: var(--fixed-font);
font-size: 0.85em;
color: var(--keybinding-color);
background-color: var(--keybinding-bg-color);
background-color: var(--highlight-bg-color);
border-radius: 4px;
border: 1px solid var(--keybinding-border-color);
box-shadow: none;

View File

@ -1,16 +1,16 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { BlockNodeModel } from "@/app/block/blocktypes";
import { getApi } from "@/app/store/global";
import { WebView, WebViewModel } from "@/app/view/webview/webview";
import { NodeModel } from "@/layout/index";
import { fireAndForget } from "@/util/util";
import { atom, useAtomValue } from "jotai";
import { useCallback } from "react";
import "./helpview.less";
class HelpViewModel extends WebViewModel {
constructor(blockId: string, nodeModel: NodeModel) {
constructor(blockId: string, nodeModel: BlockNodeModel) {
super(blockId, nodeModel);
this.getSettingsMenuItems = undefined;
this.viewText = atom((get) => {
@ -44,7 +44,7 @@ class HelpViewModel extends WebViewModel {
}
}
function makeHelpViewModel(blockId: string, nodeModel: NodeModel) {
function makeHelpViewModel(blockId: string, nodeModel: BlockNodeModel) {
return new HelpViewModel(blockId, nodeModel);
}

View File

@ -1,6 +1,7 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { BlockNodeModel } from "@/app/block/blocktypes";
import { CenteredDiv } from "@/app/element/quickelems";
import { TypeAheadModal } from "@/app/modals/typeaheadmodal";
import { ContextMenuModel } from "@/app/store/contextmenu";
@ -9,7 +10,6 @@ import { RpcApi } from "@/app/store/wshclientapi";
import { TabRpcClient } from "@/app/store/wshrpcutil";
import { CodeEditor } from "@/app/view/codeeditor/codeeditor";
import { Markdown } from "@/element/markdown";
import { NodeModel } from "@/layout/index";
import { atoms, createBlock, getConnStatusAtom, getSettingsKeyAtom, globalStore, refocusNode } from "@/store/global";
import * as services from "@/store/services";
import * as WOS from "@/store/wos";
@ -98,7 +98,7 @@ function isStreamingType(mimeType: string): boolean {
export class PreviewModel implements ViewModel {
viewType: string;
blockId: string;
nodeModel: NodeModel;
nodeModel: BlockNodeModel;
blockAtom: Atom<Block>;
viewIcon: Atom<string | IconButtonDecl>;
viewName: Atom<string>;
@ -141,7 +141,7 @@ export class PreviewModel implements ViewModel {
directoryKeyDownHandler: (waveEvent: WaveKeyboardEvent) => boolean;
codeEditKeyDownHandler: (waveEvent: WaveKeyboardEvent) => boolean;
constructor(blockId: string, nodeModel: NodeModel) {
constructor(blockId: string, nodeModel: BlockNodeModel) {
this.viewType = "preview";
this.blockId = blockId;
this.nodeModel = nodeModel;
@ -733,7 +733,7 @@ export class PreviewModel implements ViewModel {
}
}
function makePreviewModel(blockId: string, nodeModel: NodeModel): PreviewModel {
function makePreviewModel(blockId: string, nodeModel: BlockNodeModel): PreviewModel {
const previewModel = new PreviewModel(blockId, nodeModel);
return previewModel;
}

View File

@ -1,7 +1,8 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { Block } from "@/app/block/block";
import { Block, SubBlock } from "@/app/block/block";
import { BlockNodeModel } from "@/app/block/blocktypes";
import { getAllGlobalKeyBindings } from "@/app/store/keymodel";
import { waveEventSubscribe } from "@/app/store/wps";
import { RpcApi } from "@/app/store/wshclientapi";
@ -9,7 +10,6 @@ import { makeFeBlockRouteId } from "@/app/store/wshrouter";
import { DefaultRouter, TabRpcClient } from "@/app/store/wshrpcutil";
import { TermWshClient } from "@/app/view/term/term-wsh";
import { VDomModel } from "@/app/view/vdom/vdom-model";
import { NodeModel } from "@/layout/index";
import {
WOS,
atoms,
@ -41,7 +41,7 @@ type InitialLoadDataType = {
class TermViewModel {
viewType: string;
nodeModel: NodeModel;
nodeModel: BlockNodeModel;
connected: boolean;
termRef: React.RefObject<TermWrap>;
blockAtom: jotai.Atom<Block>;
@ -59,7 +59,7 @@ class TermViewModel {
fontSizeAtom: jotai.Atom<number>;
termThemeNameAtom: jotai.Atom<string>;
constructor(blockId: string, nodeModel: NodeModel) {
constructor(blockId: string, nodeModel: BlockNodeModel) {
this.viewType = "term";
this.blockId = blockId;
this.termWshClient = new TermWshClient(blockId, this);
@ -351,7 +351,7 @@ class TermViewModel {
}
}
function makeTerminalModel(blockId: string, nodeModel: NodeModel): TermViewModel {
function makeTerminalModel(blockId: string, nodeModel: BlockNodeModel): TermViewModel {
return new TermViewModel(blockId, nodeModel);
}
@ -407,6 +407,9 @@ const TermVDomNodeSingleId = ({ vdomBlockId, blockId, model }: TerminalViewProps
let vdomNodeModel = {
blockId: vdomBlockId,
isFocused: isFocusedAtom,
focusNode: () => {
model.nodeModel.focusNode();
},
onClose: () => {
if (vdomBlockId != null) {
RpcApi.DeleteSubBlockCommand(TabRpcClient, { blockid: vdomBlockId });
@ -415,7 +418,7 @@ const TermVDomNodeSingleId = ({ vdomBlockId, blockId, model }: TerminalViewProps
};
return (
<div key="htmlElem" className="term-htmlelem">
<Block key="vdom" isSubBlock={true} preview={false} nodeModel={vdomNodeModel} />
<SubBlock key="vdom" nodeModel={vdomNodeModel} />
</div>
);
};

View File

@ -1,6 +1,7 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { BlockNodeModel } from "@/app/block/blocktypes";
import { getBlockMetaKeyAtom, globalStore, WOS } from "@/app/store/global";
import { makeORef } from "@/app/store/wos";
import { waveEventSubscribe } from "@/app/store/wps";
@ -8,7 +9,6 @@ import { RpcResponseHelper, WshClient } from "@/app/store/wshclient";
import { RpcApi } from "@/app/store/wshclientapi";
import { makeFeBlockRouteId } from "@/app/store/wshrouter";
import { DefaultRouter, TabRpcClient } from "@/app/store/wshrpcutil";
import { NodeModel } from "@/layout/index";
import { adaptFromReactOrNativeKeyEvent, checkKeyPressed } from "@/util/keyutil";
import debug from "debug";
import * as jotai from "jotai";
@ -79,7 +79,7 @@ class VDomWshClient extends WshClient {
export class VDomModel {
blockId: string;
nodeModel: NodeModel;
nodeModel: BlockNodeModel;
viewType: string;
viewIcon: jotai.Atom<string>;
viewName: jotai.Atom<string>;
@ -109,7 +109,7 @@ export class VDomModel {
routeGoneUnsub: () => void;
routeConfirmed: boolean = false;
constructor(blockId: string, nodeModel: NodeModel) {
constructor(blockId: string, nodeModel: BlockNodeModel) {
this.viewType = "vdom";
this.blockId = blockId;
this.nodeModel = nodeModel;

View File

@ -9,8 +9,8 @@ import debug from "debug";
import * as jotai from "jotai";
import * as React from "react";
import { BlockNodeModel } from "@/app/block/blocktypes";
import { convertVDomId, getTextChildren, validateAndWrapCss } from "@/app/view/vdom/vdom-utils";
import { NodeModel } from "@/layout/index";
import "./vdom.less";
const TextTag = "#text";
@ -331,7 +331,7 @@ function VDomRoot({ model }: { model: VDomModel }) {
return <div className="vdom">{rtn}</div>;
}
function makeVDomModel(blockId: string, nodeModel: NodeModel): VDomModel {
function makeVDomModel(blockId: string, nodeModel: BlockNodeModel): VDomModel {
return new VDomModel(blockId, nodeModel);
}

View File

@ -1,12 +1,12 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { BlockNodeModel } from "@/app/block/blocktypes";
import { getApi, getSettingsKeyAtom, openLink } from "@/app/store/global";
import { getSimpleControlShiftAtom } from "@/app/store/keymodel";
import { ObjectService } from "@/app/store/services";
import { RpcApi } from "@/app/store/wshclientapi";
import { TabRpcClient } from "@/app/store/wshrpcutil";
import { NodeModel } from "@/layout/index";
import { WOS, globalStore } from "@/store/global";
import { adaptFromReactOrNativeKeyEvent, checkKeyPressed } from "@/util/keyutil";
import { fireAndForget } from "@/util/util";
@ -44,12 +44,12 @@ export class WebViewModel implements ViewModel {
refreshIcon: PrimitiveAtom<string>;
webviewRef: React.RefObject<WebviewTag>;
urlInputRef: React.RefObject<HTMLInputElement>;
nodeModel: NodeModel;
nodeModel: BlockNodeModel;
endIconButtons?: Atom<IconButtonDecl[]>;
mediaPlaying: PrimitiveAtom<boolean>;
mediaMuted: PrimitiveAtom<boolean>;
constructor(blockId: string, nodeModel: NodeModel) {
constructor(blockId: string, nodeModel: BlockNodeModel) {
this.nodeModel = nodeModel;
this.viewType = "web";
this.blockId = blockId;
@ -459,7 +459,7 @@ export class WebViewModel implements ViewModel {
}
}
function makeWebViewModel(blockId: string, nodeModel: NodeModel): WebViewModel {
function makeWebViewModel(blockId: string, nodeModel: BlockNodeModel): WebViewModel {
const webviewModel = new WebViewModel(blockId, nodeModel);
return webviewModel;
}