diff options
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/DocServer.ts | 1 | ||||
| -rw-r--r-- | src/client/util/ClientDiagnostics.ts | 34 | ||||
| -rw-r--r-- | src/client/util/TooltipTextMenu.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/Main.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/MainView.scss | 17 | ||||
| -rw-r--r-- | src/client/views/MainView.tsx | 106 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionDockingView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionStackingView.tsx | 20 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionStackingViewFieldColumn.tsx | 6 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionView.tsx | 16 | ||||
| -rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/ContentFittingDocumentView.tsx | 1 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 3 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 7 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 6 |
15 files changed, 113 insertions, 112 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index e4b183715..befe9ea5c 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -82,6 +82,7 @@ export namespace DocServer { Utils.AddServerHandler(_socket, MessageStore.UpdateField, respondToUpdate); Utils.AddServerHandler(_socket, MessageStore.DeleteField, respondToDelete); Utils.AddServerHandler(_socket, MessageStore.DeleteFields, respondToDelete); + _socket.on("connection_terminated", () => alert("Your connection to the server has been terminated.")); } function errorFunc(): never { diff --git a/src/client/util/ClientDiagnostics.ts b/src/client/util/ClientDiagnostics.ts deleted file mode 100644 index 0a213aa1c..000000000 --- a/src/client/util/ClientDiagnostics.ts +++ /dev/null @@ -1,34 +0,0 @@ -export namespace ClientDiagnostics { - - export async function start() { - - let serverPolls = 0; - const serverHandle = setInterval(async () => { - if (++serverPolls === 20) { - alert("Your connection to the server has been terminated."); - clearInterval(serverHandle); - } - await fetch("/serverHeartbeat"); - serverPolls--; - }, 1000 * 15); - - let executed = false; - let solrHandle: NodeJS.Timeout | undefined; - const handler = async () => { - const response = await fetch("/solrHeartbeat"); - if (!(await response.json()).running) { - if (!executed) { - alert("Looks like SOLR is not running on your machine."); - executed = true; - solrHandle && clearInterval(solrHandle); - } - } - }; - await handler(); - if (!executed) { - solrHandle = setInterval(handler, 1000 * 15); - } - - } - -}
\ No newline at end of file diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 89037dcb2..01d566831 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -1030,7 +1030,7 @@ export class TooltipTextMenu { TooltipTextMenuManager.Instance._brushMarks && TooltipTextMenuManager.Instance._brushMap.set(input.value, TooltipTextMenuManager.Instance._brushMarks); input.style.background = "lightGray"; } - } + }; const wrapper = document.createElement("div"); wrapper.appendChild(input); diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 9e699978f..b21eb9c8f 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -5,12 +5,10 @@ import * as ReactDOM from 'react-dom'; import * as React from 'react'; import { DocServer } from "../DocServer"; import { AssignAllExtensions } from "../../extensions/General/Extensions"; -import { ClientDiagnostics } from "../util/ClientDiagnostics"; AssignAllExtensions(); (async () => { - await ClientDiagnostics.start(); const info = await CurrentUserUtils.loadCurrentUser(); DocServer.init(window.location.protocol, window.location.hostname, 4321, info.email); await Docs.Prototypes.initialize(); diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 0ee30f117..a8924c6b1 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -7,11 +7,18 @@ width: 100%; } +.mainContent-div { + position: relative; + width:100%; + height:100%; +} + // add nodes menu. Note that the + button is actually an input label, not an actual button. .mainView-docButtons { position: absolute; bottom: 20px; - left: 250px; + left: calc(100% + 5px); + z-index: 1; } #mainView-container { @@ -27,13 +34,13 @@ width: 100%; height: 100%; position: absolute; + display: flex; } .mainView-flyoutContainer { display: flex; flex-direction: column; - position: absolute; - width: 100%; + position: relative; height: 100%; .documentView-node-topmost { @@ -59,9 +66,11 @@ .mainView-libraryFlyout { height: 100%; + width:100%; position: absolute; display: flex; flex-direction: column; + z-index: 1; } .mainView-expandFlyoutButton { @@ -73,6 +82,7 @@ .mainView-libraryHandle { width: 20px; + left: calc(100% - 10px); height: 40px; top: 50%; border: 1px solid black; @@ -80,6 +90,7 @@ position: absolute; z-index: 1; touch-action: none; + cursor: ew-resize; } .mainView-workspace { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 29719a6eb..bcdc3a453 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -15,7 +15,7 @@ import { List } from '../../new_fields/List'; import { listSpec } from '../../new_fields/Schema'; import { Cast, FieldValue, StrCast } from '../../new_fields/Types'; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; -import { emptyFunction, returnEmptyString, returnFalse, returnOne, returnTrue, Utils } from '../../Utils'; +import { emptyFunction, returnEmptyString, returnFalse, returnOne, returnTrue, Utils, emptyPath } from '../../Utils'; import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager'; import { DocServer } from '../DocServer'; import { Docs, DocumentOptions } from '../documents/Documents'; @@ -39,6 +39,7 @@ import MarqueeOptionsMenu from './collections/collectionFreeForm/MarqueeOptionsM import InkSelectDecorations from './InkSelectDecorations'; import { Scripting } from '../util/Scripting'; import { AudioBox } from './nodes/AudioBox'; +import { TraceMobx } from '../../new_fields/util'; @observer export class MainView extends React.Component { @@ -56,6 +57,7 @@ export class MainView extends React.Component { @computed private get userDoc() { return CurrentUserUtils.UserDocument; } @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeWorkspace, Doc)) : CurrentUserUtils.GuestWorkspace; } @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs && docs.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); } + @computed public get sidebarButtonsDoc() { return Cast(CurrentUserUtils.UserDocument.sidebarButtons, Doc) as Doc; } public isPointerDown = false; @@ -205,7 +207,7 @@ export class MainView extends React.Component { } @action - openWorkspace = async (doc: Doc, fromHistory = false) => { + openWorkspace = (doc: Doc, fromHistory = false) => { CurrentUserUtils.MainDocId = doc[Id]; if (doc) { // this has the side-effect of setting the main container since we're assigning the active/guest workspace @@ -260,38 +262,40 @@ export class MainView extends React.Component { getPHeight = () => this._panelHeight; getContentsHeight = () => this._panelHeight - this._buttonBarHeight; + @computed get mainDocView() { + return <DocumentView Document={this.mainContainer!} + DataDoc={undefined} + LibraryPath={emptyPath} + addDocument={undefined} + addDocTab={this.addDocTabFunc} + pinToPres={emptyFunction} + onClick={undefined} + ruleProvider={undefined} + removeDocument={undefined} + ScreenToLocalTransform={Transform.Identity} + ContentScaling={returnOne} + PanelWidth={this.getPWidth} + PanelHeight={this.getPHeight} + renderDepth={0} + backgroundColor={returnEmptyString} + focus={emptyFunction} + parentActive={returnTrue} + whenActiveChanged={emptyFunction} + bringToFront={emptyFunction} + ContainingCollectionView={undefined} + ContainingCollectionDoc={undefined} + zoomToScale={emptyFunction} + getScale={returnOne} + /> + } @computed get dockingContent() { + TraceMobx(); const mainContainer = this.mainContainer; - const flyoutWidth = this.flyoutWidth; // bcz: need to be here because Measure messes with observables. - const flyoutTranslate = this._flyoutTranslate; + const width = this.flyoutWidth; return <Measure offset onResize={this.onResize}> {({ measureRef }) => - <div ref={measureRef} id="mainContent-div" style={{ width: `calc(100% - ${flyoutTranslate ? flyoutWidth : 0}px`, transform: `translate(${flyoutTranslate ? flyoutWidth : 0}px, 0px)` }} onDrop={this.onDrop}> - {!mainContainer ? (null) : - <DocumentView Document={mainContainer} - DataDoc={undefined} - LibraryPath={[]} - addDocument={undefined} - addDocTab={this.addDocTabFunc} - pinToPres={emptyFunction} - onClick={undefined} - ruleProvider={undefined} - removeDocument={undefined} - ScreenToLocalTransform={Transform.Identity} - ContentScaling={returnOne} - PanelWidth={this.getPWidth} - PanelHeight={this.getPHeight} - renderDepth={0} - backgroundColor={returnEmptyString} - focus={emptyFunction} - parentActive={returnTrue} - whenActiveChanged={emptyFunction} - bringToFront={emptyFunction} - ContainingCollectionView={undefined} - ContainingCollectionDoc={undefined} - zoomToScale={emptyFunction} - getScale={returnOne} - />} + <div ref={measureRef} className="mainContent-div" onDrop={this.onDrop} style={{ width: `calc(100% - ${width}px)` }}> + {!mainContainer ? (null) : this.mainDocView} </div> } </Measure>; @@ -313,6 +317,7 @@ export class MainView extends React.Component { pointerOverDragger = () => { if (this.flyoutWidth === 0) { this.flyoutWidth = 250; + this.sidebarButtonsDoc.columnWidth = this.flyoutWidth / 3 - 30; this._flyoutTranslate = false; } } @@ -328,26 +333,22 @@ export class MainView extends React.Component { @action onPointerMove = (e: PointerEvent) => { this.flyoutWidth = Math.max(e.clientX, 0); + this.sidebarButtonsDoc.columnWidth = this.flyoutWidth / 3 - 30; } @action onPointerUp = (e: PointerEvent) => { if (Math.abs(e.clientX - this._flyoutSizeOnDown) < 4) { this.flyoutWidth = this.flyoutWidth < 5 ? 250 : 0; + this.flyoutWidth && (this.sidebarButtonsDoc.columnWidth = this.flyoutWidth / 3 - 30); } document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); } flyoutWidthFunc = () => this.flyoutWidth; - addDocTabFunc = (doc: Doc, data: Opt<Doc>, where: string, libraryPath?: Doc[]) => { - if (where === "close") { - return CollectionDockingView.CloseRightSplit(doc); - } - if (doc.dockingConfig) { - this.openWorkspace(doc); - return true; - } else { - return CollectionDockingView.AddRightSplit(doc, undefined, undefined, libraryPath); - } + addDocTabFunc = (doc: Doc, data: Opt<Doc>, where: string, libraryPath?: Doc[]): boolean => { + return where === "close" ? CollectionDockingView.CloseRightSplit(doc) : + doc.dockingConfig ? this.openWorkspace(doc) : + CollectionDockingView.AddRightSplit(doc, undefined, undefined, libraryPath); } mainContainerXf = () => new Transform(0, -this._buttonBarHeight, 1); @@ -357,13 +358,12 @@ export class MainView extends React.Component { return (null); } const sidebarButtonsDoc = Cast(CurrentUserUtils.UserDocument.sidebarButtons, Doc) as Doc; - sidebarButtonsDoc.columnWidth = this.flyoutWidth / 3 - 30; return <div className="mainView-flyoutContainer" > <div className="mainView-tabButtons" style={{ height: `${this._buttonBarHeight}px` }}> <DocumentView Document={sidebarButtonsDoc} DataDoc={undefined} - LibraryPath={[]} + LibraryPath={emptyPath} addDocument={undefined} addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} @@ -390,7 +390,7 @@ export class MainView extends React.Component { <DocumentView Document={sidebarContent} DataDoc={undefined} - LibraryPath={[]} + LibraryPath={emptyPath} addDocument={undefined} addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} @@ -416,6 +416,7 @@ export class MainView extends React.Component { {CurrentUserUtils.GuestWorkspace ? "Exit" : "Log Out"} </button> </div> + {this.docButtons} </div>; } @@ -423,10 +424,9 @@ export class MainView extends React.Component { const sidebar = this.userDoc && this.userDoc.sidebarContainer; return !this.userDoc || !(sidebar instanceof Doc) ? (null) : ( <div className="mainView-mainContent" > - <div className="mainView-flyoutContainer" onPointerLeave={this.pointerLeaveDragger}> - <div className="mainView-libraryHandle" - style={{ cursor: "ew-resize", left: `${(this.flyoutWidth * (this._flyoutTranslate ? 1 : 0)) - 10}px`, backgroundColor: `${StrCast(sidebar.backgroundColor, "lightGray")}` }} - onPointerDown={this.onPointerDown} onPointerOver={this.pointerOverDragger}> + <div className="mainView-flyoutContainer" onPointerLeave={this.pointerLeaveDragger} style={{ width: this.flyoutWidth }}> + <div className="mainView-libraryHandle" onPointerDown={this.onPointerDown} onPointerOver={this.pointerOverDragger} + style={{ backgroundColor: `${StrCast(sidebar.backgroundColor, "lightGray")}` }} > <span title="library View Dragger" style={{ width: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "100%" : "3vw", height: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "100%" : "100vh", @@ -435,11 +435,9 @@ export class MainView extends React.Component { }} /> </div> <div className="mainView-libraryFlyout" style={{ - width: `${this.flyoutWidth}px`, - zIndex: 1, - transformOrigin: this._flyoutTranslate ? "" : "left center", + //transformOrigin: this._flyoutTranslate ? "" : "left center", transition: this._flyoutTranslate ? "" : "width .5s", - transform: `scale(${this._flyoutTranslate ? 1 : 0.8})`, + //transform: `scale(${this._flyoutTranslate ? 1 : 0.8})`, boxShadow: this._flyoutTranslate ? "" : "rgb(156, 147, 150) 0.2vw 0.2vw 0.8vw" }}> {this.flyout} @@ -453,6 +451,7 @@ export class MainView extends React.Component { public static expandFlyout = action(() => { MainView.Instance._flyoutTranslate = true; MainView.Instance.flyoutWidth = (MainView.Instance.flyoutWidth || 250); + MainView.Instance.sidebarButtonsDoc.columnWidth = MainView.Instance.flyoutWidth / 3 - 30; }); @computed get expandButton() { @@ -471,12 +470,12 @@ export class MainView extends React.Component { @computed get docButtons() { if (CurrentUserUtils.UserDocument?.expandingButtons instanceof Doc) { return <div className="mainView-docButtons" ref={this._docBtnRef} - style={{ left: (this._flyoutTranslate ? this.flyoutWidth : 0) + 20, height: !CurrentUserUtils.UserDocument.expandingButtons.isExpanded ? "42px" : undefined }} > + style={{ height: !CurrentUserUtils.UserDocument.expandingButtons.isExpanded ? "42px" : undefined }} > <MainViewNotifs /> <CollectionLinearView Document={CurrentUserUtils.UserDocument.expandingButtons} DataDoc={undefined} - LibraryPath={[]} + LibraryPath={emptyPath} fieldKey={"data"} annotationsKey={""} select={emptyFunction} @@ -515,7 +514,6 @@ export class MainView extends React.Component { {this.mainContent} <PreviewCursor /> <ContextMenu /> - {this.docButtons} <PDFMenu /> <MarqueeOptionsMenu /> <OverlayView /> diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 4374cde3c..ffcb3e9ce 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -32,6 +32,7 @@ import React = require("react"); import { ButtonSelector } from './ParentDocumentSelector'; import { DocumentType } from '../../documents/DocumentTypes'; import { ComputedField } from '../../../new_fields/ScriptField'; +import { TraceMobx } from '../../../new_fields/util'; library.add(faFile); const _global = (window /* browser */ || global /* node */) as any; @@ -662,6 +663,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> { } @computed get docView() { + TraceMobx(); if (!this._document) return (null); const document = this._document; const resolvedDataDoc = document.layout instanceof Doc ? document : this._dataDoc; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 9f01de08b..ff3417b77 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -24,6 +24,7 @@ import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; import { ScriptBox } from "../ScriptBox"; import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow"; +import { TraceMobx } from "../../../new_fields/util"; @observer export class CollectionStackingView extends CollectionSubView(doc => doc) { @@ -383,17 +384,22 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } } + @computed get renderedSections() { + TraceMobx(); + let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]]; + if (this.sectionFilter) { + const entries = Array.from(this.Sections.entries()); + sections = entries.sort(this.sortFunc); + } + return sections.map(section => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1])); + } render() { + TraceMobx(); const editableViewProps = { GetValue: () => "", SetValue: this.addGroup, contents: "+ ADD A GROUP" }; - let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]]; - if (this.sectionFilter) { - const entries = Array.from(this.Sections.entries()); - sections = entries.sort(this.sortFunc); - } return ( <div className="collectionStackingMasonry-cont" > <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"} @@ -401,8 +407,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} - onWheel={(e: React.WheelEvent) => e.stopPropagation()} > - {sections.map(section => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1]))} + onWheel={e => e.stopPropagation()} > + {this.renderedSections} {!this.showAddAGroup ? (null) : <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton" style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}> diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 80dc482af..ca3b93bf8 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -17,6 +17,7 @@ import { anchorPoints, Flyout } from "../DocumentDecorations"; import { EditableView } from "../EditableView"; import { CollectionStackingView } from "./CollectionStackingView"; import "./CollectionStackingView.scss"; +import { TraceMobx } from "../../../new_fields/util"; library.add(faPalette); @@ -252,13 +253,12 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC @observable private collapsed: boolean = false; - private toggleVisibility = action(() => { - this.collapsed = !this.collapsed; - }); + private toggleVisibility = action(() => this.collapsed = !this.collapsed); @observable _headingsHack: number = 1; render() { + TraceMobx(); const cols = this.props.cols(); const key = StrCast(this.props.parent.props.Document.sectionFilter); let templatecols = ""; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 54f5a2c42..411040332 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -32,6 +32,8 @@ import { SelectionManager } from '../../util/SelectionManager'; import './CollectionView.scss'; import { FieldViewProps, FieldView } from '../nodes/FieldView'; import { Touchable } from '../Touchable'; +import { TraceMobx } from '../../../new_fields/util'; +const path = require('path'); library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy); export enum CollectionViewType { @@ -234,15 +236,23 @@ export class CollectionView extends Touchable<FieldViewProps> { } lightbox = (images: string[]) => { + if (!images.length) return (null); + const mainPath = path.extname(images[this._curLightboxImg]); + const nextPath = path.extname(images[(this._curLightboxImg + 1) % images.length]); + const prevPath = path.extname(images[(this._curLightboxImg + images.length - 1) % images.length]); + let main = images[this._curLightboxImg].replace(mainPath, "_o" + mainPath); + let next = images[(this._curLightboxImg + 1) % images.length].replace(nextPath, "_o" + nextPath); + let prev = images[(this._curLightboxImg + images.length - 1) % images.length].replace(prevPath, "_o" + prevPath); return !this._isLightboxOpen ? (null) : (<Lightbox key="lightbox" - mainSrc={images[this._curLightboxImg]} - nextSrc={images[(this._curLightboxImg + 1) % images.length]} - prevSrc={images[(this._curLightboxImg + images.length - 1) % images.length]} + mainSrc={main} + nextSrc={next} + prevSrc={prev} onCloseRequest={action(() => this._isLightboxOpen = false)} onMovePrevRequest={action(() => this._curLightboxImg = (this._curLightboxImg + images.length - 1) % images.length)} onMoveNextRequest={action(() => this._curLightboxImg = (this._curLightboxImg + 1) % images.length)} />); } render() { + TraceMobx(); const props: CollectionRenderProps = { addDocument: this.addDocument, removeDocument: this.removeDocument, diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 0d3748ded..81d8d467b 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -711,7 +711,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { case "pivot": computedElementData = this.doPivotLayout(this._layoutPoolData); break; default: computedElementData = this.doFreeformLayout(this._layoutPoolData); break; } - this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).forEach(pair => + this.childLayoutPairs.filter((pair, i) => this.isCurrent(pair.layout)).forEach(pair => computedElementData.elements.push({ ele: <CollectionFreeFormDocumentView key={pair.layout[Id]} dataProvider={this.childDataProvider} ruleProvider={this.Document.isRuleProvider ? this.props.Document : this.props.ruleProvider} diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 660a5bb7e..6d0ea33fa 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -45,6 +45,7 @@ interface ContentFittingDocumentViewProps { @observer export class ContentFittingDocumentView extends React.Component<ContentFittingDocumentViewProps>{ + public get displayName() { return "DocumentView(" + this.props.Document?.title + ")"; } // this makes mobx trace() statements more descriptive private get layoutDoc() { return this.props.Document && Doc.Layout(this.props.Document); } private get nativeWidth() { return NumCast(this.layoutDoc!.nativeWidth, this.props.PanelWidth()); } private get nativeHeight() { return NumCast(this.layoutDoc!.nativeHeight, this.props.PanelHeight()); } diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 13fd3cde1..1bbc82119 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -32,6 +32,7 @@ import { VideoBox } from "./VideoBox"; import { WebBox } from "./WebBox"; import { InkingStroke } from "../InkingStroke"; import React = require("react"); +import { TraceMobx } from "../../../new_fields/util"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? type BindingProps = Without<FieldViewProps, 'fieldKey'>; @@ -57,6 +58,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { hideOnLeave?: boolean }> { @computed get layout(): string { + TraceMobx(); if (!this.layoutDoc) return "<p>awaiting layout</p>"; const layout = Cast(this.layoutDoc[this.props.layoutKey], "string"); if (layout === undefined) { @@ -92,6 +94,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { } render() { + TraceMobx(); return (this.props.renderDepth > 7 || !this.layout) ? (null) : <ObserverJsxParser blacklistedAttrs={[]} diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 11fececd7..3ed010e8f 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -1078,8 +1078,11 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & getComputedStyle(this._ref.current!.parentElement!).top === "0px") { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation const nh = this.Document.isTemplateField ? 0 : NumCast(this.dataDoc.nativeHeight, 0); const dh = NumCast(this.layoutDoc.height, 0); - this.layoutDoc.height = Math.max(10, (nh ? dh / nh * scrollHeight : scrollHeight) + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0)); - this.dataDoc.nativeHeight = nh ? scrollHeight : undefined; + let newHeight = Math.max(10, (nh ? dh / nh * scrollHeight : scrollHeight) + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0)); + if (Math.abs(newHeight - dh) > 1) { // bcz: Argh! without this, we get into a React crash if the same document is opened in a freeform view and in the treeview. no idea why, but after dragging the freeform document, selecting it, and selecting text, it will compute to 1 pixel higher than the treeview which causes a cycle + this.layoutDoc.height = newHeight; + this.dataDoc.nativeHeight = nh ? scrollHeight : undefined; + } } } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index f60888929..4b3da3dae 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -215,6 +215,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum } _curSuffix = "_m"; + _resized = false; resize = (srcpath: string) => { requestImageSize(srcpath) .then((size: any) => { @@ -223,11 +224,12 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum const aspect = realsize.height / realsize.width; if (this.Document.width && (Math.abs(1 - NumCast(this.Document.height) / NumCast(this.Document.width) / (realsize.height / realsize.width)) > 0.1)) { setTimeout(action(() => { + this._resized = true; this.Document.height = this.Document[WidthSym]() * aspect; this.Document.nativeHeight = realsize.height; this.Document.nativeWidth = realsize.width; }), 0); - } + } else this._resized = true; }) .catch((err: any) => console.log(err)); } @@ -315,7 +317,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum const srcaspect = paths[Math.min(paths.length - 1, (this.Document.curPage || 0))][1] as number; const fadepath = paths[Math.min(paths.length - 1, 1)][0] as string; - !this.Document.ignoreAspect && this.resize(srcpath); + !this.Document.ignoreAspect && !this._resized && this.resize(srcpath); return <div className="imageBox-cont" key={this.props.Document[Id]} ref={this.createDropTarget} onContextMenu={this.specificContextMenu}> <div className="imageBox-fader" > |
