diff options
author | usodhi <61431818+usodhi@users.noreply.github.com> | 2021-04-08 01:01:43 -0400 |
---|---|---|
committer | usodhi <61431818+usodhi@users.noreply.github.com> | 2021-04-08 01:01:43 -0400 |
commit | 3d434ba49ed378cbbf0214d991ca448de0864a03 (patch) | |
tree | 216701eb8128b1558e65f474feb3a0fec3047d86 | |
parent | 0bc38e1ca78a5a2ee21d99ef511f2f744d8c67bb (diff) | |
parent | d0b37d7b5a8749cb6157d938ff576c7714c8ce0b (diff) |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into sharing_scenario
-rw-r--r-- | src/client/documents/Documents.ts | 6 | ||||
-rw-r--r-- | src/client/util/DragManager.ts | 2 | ||||
-rw-r--r-- | src/client/views/DocComponent.tsx | 2 | ||||
-rw-r--r-- | src/client/views/LightboxView.tsx | 4 | ||||
-rw-r--r-- | src/client/views/PropertiesButtons.tsx | 3 | ||||
-rw-r--r-- | src/client/views/SidebarAnnos.tsx | 3 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 60 | ||||
-rw-r--r-- | src/client/views/collections/TreeView.tsx | 25 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 83 |
10 files changed, 132 insertions, 58 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 17875a324..c5b210d1f 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -668,7 +668,7 @@ export namespace Docs { viewProps["acl-Override"] = "None"; viewProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add; const viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewProps, true, true); - ![DocumentType.LINK, DocumentType.TEXTANCHOR, DocumentType.LABEL].includes(viewDoc.type as any) && DocUtils.MakeLinkToActiveAudio(viewDoc); + ![DocumentType.LINK, DocumentType.TEXTANCHOR, DocumentType.LABEL].includes(viewDoc.type as any) && DocUtils.MakeLinkToActiveAudio(() => viewDoc); !Doc.IsSystem(dataDoc) && ![DocumentType.HTMLANCHOR, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR, DocumentType.TEXTANCHOR].includes(proto.type as any) && !dataDoc.isFolder && !dataProps.annotationOn && Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", dataDoc); @@ -1046,10 +1046,10 @@ export namespace DocUtils { export let ActiveRecordings: { props: FieldViewProps, getAnchor: () => Doc }[] = []; - export function MakeLinkToActiveAudio(doc: Doc, broadcastEvent = true) { + export function MakeLinkToActiveAudio(getSourceDoc: () => Doc, broadcastEvent = true) { broadcastEvent && runInAction(() => DocumentManager.Instance.RecordingEvent = DocumentManager.Instance.RecordingEvent + 1); return DocUtils.ActiveRecordings.map(audio => - DocUtils.MakeLink({ doc: doc }, { doc: audio.getAnchor() || audio.props.Document }, "recording link", "recording timeline")); + DocUtils.MakeLink({ doc: getSourceDoc() }, { doc: audio.getAnchor() || audio.props.Document }, "recording link", "recording timeline")); } export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", description: string = "", id?: string, allowParCollectionLink?: boolean, showPopup?: number[]) { diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index c1235163b..d8c2f913e 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -207,7 +207,7 @@ export namespace DragManager { ) { const addAudioTag = (dropDoc: any) => { dropDoc && !dropDoc.creationDate && (dropDoc.creationDate = new DateField); - dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(dropDoc); + dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(() => dropDoc); return dropDoc; }; const finishDrag = (e: DragCompleteEvent) => { diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 447daeb02..cff70afc2 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -68,7 +68,7 @@ export function ViewBoxBaseComponent<P extends ViewBoxBaseProps, T>(schemaCtor: isContentActive = (outsideReaction?: boolean) => (CurrentUserUtils.SelectedTool !== InkTool.None || (this.props.isContentActive?.() || this.props.Document.forceActive || this.props.isSelected(outsideReaction) || - this.props.rootSelected(outsideReaction)) ? true : false); + this.props.rootSelected(outsideReaction)) ? true : false) protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer; } return Component; diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index e33b3b35e..b26765fa7 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -116,7 +116,7 @@ export class LightboxView extends React.Component<LightboxViewProps> { const target = LightboxView._docTarget = LightboxView._future?.pop(); const targetDocView = target && DocumentManager.Instance.getLightboxDocumentView(target); if (targetDocView && target) { - const l = DocUtils.MakeLinkToActiveAudio(targetDocView.ComponentView?.getAnchor?.() || target).lastElement(); + const l = DocUtils.MakeLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.() || target).lastElement(); l && (Cast(l.anchor2, Doc, null).backgroundColor = "lightgreen"); targetDocView.focus(target, { originalTarget: target, willZoom: true, scale: 0.9 }); if (LightboxView._history?.lastElement().target !== target) LightboxView._history?.push({ doc, target }); @@ -282,7 +282,7 @@ interface LightboxTourBtnProps { export class LightboxTourBtn extends React.Component<LightboxTourBtnProps> { render() { return this.props.navBtn("50%", 0, 0, "chevron-down", - () => LightboxView.LightboxDoc && this.props.future()?.length ? "" : "none", e => { + () => LightboxView.LightboxDoc /*&& this.props.future()?.length*/ ? "" : "none", e => { e.stopPropagation(); this.props.stepInto(); }, diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index e1c0b96c0..5c41a96d0 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -188,6 +188,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { const isCollection = this.selectedDoc?.type === DocumentType.COL; const isStacking = this.selectedDoc?._viewType === CollectionViewType.Stacking; const isFreeForm = this.selectedDoc?._viewType === CollectionViewType.Freeform; + const isTree = this.selectedDoc?._viewType === CollectionViewType.Tree; const toggle = (ele: JSX.Element | null, style?: React.CSSProperties) => <div className="propertiesButtons-button" style={style}> {ele} </div>; return !this.selectedDoc ? (null) : @@ -199,7 +200,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { {toggle(this.onClickButton)} {toggle(this.fitWidthButton)} {toggle(this.fitContentButton, { display: !isFreeForm ? "none" : "" })} - {toggle(this.autoHeightButton, { display: !isText && !isStacking ? "none" : "" })} + {toggle(this.autoHeightButton, { display: !isText && !isStacking && !isTree ? "none" : "" })} {toggle(this.maskButton, { display: !isInk ? "none" : "" })} {toggle(this.chromeButton, { display: isCollection ? "" : "none" })} {toggle(this.gridButton, { display: isCollection ? "" : "none" })} diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index b5bdf4ca8..6c3eb1e95 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -16,6 +16,7 @@ import "./SidebarAnnos.scss"; import { StyleProp } from './StyleProvider'; import React = require("react"); import { DocumentViewProps } from './nodes/DocumentView'; +import { DocumentType } from '../documents/DocumentTypes'; interface ExtraProps { fieldKey: string; @@ -69,7 +70,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> { sidebarKey = () => this.props.fieldKey + "-sidebar"; filtersHeight = () => 50; screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(Doc.NativeWidth(this.props.dataDoc), 0).scale(this.props.scaling?.() || 1); - panelWidth = () => !this.props.layoutDoc._showSidebar ? 0 : (NumCast(this.props.layoutDoc.nativeWidth) - Doc.NativeWidth(this.props.dataDoc)) * this.props.PanelWidth() / NumCast(this.props.layoutDoc.nativeWidth); + panelWidth = () => !this.props.layoutDoc._showSidebar ? 0 : this.props.layoutDoc.type === DocumentType.RTF ? this.props.PanelWidth() : (NumCast(this.props.layoutDoc.nativeWidth) - Doc.NativeWidth(this.props.dataDoc)) * this.props.PanelWidth() / NumCast(this.props.layoutDoc.nativeWidth); panelHeight = () => this.props.PanelHeight() - this.filtersHeight(); addDocument = (doc: Doc | Doc[]) => this.props.sidebarAddDocument(doc, this.sidebarKey()); moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(doc, targetCollection, addDocument, this.sidebarKey()); diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index cc5a41c72..8d8c69fd5 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -23,7 +23,6 @@ import { EditableView } from "../EditableView"; import { LightboxView } from "../LightboxView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from "../nodes/DocumentView"; -import { FieldViewProps } from "../nodes/FieldView"; import { StyleProp } from "../StyleProvider"; import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow"; import "./CollectionStackingView.scss"; @@ -400,7 +399,6 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument, observeHeight={ref => { if (ref) { this.refList.push(ref); - const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; this.observer = new _global.ResizeObserver(action((entries: any) => { if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { const height = this.headerMargin + diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index ed0ed63b3..5a4864d2d 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed } from "mobx"; +import { action, computed, reaction, IReactionDisposer, observable } from "mobx"; import { observer } from "mobx-react"; import { DataSym, Doc, DocListCast, HeightSym, Opt, WidthSym } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; @@ -8,7 +8,7 @@ import { Document } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, Utils } from '../../../Utils'; +import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils'; import { DocUtils } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from "../../util/DragManager"; @@ -25,6 +25,9 @@ import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; import { TreeView } from "./TreeView"; import React = require("react"); +import { InkTool } from '../../../fields/InkField'; +import { CurrentUserUtils } from '../../util/CurrentUserUtils'; +const _global = (window /* browser */ || global /* node */) as any; export type collectionTreeViewProps = { treeViewExpandedView?: "fields" | "layout" | "links" | "data"; @@ -40,7 +43,9 @@ export type collectionTreeViewProps = { export class CollectionTreeView extends CollectionSubView<Document, Partial<collectionTreeViewProps>>(Document) { private treedropDisposer?: DragManager.DragDropDisposer; private _mainEle?: HTMLDivElement; + private _disposers: { [name: string]: IReactionDisposer } = {}; MainEle = () => this._mainEle; + @computed get doc() { return this.props.Document; } @computed get dataDoc() { return this.props.DataDoc || this.doc; } @computed get treeViewtruncateTitleWidth() { return NumCast(this.doc.treeViewTruncateTitleWidth, this.panelWidth()); } @@ -48,11 +53,45 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll @computed get outlineMode() { return this.doc.treeViewType === "outline"; } @computed get fileSysMode() { return this.doc.treeViewType === "fileSystem"; } + // these should stay in synch with counterparts in DocComponent.ts ViewBoxAnnotatableComponent + @observable _isAnyChildContentActive = false; + whenChildContentsActiveChanged = action((isActive: boolean) => this.props.whenChildContentsActiveChanged(this._isAnyChildContentActive = isActive)); + isContentActive = (outsideReaction?: boolean) => (CurrentUserUtils.SelectedTool !== InkTool.None || + (this.props.isContentActive?.() || this.props.Document.forceActive || + this.props.isSelected(outsideReaction) || this._isAnyChildContentActive || + this.props.rootSelected(outsideReaction)) ? true : false) + componentWillUnmount() { super.componentWillUnmount(); this.treedropDisposer?.(); + Object.values(this._disposers).forEach(disposer => disposer?.()); + } + + componentWillMount() { + this._disposers.autoheight = reaction(() => this.rootDoc.autoHeight, + auto => auto && this.computeHeight(), + { fireImmediately: true }) } + refList: Set<any> = new Set(); + observer: any; + computeHeight = () => { + this.rootDoc._height = this.paddingTop() + 26/* bcz: ugh: title bar height hack ... get ref and compute instead */ + + Array.from(this.refList).reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0); + } + unobserveHeight = (ref: any) => this.refList.delete(ref); + observerHeight = (ref: any) => { + if (ref) { + this.refList.add(ref); + this.observer = new _global.ResizeObserver(action((entries: any) => { + if (this.rootDoc.autoHeight && ref && this.refList.size && !SnappingManager.GetIsDragging()) { + this.computeHeight(); + } + })); + this.rootDoc.autoHeight && this.computeHeight(); + this.observer.observe(ref); + } + } protected createTreeDropTarget = (ele: HTMLDivElement) => { this.treedropDisposer?.(); if (this._mainEle = ele) this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.doc, this.onInternalPreDrop.bind(this)); @@ -134,6 +173,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll })} />; } + documentTitle = (childDocs: Doc[]) => { return <div style={{ display: "inline-block", width: "100%", height: this.documentTitleHeight() }} key={this.doc[Id]} onKeyDown={e => { @@ -146,6 +186,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll LayoutTemplateString={FormattedTextBox.LayoutString("text")} renderDepth={this.props.renderDepth + 1} isContentActive={this.isContentActive} + isDocumentActive={this.isContentActive} rootSelected={returnTrue} docViewPath={this.props.docViewPath} styleProvider={this.props.styleProvider} @@ -164,7 +205,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll addDocument={this.props.addDocument} moveDocument={returnFalse} removeDocument={returnFalse} - whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} + whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} bringToFront={returnFalse} @@ -191,7 +232,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll this.props.addDocTab, this.props.styleProvider, this.props.ScreenToLocalTransform, - this.props.isContentActive, + this.isContentActive, this.panelWidth, this.props.renderDepth, () => this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields), @@ -200,8 +241,10 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll this.onChildClick, this.props.treeViewSkipFields, true, - this.props.whenChildContentsActiveChanged, - this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null)); + this.whenChildContentsActiveChanged, + this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null), + this.observerHeight, + this.unobserveHeight); } @computed get titleBar() { const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle; @@ -217,23 +260,22 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll } paddingX = () => NumCast(this.doc._xPadding, 15); + paddingTop = () => NumCast(this.doc._yPadding, 20); documentTitleWidth = () => Math.min(this.layoutDoc?.[WidthSym](), this.panelWidth()); documentTitleHeight = () => Math.min(this.layoutDoc?.[HeightSym](), (StrCast(this.layoutDoc?._fontSize) ? Number(StrCast(this.layoutDoc?._fontSize, "32px").replace("px", "")) : NumCast(this.layoutDoc?._fontSize)) * 2); titleTransform = () => this.props.ScreenToLocalTransform().translate(-NumCast(this.doc._xPadding, 10), -NumCast(this.doc._yPadding, 20)); truncateTitleWidth = () => this.treeViewtruncateTitleWidth; onChildClick = () => this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick); panelWidth = () => this.props.PanelWidth() - 2 * this.paddingX(); - isContentActive = () => this.props.isContentActive() || this.props.isSelected(); render() { TraceMobx(); const background = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor); - const paddingTop = () => `${NumCast(this.doc._yPadding, 20)}px`; const pointerEvents = () => !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined; return !(this.doc instanceof Doc) || !this.treeChildren ? (null) : <div className="collectionTreeView-container" onContextMenu={this.onContextMenu}> <div className="collectionTreeView-dropTarget" - style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingTop: paddingTop(), pointerEvents: pointerEvents() }} + style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }} onWheel={e => e.stopPropagation()} onDrop={this.onTreeDrop} ref={this.createTreeDropTarget}> diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 914b21685..2c3a6c0d7 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -35,6 +35,8 @@ import React = require("react"); export interface TreeViewProps { treeView: CollectionTreeView; parentTreeView: TreeView | CollectionTreeView | undefined; + observeHeight: (ref: any) => void; + unobserveHeight: (ref: any) => void; prevSibling?: Doc; document: Doc; dataDoc?: Doc; @@ -76,13 +78,13 @@ export class TreeView extends React.Component<TreeViewProps> { static _editTitleOnLoad: Opt<{ id: string, parent: TreeView | CollectionTreeView | undefined }>; static _openTitleScript: Opt<ScriptField | undefined>; static _openLevelScript: Opt<ScriptField | undefined>; - private _header: React.RefObject<HTMLDivElement> = React.createRef();; + private _header: React.RefObject<HTMLDivElement> = React.createRef(); private _tref = React.createRef<HTMLDivElement>(); private _docRef: Opt<DocumentView>; private _selDisposer: Opt<IReactionDisposer>; private _editTitleScript: (() => ScriptField) | undefined; private _openScript: (() => ScriptField) | undefined; - private _treedropDisposer?: DragManager.DragDropDisposer + private _treedropDisposer?: DragManager.DragDropDisposer; get treeViewOpenIsTransient() { return this.props.treeView.doc.treeViewOpenIsTransient || Doc.IsPrototype(this.doc); } set treeViewOpen(c: boolean) { @@ -162,13 +164,17 @@ export class TreeView extends React.Component<TreeViewProps> { this._editTitleScript = Doc.IsSystem(this.props.document) ? () => TreeView._openLevelScript! : () => TreeView._openTitleScript!; } + _treeEle: any; protected createTreeDropTarget = (ele: HTMLDivElement) => { this._treedropDisposer?.(); ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), undefined, this.preTreeDrop.bind(this)), this.doc); + if (this._treeEle) this.props.unobserveHeight(this._treeEle); + this.props.observeHeight(this._treeEle = ele); } componentWillUnmount() { this._selDisposer?.(); + this._treeEle && this.props.unobserveHeight(this._treeEle) document.removeEventListener("pointermove", this.onDragMove, true); document.removeEventListener("pointermove", this.onDragUp, true); } @@ -322,7 +328,8 @@ export class TreeView extends React.Component<TreeViewProps> { this.props.treeView, this, doc, undefined, this.props.containerCollection, this.props.prevSibling, addDoc, remDoc, this.move, this.props.dropAction, this.props.addDocTab, this.titleStyleProvider, this.props.ScreenToLocalTransform, this.props.isContentActive, this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields, - [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged, this.props.dontRegisterView); + [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged, + this.props.dontRegisterView, emptyFunction, emptyFunction); } else { contentElement = <EditableView key="editableView" contents={contents !== undefined ? Field.toString(contents as Field) : "null"} @@ -403,7 +410,8 @@ export class TreeView extends React.Component<TreeViewProps> { this.dataDoc, this.props.containerCollection, this.props.prevSibling, addDoc, remDoc, this.move, StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.titleStyleProvider, this.props.ScreenToLocalTransform, this.props.isContentActive, this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields, - [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged, this.props.dontRegisterView)} + [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged, + this.props.dontRegisterView, emptyFunction, emptyFunction)} </ul >; } else if (this.treeViewExpandedView === "fields") { return <ul key={this.doc[Id] + this.doc.title}> @@ -534,7 +542,7 @@ export class TreeView extends React.Component<TreeViewProps> { } } } - titleWidth = () => Math.max(20, Math.min(this.props.treeView.truncateTitleWidth(), this.props.panelWidth() - treeBulletWidth())) + titleWidth = () => Math.max(20, Math.min(this.props.treeView.truncateTitleWidth(), this.props.panelWidth() - treeBulletWidth())); /** * Renders the EditableView title element for placement into the tree. @@ -782,6 +790,8 @@ export class TreeView extends React.Component<TreeViewProps> { firstLevel: boolean, whenChildContentsActiveChanged: (isActive: boolean) => void, dontRegisterView: boolean | undefined, + observerHeight: (ref: any) => void, + unobserveHeight: (ref: any) => void ) { const viewSpecScript = Cast(conainerCollection.viewSpecScript, ScriptField); if (viewSpecScript) { @@ -843,7 +853,10 @@ export class TreeView extends React.Component<TreeViewProps> { skipFields={skipFields} firstLevel={firstLevel} whenChildContentsActiveChanged={whenChildContentsActiveChanged} - parentTreeView={parentTreeView} />; + parentTreeView={parentTreeView} + observeHeight={observerHeight} + unobserveHeight={unobserveHeight} + />; }); } }
\ No newline at end of file diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 26e78cfbf..9482b632a 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -62,6 +62,7 @@ import { schema } from "./schema_rts"; import { SummaryView } from "./SummaryView"; import applyDevTools = require("prosemirror-dev-tools"); import React = require("react"); +import { SidebarAnnos } from '../../SidebarAnnos'; const translateGoogleApi = require("translate-google-api"); export interface FormattedTextBoxProps { @@ -91,6 +92,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp static _userStyleSheet: any = addStyleSheet(); static _canAnnotate = true; static _hadSelection: boolean = false; + private _sidebarRef = React.createRef<SidebarAnnos>(); private _ref: React.RefObject<HTMLDivElement> = React.createRef(); private _scrollRef: React.RefObject<HTMLDivElement> = React.createRef(); private _editorView: Opt<EditorView>; @@ -537,13 +539,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } + @action + toggleSidebar = () => { + const prevWidth = this.sidebarWidth(); + this.layoutDoc._showSidebar = ((this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, "0%") === "0%" ? "50%" : "0%")) !== "0%"; + this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); + } sidebarDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, - () => setTimeout(action(() => { - const prevWidth = this.sidebarWidth(); - this.layoutDoc._showSidebar = ((this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, "0%") === "0%" ? "50%" : "0%")) !== "0%"; - this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); - })), false); + setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), false); } sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { const bounds = this._ref.current!.getBoundingClientRect(); @@ -666,7 +669,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (this._break) { const textanchor = Docs.Create.TextanchorDocument({ title: "dictation anchor" }); this.addDocument(textanchor); - const link = DocUtils.MakeLinkToActiveAudio(textanchor, false).lastElement(); + const link = DocUtils.MakeLinkToActiveAudio(() => textanchor, false).lastElement(); link && (Doc.GetProto(link).isDictation = true); if (!link) return; const audioanchor = Cast(link.anchor2, Doc, null); @@ -1421,7 +1424,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } fitToBox = () => this.props.Document._fitToBox; sidebarContentScaling = () => (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1); - sidebarAddDocument = (doc: Doc | Doc[]) => this.addDocument(doc, this.SidebarKey); + sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => { + if (!this.layoutDoc._showSidebar) this.toggleSidebar(); + return this.addDocument(doc, sidebarKey); + } sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.SidebarKey); sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.SidebarKey); setSidebarHeight = (height: number) => this.rootDoc[this.SidebarKey + "-height"] = height; @@ -1445,30 +1451,43 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get sidebarCollection() { const renderComponent = (tag: string) => { const ComponentTag = tag === "freeform" ? CollectionFreeFormView : tag === "translation" ? FormattedTextBox : CollectionStackingView; - return <ComponentTag - {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit} - NativeWidth={returnZero} - NativeHeight={returnZero} - PanelHeight={this.props.PanelHeight} - PanelWidth={this.sidebarWidth} - xMargin={0} - yMargin={0} - scaleField={this.SidebarKey + "-scale"} - isAnnotationOverlay={false} - select={emptyFunction} - isContentActive={this.isContentActive} - scaling={this.sidebarContentScaling} - whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} - removeDocument={this.sidebarRemDocument} - moveDocument={this.sidebarMoveDocument} - addDocument={this.sidebarAddDocument} - CollectionView={undefined} - ScreenToLocalTransform={this.sidebarScreenToLocal} - renderDepth={this.props.renderDepth + 1} - setHeight={this.setSidebarHeight} - fitContentsToDoc={this.fitToBox} - noSidebar={true} - fieldKey={this.layoutDoc.sidebarViewType === "translation" ? `${this.fieldKey}-translation` : this.SidebarKey} />; + return ComponentTag === CollectionStackingView ? + <SidebarAnnos ref={this._sidebarRef} + {...this.props} + fieldKey={this.annotationKey} + rootDoc={this.rootDoc} + layoutDoc={this.layoutDoc} + dataDoc={this.dataDoc} + PanelWidth={this.sidebarWidth} + sidebarAddDocument={this.sidebarAddDocument} + moveDocument={this.moveDocument} + removeDocument={this.removeDocument} + isContentActive={this.isContentActive} + /> : + <ComponentTag + {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit} + NativeWidth={returnZero} + NativeHeight={returnZero} + PanelHeight={this.props.PanelHeight} + PanelWidth={this.sidebarWidth} + xMargin={0} + yMargin={0} + scaleField={this.SidebarKey + "-scale"} + isAnnotationOverlay={false} + select={emptyFunction} + isContentActive={this.isContentActive} + scaling={this.sidebarContentScaling} + whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} + removeDocument={this.sidebarRemDocument} + moveDocument={this.sidebarMoveDocument} + addDocument={this.sidebarAddDocument} + CollectionView={undefined} + ScreenToLocalTransform={this.sidebarScreenToLocal} + renderDepth={this.props.renderDepth + 1} + setHeight={this.setSidebarHeight} + fitContentsToDoc={this.fitToBox} + noSidebar={true} + fieldKey={this.layoutDoc.sidebarViewType === "translation" ? `${this.fieldKey}-translation` : this.SidebarKey} />; }; return <div className={"formattedTextBox-sidebar" + (CurrentUserUtils.SelectedTool !== InkTool.None ? "-inking" : "")} style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}> |