@@ -56,8 +56,11 @@ class TermViewModel {
5656 termWshClient : TermWshClient ;
5757 shellProcStatusRef : React . MutableRefObject < string > ;
5858 vdomBlockId : jotai . Atom < string > ;
59+ vdomToolbarBlockId : jotai . Atom < string > ;
60+ vdomToolbarTarget : jotai . PrimitiveAtom < VDomTargetToolbar > ;
5961 fontSizeAtom : jotai . Atom < number > ;
6062 termThemeNameAtom : jotai . Atom < string > ;
63+ noPadding : jotai . PrimitiveAtom < boolean > ;
6164
6265 constructor ( blockId : string , nodeModel : BlockNodeModel ) {
6366 this . viewType = "term" ;
@@ -70,6 +73,11 @@ class TermViewModel {
7073 const blockData = get ( this . blockAtom ) ;
7174 return blockData ?. meta ?. [ "term:vdomblockid" ] ;
7275 } ) ;
76+ this . vdomToolbarBlockId = jotai . atom ( ( get ) => {
77+ const blockData = get ( this . blockAtom ) ;
78+ return blockData ?. meta ?. [ "term:vdomtoolbarblockid" ] ;
79+ } ) ;
80+ this . vdomToolbarTarget = jotai . atom < VDomTargetToolbar > ( null ) as jotai . PrimitiveAtom < VDomTargetToolbar > ;
7381 this . termMode = jotai . atom ( ( get ) => {
7482 const blockData = get ( this . blockAtom ) ;
7583 return blockData ?. meta ?. [ "term:mode" ] ?? "term" ;
@@ -167,6 +175,7 @@ class TermViewModel {
167175 return blockData ?. meta ?. [ "term:theme" ] ?? get ( settingsKeyAtom ) ?? "default-dark" ;
168176 } ) ;
169177 } ) ;
178+ this . noPadding = jotai . atom ( true ) ;
170179 }
171180
172181 setTermMode ( mode : "term" | "vdom" ) {
@@ -191,6 +200,18 @@ class TermViewModel {
191200 return bcm . viewModel as VDomModel ;
192201 }
193202
203+ getVDomToolbarModel ( ) : VDomModel {
204+ const vdomToolbarBlockId = globalStore . get ( this . vdomToolbarBlockId ) ;
205+ if ( ! vdomToolbarBlockId ) {
206+ return null ;
207+ }
208+ const bcm = getBlockComponentModel ( vdomToolbarBlockId ) ;
209+ if ( ! bcm ) {
210+ return null ;
211+ }
212+ return bcm . viewModel as VDomModel ;
213+ }
214+
194215 dispose ( ) {
195216 DefaultRouter . unregisterRoute ( makeFeBlockRouteId ( this . blockId ) ) ;
196217 }
@@ -347,6 +368,15 @@ class TermViewModel {
347368 prtn . catch ( ( e ) => console . log ( "error controller resync (force restart)" , e ) ) ;
348369 } ,
349370 } ) ;
371+ if ( blockData ?. meta ?. [ "term:vdomtoolbarblockid" ] ) {
372+ fullMenu . push ( { type : "separator" } ) ;
373+ fullMenu . push ( {
374+ label : "Close Toolbar" ,
375+ click : ( ) => {
376+ RpcApi . DeleteSubBlockCommand ( TabRpcClient , { blockid : blockData . meta [ "term:vdomtoolbarblockid" ] } ) ;
377+ } ,
378+ } ) ;
379+ }
350380 return fullMenu ;
351381 }
352382}
@@ -382,6 +412,44 @@ const TermResyncHandler = React.memo(({ blockId, model }: TerminalViewProps) =>
382412 return null ;
383413} ) ;
384414
415+ const TermVDomToolbarNode = ( { vdomBlockId, blockId, model } : TerminalViewProps & { vdomBlockId : string } ) => {
416+ React . useEffect ( ( ) => {
417+ const unsub = waveEventSubscribe ( {
418+ eventType : "blockclose" ,
419+ scope : WOS . makeORef ( "block" , vdomBlockId ) ,
420+ handler : ( event ) => {
421+ RpcApi . SetMetaCommand ( TabRpcClient , {
422+ oref : WOS . makeORef ( "block" , blockId ) ,
423+ meta : {
424+ "term:mode" : null ,
425+ "term:vdomtoolbarblockid" : null ,
426+ } ,
427+ } ) ;
428+ } ,
429+ } ) ;
430+ return ( ) => {
431+ unsub ( ) ;
432+ } ;
433+ } , [ ] ) ;
434+ let vdomNodeModel = {
435+ blockId : vdomBlockId ,
436+ isFocused : jotai . atom ( false ) ,
437+ focusNode : ( ) => { } ,
438+ onClose : ( ) => {
439+ if ( vdomBlockId != null ) {
440+ RpcApi . DeleteSubBlockCommand ( TabRpcClient , { blockid : vdomBlockId } ) ;
441+ }
442+ } ,
443+ } ;
444+ const toolbarTarget = jotai . useAtomValue ( model . vdomToolbarTarget ) ;
445+ const heightStr = toolbarTarget ?. height ?? "1.5em" ;
446+ return (
447+ < div key = "vdomToolbar" className = "term-toolbar" style = { { height : heightStr } } >
448+ < SubBlock key = "vdom" nodeModel = { vdomNodeModel } />
449+ </ div >
450+ ) ;
451+ } ;
452+
385453const TermVDomNodeSingleId = ( { vdomBlockId, blockId, model } : TerminalViewProps & { vdomBlockId : string } ) => {
386454 React . useEffect ( ( ) => {
387455 const unsub = waveEventSubscribe ( {
@@ -431,6 +499,21 @@ const TermVDomNode = ({ blockId, model }: TerminalViewProps) => {
431499 return < TermVDomNodeSingleId key = { vdomBlockId } vdomBlockId = { vdomBlockId } blockId = { blockId } model = { model } /> ;
432500} ;
433501
502+ const TermToolbarVDomNode = ( { blockId, model } : TerminalViewProps ) => {
503+ const vdomToolbarBlockId = jotai . useAtomValue ( model . vdomToolbarBlockId ) ;
504+ if ( vdomToolbarBlockId == null ) {
505+ return null ;
506+ }
507+ return (
508+ < TermVDomToolbarNode
509+ key = { vdomToolbarBlockId }
510+ vdomBlockId = { vdomToolbarBlockId }
511+ blockId = { blockId }
512+ model = { model }
513+ />
514+ ) ;
515+ } ;
516+
434517const TerminalView = ( { blockId, model } : TerminalViewProps ) => {
435518 const viewRef = React . useRef < HTMLDivElement > ( null ) ;
436519 const connectElemRef = React . useRef < HTMLDivElement > ( null ) ;
@@ -547,14 +630,14 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
547630 cols : termRef . current ?. terminal . cols ?? 80 ,
548631 blockId : blockId ,
549632 } ;
550-
551633 return (
552634 < div className = { clsx ( "view-term" , "term-mode-" + termMode ) } ref = { viewRef } >
553635 < TermResyncHandler blockId = { blockId } model = { model } />
554636 < TermThemeUpdater blockId = { blockId } termRef = { termRef } />
555637 < TermStickers config = { stickerConfig } />
556- < div key = "conntectElem" className = "term-connectelem" ref = { connectElemRef } > </ div >
638+ < TermToolbarVDomNode key = "vdom-toolbar" blockId = { blockId } model = { model } / >
557639 < TermVDomNode key = "vdom" blockId = { blockId } model = { model } />
640+ < div key = "conntectElem" className = "term-connectelem" ref = { connectElemRef } > </ div >
558641 </ div >
559642 ) ;
560643} ;
0 commit comments