diff options
Diffstat (limited to 'src/client/views/nodes/formattedText/DashDocView.tsx')
-rw-r--r-- | src/client/views/nodes/formattedText/DashDocView.tsx | 120 |
1 files changed, 61 insertions, 59 deletions
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index c5167461b..7335c9286 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -1,18 +1,21 @@ -import { action, IReactionDisposer, observable, reaction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { NodeSelection } from 'prosemirror-state'; +import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; import { Doc } from '../../../../fields/Doc'; import { Height, Width } from '../../../../fields/DocSymbols'; -import { NumCast, StrCast } from '../../../../fields/Types'; +import { NumCast } from '../../../../fields/Types'; import { emptyFunction, returnFalse, Utils } from '../../../../Utils'; import { DocServer } from '../../../DocServer'; import { Docs, DocUtils } from '../../../documents/Documents'; import { Transform } from '../../../util/Transform'; -import { DocFocusOptions, DocumentView } from '../DocumentView'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; +import { DocumentView } from '../DocumentView'; +import { FocusViewOptions } from '../FieldView'; import { FormattedTextBox } from './FormattedTextBox'; -import React = require('react'); +var horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side. export class DashDocView { dom: HTMLSpanElement; // container for label and value root: any; @@ -21,8 +24,7 @@ export class DashDocView { this.dom = document.createElement('span'); this.dom.style.position = 'relative'; this.dom.style.textIndent = '0'; - this.dom.style.border = '1px solid ' + StrCast(tbox.layoutDoc.color, 'lightGray'); - this.dom.style.width = node.attrs.width; + this.dom.style.width = (+node.attrs.width.toString().replace('px', '') + horizPadding).toString(); this.dom.style.height = node.attrs.height; this.dom.style.display = node.attrs.hidden ? 'none' : 'inline-block'; (this.dom.style as any).float = node.attrs.float; @@ -62,7 +64,12 @@ export class DashDocView { } catch {} }); } - selectNode() {} + deselectNode() { + this.dom.style.backgroundColor = ''; + } + selectNode() { + this.dom.style.backgroundColor = 'rgb(141, 182, 247)'; + } } interface IDashDocViewInternal { @@ -78,27 +85,27 @@ interface IDashDocViewInternal { getPos: any; } @observer -export class DashDocViewInternal extends React.Component<IDashDocViewInternal> { +export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewInternal> { _spanRef = React.createRef<HTMLDivElement>(); _disposers: { [name: string]: IReactionDisposer } = {}; _textBox: FormattedTextBox; - @observable _dashDoc: Doc | undefined; - @observable _finalLayout: any; - @observable _width: number = 0; - @observable _height: number = 0; + @observable _dashDoc: Doc | undefined = undefined; + @computed get _width() { + return NumCast(this._dashDoc?._width); + } + @computed get _height() { + return NumCast(this._dashDoc?._height); + } updateDoc = action((dashDoc: Doc) => { this._dashDoc = dashDoc; - this._finalLayout = dashDoc; - if (this.props.width !== (this._dashDoc?._width ?? '') + 'px' || this.props.height !== (this._dashDoc?._height ?? '') + 'px') { + if (this._props.width !== (this._dashDoc?._width ?? '') + 'px' || this._props.height !== (this._dashDoc?._height ?? '') + 'px') { try { - this._width = NumCast(this._dashDoc?._width); - this._height = NumCast(this._dashDoc?._height); // bcz: an exception will be thrown if two embeddings are open at the same time when a doc view comment is made - this.props.view.dispatch( - this.props.view.state.tr.setNodeMarkup(this.props.getPos(), null, { - ...this.props.node.attrs, + this._props.view.dispatch( + this._props.view.state.tr.setNodeMarkup(this._props.getPos(), null, { + ...this._props.node.attrs, width: this._width + 'px', height: this._height + 'px', }) @@ -111,16 +118,17 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> { constructor(props: IDashDocViewInternal) { super(props); - this._textBox = this.props.tbox; + makeObservable(this); + this._textBox = this._props.tbox; - DocServer.GetRefField(this.props.docId + this.props.embedding).then(async dashDoc => { + DocServer.GetRefField(this._props.docId + this._props.embedding).then(async dashDoc => { if (!(dashDoc instanceof Doc)) { - this.props.embedding && - DocServer.GetRefField(this.props.docId).then(async dashDocBase => { + this._props.embedding && + DocServer.GetRefField(this._props.docId).then(async dashDocBase => { if (dashDocBase instanceof Doc) { - const embedding = Doc.MakeEmbedding(dashDocBase, this.props.docId + this.props.embedding); + const embedding = Doc.MakeEmbedding(dashDocBase, this._props.docId + this._props.embedding); embedding.layout_fieldKey = 'layout'; - this.props.fieldKey && DocUtils.makeCustomViewClicked(embedding, Docs.Create.StackingDocument, this.props.fieldKey, undefined); + this._props.fieldKey && DocUtils.makeCustomViewClicked(embedding, Docs.Create.StackingDocument, this._props.fieldKey, undefined); this.updateDoc(embedding); } }); @@ -132,23 +140,18 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> { componentDidMount() { this._disposers.upater = reaction( - () => this._dashDoc && NumCast(this._dashDoc._height) + NumCast(this._dashDoc._width), - action(() => { - if (this._dashDoc) { - this._width = NumCast(this._dashDoc._width); - this._height = NumCast(this._dashDoc._height); - const parent = this._spanRef.current?.parentNode as HTMLElement; - if (parent) { - parent.style.width = this._width + 'px'; - parent.style.height = this._height + 'px'; - } + () => ({ width: this._width, height: this._height, parent: this._spanRef.current?.parentNode as HTMLElement }), + action(({ width, height, parent }) => { + if (parent) { + parent.style.width = width + 'px'; + parent.style.height = height + 'px'; } }) ); } removeDoc = () => { - this.props.view.dispatch(this.props.view.state.tr.setSelection(new NodeSelection(this.props.view.state.doc.resolve(this.props.getPos()))).deleteSelection()); + this._props.view.dispatch(this._props.view.state.tr.setSelection(new NodeSelection(this._props.view.state.doc.resolve(this._props.getPos()))).deleteSelection()); return true; }; @@ -157,7 +160,7 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> { const { scale, translateX, translateY } = Utils.GetScreenTransform(this._spanRef.current); return new Transform(-translateX, -translateY, 1).scale(1 / scale); }; - outerFocus = (target: Doc, options: DocFocusOptions) => this._textBox.focus(target, options); // ideally, this would scroll to show the focus target + outerFocus = (target: Doc, options: FocusViewOptions) => this._textBox.focus(target, options); // ideally, this would scroll to show the focus target onKeyDown = (e: any) => { e.stopPropagation(); @@ -167,29 +170,30 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> { }; onPointerLeave = () => { - const ele = document.getElementById('DashDocCommentView-' + this.props.docId) as HTMLDivElement; + const ele = document.getElementById('DashDocCommentView-' + this._props.docId) as HTMLDivElement; ele && (ele.style.backgroundColor = ''); }; onPointerEnter = () => { - const ele = document.getElementById('DashDocCommentView-' + this.props.docId) as HTMLDivElement; + const ele = document.getElementById('DashDocCommentView-' + this._props.docId) as HTMLDivElement; ele && (ele.style.backgroundColor = 'orange'); }; componentWillUnmount = () => Object.values(this._disposers).forEach(disposer => disposer?.()); + isContentActive = () => this._props.tbox._props.isContentActive() || this._props.tbox.isAnyChildContentActive?.(); render() { - return !this._dashDoc || !this._finalLayout || this.props.hidden ? null : ( + return !this._dashDoc || this._props.hidden ? null : ( <div ref={this._spanRef} className="dash-span" style={{ - width: this._width, + width: `calc(100% - ${horizPadding}px)`, height: this._height, - position: 'absolute', - display: 'inline-block', - left: 0, - top: 0, + position: 'relative', + display: 'flex', + margin: 'auto', + pointerEvents: this.isContentActive() ? undefined : 'none', }} onPointerLeave={this.onPointerLeave} onPointerEnter={this.onPointerEnter} @@ -198,27 +202,25 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> { onKeyUp={e => e.stopPropagation()} onWheel={e => e.preventDefault()}> <DocumentView - Document={this._finalLayout} + Document={this._dashDoc} addDocument={returnFalse} - rootSelected={returnFalse} //{this._textBox.props.isSelected} removeDocument={this.removeDoc} isDocumentActive={returnFalse} - isContentActive={emptyFunction} - styleProvider={this._textBox.props.styleProvider} - docViewPath={this._textBox.props.docViewPath} + isContentActive={this.isContentActive} + styleProvider={this._textBox._props.styleProvider} + containerViewPath={this._textBox.DocumentView?.().docViewPath} ScreenToLocalTransform={this.getDocTransform} - addDocTab={this._textBox.props.addDocTab} + addDocTab={this._textBox._props.addDocTab} pinToPres={returnFalse} - renderDepth={this._textBox.props.renderDepth + 1} - PanelWidth={this._finalLayout[Width]} - PanelHeight={this._finalLayout[Height]} + renderDepth={this._textBox._props.renderDepth + 1} + PanelWidth={this._dashDoc[Width]} + PanelHeight={this._dashDoc[Height]} focus={this.outerFocus} - whenChildContentsActiveChanged={returnFalse} - bringToFront={emptyFunction} + whenChildContentsActiveChanged={this._props.tbox.whenChildContentsActiveChanged} dontRegisterView={false} - childFilters={this.props.tbox?.props.childFilters} - childFiltersByRanges={this.props.tbox?.props.childFiltersByRanges} - searchFilterDocs={this.props.tbox?.props.searchFilterDocs} + childFilters={this._props.tbox?._props.childFilters} + childFiltersByRanges={this._props.tbox?._props.childFiltersByRanges} + searchFilterDocs={this._props.tbox?._props.searchFilterDocs} /> </div> ); |