diff options
Diffstat (limited to 'src/client/views/collections')
19 files changed, 116 insertions, 223 deletions
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index f0b9b5240..b2ae441d6 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -54,7 +54,6 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume PanelHeight={this.panelHeight} ScreenToLocalTransform={this.props.ScreenToLocalTransform} bringToFront={returnFalse} - parentActive={this.props.active} />; }; @@ -127,7 +126,7 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume } @computed get buttons() { - if (!this.props.active()) return null; + if (!this.props.isContentActive()) return null; return <div className="arrow-buttons" > <div key="back" className="carousel3DView-back" style={{ background: `${StrCast(this.props.Document.backgroundColor)}` }} onClick={(e) => this.onArrowClick(e, -1)} diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index f400ac5a2..cc90b9134 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -58,7 +58,6 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) PanelHeight={this.panelHeight} ScreenToLocalTransform={this.props.ScreenToLocalTransform} bringToFront={returnFalse} - parentActive={this.props.active} /> </div> <div className="collectionCarouselView-caption" key="caption" diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index ead0ce6c4..5c12bd126 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -154,8 +154,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { styleProvider={this.props.styleProvider} layerProvider={this.props.layerProvider} docViewPath={returnEmptyDoclist} - parentActive={returnTrue} - whenActiveChanged={emptyFunction} + whenChildContentsActiveChanged={emptyFunction} bringToFront={emptyFunction} docFilters={this.props.docFilters} docRangeFilters={this.props.docRangeFilters} diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx index 92288c1f2..2d7569d45 100644 --- a/src/client/views/collections/CollectionMapView.tsx +++ b/src/client/views/collections/CollectionMapView.tsx @@ -208,7 +208,7 @@ export class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMap render() { const { childLayoutPairs } = this; - const { Document, fieldKey, active, google } = this.props; + const { Document, fieldKey, isContentActive: active, google } = this.props; const mapLoc = this.getLocation(this.rootDoc, `${fieldKey}-mapCenter`, false); let center = mapLoc; if (center === undefined) { diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index ba701b2a4..a94e706eb 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -281,7 +281,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ""), }}> {this.props.parent.children(this.props.docList)} - {this.props.showHandle && this.props.parent.props.active() ? this.props.parent.columnDragger : (null)} + {this.props.showHandle && this.props.parent.props.isContentActive() ? this.props.parent.columnDragger : (null)} </div> </div>; } diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index a265045b8..d49403d8e 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -328,7 +328,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @action onWheel(e: React.WheelEvent) { const scale = this.props.ScreenToLocalTransform().Scale; - this.props.active(true) && e.stopPropagation(); + this.props.isContentActive(true) && e.stopPropagation(); } @computed get renderMenuContent() { @@ -422,8 +422,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { moveDocument={this.props.moveDocument} addDocument={this.props.addDocument} removeDocument={this.props.removeDocument} - parentActive={this.props.active} - whenActiveChanged={this.props.whenActiveChanged} + whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} bringToFront={returnFalse} @@ -445,7 +444,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { renderDepth={this.props.renderDepth} moveDocument={this.props.moveDocument} ScreenToLocalTransform={this.props.ScreenToLocalTransform} - active={this.props.active} + active={this.props.isContentActive} onDrop={this.onExternalDrop} addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} @@ -534,11 +533,11 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { this.columns = columns; } - onZoomMenu = (e: React.WheelEvent) => this.props.active(true) && e.stopPropagation(); + onZoomMenu = (e: React.WheelEvent) => this.props.isContentActive(true) && e.stopPropagation(); render() { TraceMobx(); - if (!this.props.active()) setTimeout(() => this.closeHeader(), 0); + if (!this.props.isContentActive()) setTimeout(() => this.closeHeader(), 0); const menuContent = this.renderMenuContent; const menu = <div className="collectionSchema-header-menu" onWheel={e => this.onZoomMenu(e)} @@ -554,21 +553,21 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return <div className={"collectionSchemaView" + (this.props.Document._searchDoc ? "-searchContainer" : "-container")} style={{ overflow: this.props.scrollOverflow === true ? "scroll" : undefined, backgroundColor: "white", - pointerEvents: this.props.Document._searchDoc !== undefined && !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined, + pointerEvents: this.props.Document._searchDoc !== undefined && !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined, width: name === "collectionSchemaView-searchContainer" ? "auto" : this.props.PanelWidth() || "100%", height: this.props.PanelHeight() || "100%", position: "relative", }} > <div className="collectionSchemaView-tableContainer" style={{ width: `calc(100% - ${this.previewWidth()}px)` }} onContextMenu={this.onSpecificMenu} onPointerDown={this.onPointerDown} - onWheel={e => this.props.active(true) && e.stopPropagation()} + onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} onDrop={e => this.onExternalDrop(e, {})} ref={this.createTarget}> {this.schemaTable} </div> {this.dividerDragger} {!this.previewWidth() ? (null) : this.previewPanel} - {this._headerOpen && this.props.active() ? menu : null} + {this._headerOpen && this.props.isContentActive() ? menu : null} </div>; } }
\ No newline at end of file diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index c0cebf021..3168ef4ba 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -32,7 +32,6 @@ export type CollectionStackedTimelineProps = { playFrom: (seekTimeInSeconds: number, endTime?: number) => void; playing: () => boolean; setTime: (time: number) => void; - isChildActive: () => boolean; startTag: string; endTag: string; mediaPath: string; @@ -114,7 +113,7 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument onPointerDownTimeline = (e: React.PointerEvent): void => { const rect = this._timeline?.getBoundingClientRect(); const clientX = e.clientX; - if (rect && this.props.active()) { + if (rect && this.props.isContentActive()) { const wasPlaying = this.props.playing(); if (wasPlaying) this.props.Pause(); const wasSelecting = CollectionStackedTimeline.SelectingRegion === this; @@ -145,7 +144,7 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument e.shiftKey && CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.props.fieldKey, this.props.startTag, this.props.endTag, this.currentTime); !wasPlaying && doubleTap && this.props.Play(); }, - this.props.isSelected(true) || this.props.isChildActive(), undefined, + this.props.isSelected(true) || this.props.isContentActive(), undefined, () => !wasPlaying && this.props.setTime((clientX - rect.x) / rect.width * this.duration)); } } @@ -244,12 +243,13 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument Document={dictation} PanelHeight={this.dictationHeight} isAnnotationOverlay={true} + isDocumentActive={returnFalse} select={emptyFunction} scaling={returnOne} xMargin={25} yMargin={10} ScreenToLocalTransform={this.dictationScreenToLocalTransform} - whenActiveChanged={emptyFunction} + whenChildContentsActiveChanged={emptyFunction} removeDocument={returnFalse} moveDocument={returnFalse} addDocument={returnFalse} @@ -274,7 +274,7 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument const overlaps: { anchorStartTime: number, anchorEndTime: number, level: number }[] = []; const drawAnchors = this.childDocs.map(anchor => ({ level: this.getLevel(anchor, overlaps), anchor })); const maxLevel = overlaps.reduce((m, o) => Math.max(m, o.level), 0) + 2; - const isActive = this.props.isChildActive() || this.props.isSelected(false); + const isActive = this.props.isContentActive() || this.props.isSelected(false); return <div className="collectionStackedTimeline" ref={(timeline: HTMLDivElement | null) => this._timeline = timeline} onClick={e => isActive && StopEvent(e)} onPointerDown={e => isActive && this.onPointerDownTimeline(e)}> {drawAnchors.map(d => { @@ -323,7 +323,6 @@ interface StackedTimelineAnchorProps { toTimeline: (screen_delta: number, width: number) => number; playLink: (linkDoc: Doc) => void; setTime: (time: number) => void; - isChildActive: () => boolean; startTag: string; endTag: string; renderDepth: number; @@ -395,11 +394,11 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps> renderDepth={this.props.renderDepth + 1} LayoutTemplate={undefined} LayoutTemplateString={LabelBox.LayoutString("data")} + isDocumentActive={returnFalse} PanelWidth={() => width} PanelHeight={() => height} ScreenToLocalTransform={() => this.props.ScreenToLocalTransform().translate(-x, -y)} focus={focusFunc} - parentActive={out => this.props.isSelected(out) || this.props.isChildActive()} rootSelected={returnFalse} onClick={script} onDoubleClick={this.props.layoutDoc.autoPlayAnchors ? undefined : doublescript} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 23c63561c..cc5a41c72 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -196,7 +196,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument, }); } - styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps | FieldViewProps>, property: string) => { + styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => { if (property === StyleProp.Opacity && doc) { if (this.props.childOpacity) { return this.props.childOpacity(); @@ -207,6 +207,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument, } return this.props.styleProvider?.(doc, props, property); } + isContentActive = () => this.props.isSelected() || this.props.isContentActive(); getDisplayDoc(doc: Doc, width: () => number) { const dataDoc = (!doc.isTemplateDoc && !doc.isTemplateForField && !doc.PARAMS) ? undefined : this.props.DataDoc; const height = () => this.getDocHeight(doc); @@ -224,6 +225,8 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument, layerProvider={this.props.layerProvider} docViewPath={this.props.docViewPath} fitWidth={this.props.childFitWidth} + isContentActive={returnFalse} + isDocumentActive={this.isContentActive} LayoutTemplate={this.props.childLayoutTemplate} LayoutTemplateString={this.props.childLayoutString} freezeDimensions={this.props.childFreezeDimensions} @@ -248,8 +251,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument, moveDocument={this.props.moveDocument} removeDocument={this.props.removeDocument} contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents)} - parentActive={this.props.active} - whenActiveChanged={this.props.whenActiveChanged} + whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} addDocTab={this.addDocTab} bringToFront={returnFalse} scriptContext={this.props.scriptContext} @@ -534,14 +536,14 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument, <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"} ref={this.createRef} style={{ - overflowY: this.props.active() ? "auto" : "hidden", + overflowY: this.props.isContentActive() ? "auto" : "hidden", background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor), pointerEvents: this.backgroundEvents ? "all" : undefined }} onScroll={action(e => this._scroll = e.currentTarget.scrollTop)} onDrop={this.onExternalDrop.bind(this)} onContextMenu={this.onContextMenu} - onWheel={e => this.props.active(true) && e.stopPropagation()} > + onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} > {this.renderedSections} {!this.showAddAGroup ? (null) : <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton" diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 0702febae..f41043179 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -136,7 +136,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { } @computed get contents() { - return <div className="collectionTimeView-innards" key="timeline" style={{ pointerEvents: this.props.active() ? undefined : "none" }} + return <div className="collectionTimeView-innards" key="timeline" style={{ pointerEvents: this.props.isContentActive() ? undefined : "none" }} onClick={this.contentsDown}> <CollectionFreeFormView {...this.props} engineProps={{ pivotField: this.pivotField, docFilters: this.docFilters, docRangeFilters: this.docRangeFilters }} diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 525fa8ca1..d80534ef9 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -165,6 +165,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll DataDoc={undefined} LayoutTemplateString={FormattedTextBox.LayoutString("text")} renderDepth={this.props.renderDepth + 1} + isContentActive={() => this.props.isContentActive() || this.props.isSelected()} rootSelected={returnTrue} //dontRegisterView={true} docViewPath={this.props.docViewPath} @@ -184,8 +185,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll addDocument={this.props.addDocument} moveDocument={returnFalse} removeDocument={returnFalse} - parentActive={this.props.active} - whenActiveChanged={this.props.whenActiveChanged} + whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} bringToFront={returnFalse} @@ -197,8 +197,8 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll @computed get outlineMode() { return this.doc.treeViewType === "outline"; } @computed get fileSysMode() { return this.doc.treeViewType === "fileSystem"; } onChildClick = () => this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick); - whenActiveChanged = (isActive: boolean) => { this.props.whenActiveChanged(this._isChildActive = isActive); }; - active = (outsideReaction: boolean | undefined) => this.props.active(outsideReaction) || this._isChildActive; + whenChildContentsActiveChanged = (isActive: boolean) => { this.props.whenChildContentsActiveChanged(this._isChildActive = isActive); }; + active = (outsideReaction: boolean | undefined) => this.props.isContentActive(outsideReaction) || this._isChildActive; panelWidth = () => this.props.PanelWidth() - 20; // bcz: 20 is the 10 + 10 for the left and right padding. @computed get treeChildren() { TraceMobx(); @@ -213,7 +213,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.styleProvider, returnTrue, this.props.ScreenToLocalTransform, this.outerXf, this.active, this.panelWidth, this.props.renderDepth, () => this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields), BoolCast(this.doc.treeViewPreventOpen), [], this.props.onCheckedClick, - this.onChildClick, this.props.treeViewSkipFields, true, this.whenActiveChanged, this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null), this); + this.onChildClick, this.props.treeViewSkipFields, true, this.whenChildContentsActiveChanged, this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null), this); } @computed get titleBar() { const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle; @@ -225,13 +225,13 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll const background = this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor); const paddingX = `${NumCast(this.doc._xPadding, 15)}px`; const paddingTop = `${NumCast(this.doc._yPadding, 20)}px`; - const pointerEvents = !this.props.active() && !SnappingManager.GetIsDragging() && !this._isChildActive ? "none" : undefined; + const pointerEvents = !this.props.isContentActive() && !SnappingManager.GetIsDragging() && !this._isChildActive ? "none" : undefined; return !this.treeChildren ? (null) : ( <div className="collectionTreeView-container" onContextMenu={this.onContextMenu}> <div className="collectionTreeView-dropTarget" style={{ background, paddingLeft: paddingX, paddingRight: paddingX, paddingTop, pointerEvents }} - onWheel={(e) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()} + onWheel={e => e.stopPropagation()} onDrop={this.onTreeDrop} ref={this.createTreeDropTarget}> {this.titleBar} diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 535bf539e..28099a995 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -2,26 +2,23 @@ import { action, computed, observable } from 'mobx'; import { observer } from "mobx-react"; import * as React from 'react'; import 'react-image-lightbox-with-rotate/style.css'; // This only needs to be imported once in your app -import { DateField } from '../../../fields/DateField'; -import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, DataSym, Doc, DocListCast, DocListCastAsync, Field } from '../../../fields/Doc'; +import { Doc, DocListCast } from '../../../fields/Doc'; +import { documentSchema } from '../../../fields/documentSchemas'; import { Id } from '../../../fields/FieldSymbols'; -import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; +import { makeInterface } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; -import { Cast, ScriptCast, StrCast, DateCast } from '../../../fields/Types'; -import { denormalizeEmail, distributeAcls, GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util'; -import { returnFalse } from '../../../Utils'; -import { Docs, DocUtils } from '../../documents/Documents'; -import { BranchTask, BranchCreate } from '../../documents/Gitlike'; -import { DocumentType } from '../../documents/DocumentTypes'; +import { Cast, ScriptCast, StrCast } from '../../../fields/Types'; +import { TraceMobx } from '../../../fields/util'; +import { DocUtils } from '../../documents/Documents'; +import { BranchCreate, BranchTask } from '../../documents/Gitlike'; import { CurrentUserUtils } from '../../util/CurrentUserUtils'; import { ImageUtils } from '../../util/Import & Export/ImageUtils'; import { InteractionUtils } from '../../util/InteractionUtils'; -import { UndoManager } from '../../util/UndoManager'; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from '../ContextMenuItem'; +import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent'; import { FieldView, FieldViewProps } from '../nodes/FieldView'; -import { Touchable } from '../Touchable'; import { CollectionCarousel3DView } from './CollectionCarousel3DView'; import { CollectionCarouselView } from './CollectionCarouselView'; import { CollectionDockingView } from "./CollectionDockingView"; @@ -64,8 +61,6 @@ export enum CollectionViewType { export interface CollectionViewProps extends FieldViewProps { isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc) layoutEngine?: () => string; - parentActive: (outsideReaction: boolean) => boolean; - filterAddDocument?: (doc: Doc | Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example) setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; // property overrides for child documents @@ -82,19 +77,20 @@ export interface CollectionViewProps extends FieldViewProps { childClickScript?: ScriptField; childDoubleClickScript?: ScriptField; } + +type CollectionDocument = makeInterface<[typeof documentSchema]>; +const CollectionDocument = makeInterface(documentSchema); @observer -export class CollectionView extends Touchable<CollectionViewProps> { +export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & CollectionViewProps, CollectionDocument>(CollectionDocument, "") { public static LayoutString(fieldStr: string) { return FieldView.LayoutString(CollectionView, fieldStr); } - _isChildActive = false; //TODO should this be observable? - @observable private _curLightboxImg = 0; @observable private static _safeMode = false; public static SetSafeMode(safeMode: boolean) { this._safeMode = safeMode; } protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer; get collectionViewType(): CollectionViewType | undefined { - const viewField = StrCast(this.props.Document._viewType); + const viewField = StrCast(this.layoutDoc._viewType); if (CollectionView._safeMode) { switch (viewField) { case CollectionViewType.Freeform: @@ -105,121 +101,24 @@ export class CollectionView extends Touchable<CollectionViewProps> { return viewField as any as CollectionViewType; } - active = (outsideReaction?: boolean) => { - return this.props.renderDepth === 0 || - this.props.isSelected(outsideReaction) || - this.props.rootSelected(outsideReaction) || - (this.props.layerProvider?.(this.props.Document) !== false && (this.props.Document.forceActive || this.props.Document._isGroup)) || - this._isChildActive ? - true : - false; - } - - whenActiveChanged = (isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive); - - @action.bound - addDocument = (doc: Doc | Doc[]): boolean => { - if (this.props.filterAddDocument?.(doc) === false) { - return false; - } - - const docs = doc instanceof Doc ? [doc] : doc; - - if (docs.find(doc => Doc.AreProtosEqual(doc, this.props.Document))) return false; - const targetDataDoc = this.props.Document[DataSym]; - const docList = DocListCast(targetDataDoc[this.props.fieldKey]); - const added = docs.filter(d => !docList.includes(d)); - const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]); - - if (added.length) { - if (effectiveAcl === AclPrivate || effectiveAcl === AclReadonly) { - return false; - } - else { - if (this.props.Document[AclSym] && Object.keys(this.props.Document[AclSym])) { - added.forEach(d => { - for (const [key, value] of Object.entries(this.props.Document[AclSym])) { - if (d.author === denormalizeEmail(key.substring(4)) && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true); - //else if (this.props.Document[key] === SharingPermissions.Admin) distributeAcls(key, SharingPermissions.Add, d, true); - //else distributeAcls(key, this.AclMap.get(value) as SharingPermissions, d, true); - } - }); - } - - if (effectiveAcl === AclAddonly) { - added.map(doc => { - this.props.layerProvider?.(doc, true);// assigns layer values to the newly added document... testing the utility of this - Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc); - doc.context = this.props.Document; - }); - } - else { - added.filter(doc => [AclAdmin, AclEdit].includes(GetEffectiveAcl(doc))).map(doc => { // only make a pushpin if we have acl's to edit the document - DocUtils.LeavePushpin(doc); - doc._stayInCollection = undefined; - doc.context = this.props.Document; - }); - added.map(doc => this.props.layerProvider?.(doc, true));// assigns layer values to the newly added document... testing the utility of this - (targetDataDoc[this.props.fieldKey] as List<Doc>).push(...added); - targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now())); - } - } - } - return true; - } - - @action.bound - removeDocument = (doc: any): boolean => { - const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]); - const indocs = doc instanceof Doc ? [doc] : doc as Doc[]; - const docs = indocs.filter(doc => effectiveAcl === AclEdit || effectiveAcl === AclAdmin || GetEffectiveAcl(doc) === AclAdmin); - if (docs.length) { - const targetDataDoc = this.props.Document[DataSym]; - const value = DocListCast(targetDataDoc[this.props.fieldKey]); - const toRemove = value.filter(v => docs.includes(v)); - if (toRemove.length !== 0) { - const recent = Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc) as Doc; - toRemove.forEach(doc => { - const ind = (targetDataDoc[this.props.fieldKey] as List<Doc>).indexOf(doc); - if (ind !== -1) { - Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc); - doc.context = undefined; - recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true); - } - }); - return true; - } - } - return false; - } - - // this is called with the document that was dragged and the collection to move it into. - // if the target collection is the same as this collection, then the move will be allowed. - // otherwise, the document being moved must be able to be removed from its container before - // moving it into the target. - @action.bound - moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => { - if (Doc.AreProtosEqual(this.props.Document, targetCollection)) { - return true; - } - const first = doc instanceof Doc ? doc : doc[0]; - if (!first?._stayInCollection && addDocument !== returnFalse) { - return UndoManager.RunInTempBatch(() => this.removeDocument(doc) && addDocument(doc)); - } - return false; - } - showIsTagged = () => { return (null); // this section would display an icon in the bototm right of a collection to indicate that all // photos had been processed through Google's content analysis API and Google's tags had been // assigned to the documents googlePhotosTags field. - // const children = DocListCast(this.props.Document[this.props.fieldKey]); + // const children = DocListCast(this.rootDoc[this.props.fieldKey]); // const imageProtos = children.filter(doc => Cast(doc.data, ImageField)).map(Doc.GetProto); // const allTagged = imageProtos.length > 0 && imageProtos.every(image => image.googlePhotosTags); // return !allTagged ? (null) : <img id={"google-tags"} src={"/assets/google_tags.png"} />; } + isContentActive = (outsideReaction?: boolean) => { + return this.props.isSelected(outsideReaction) || this._isAnyChildContentActive || this.props.renderDepth === 0 || this.props.rootSelected(outsideReaction) || + (this.props.layerProvider?.(this.rootDoc) !== false && (this.rootDoc.forceActive || this.rootDoc._isGroup)) + ? + true : false; + } + screenToLocalTransform = () => this.props.renderDepth ? this.props.ScreenToLocalTransform() : this.props.ScreenToLocalTransform().scale(this.props.PanelWidth() / this.bodyPanelWidth()); private SubView = (type: CollectionViewType, props: SubCollectionViewProps) => { TraceMobx(); @@ -252,7 +151,6 @@ export class CollectionView extends Touchable<CollectionViewProps> { } subItems.push({ description: "Schema", event: () => func(CollectionViewType.Schema), icon: "th-list" }); subItems.push({ description: "Tree", event: () => func(CollectionViewType.Tree), icon: "tree" }); - !Doc.UserDoc().noviceMode && subItems.push({ description: "Stacking", event: () => func(CollectionViewType.Stacking), icon: "ellipsis-v" }); subItems.push({ description: "Stacking", event: () => func(CollectionViewType.Stacking)._autoHeight = true, icon: "ellipsis-v" }); subItems.push({ description: "Multicolumn", event: () => func(CollectionViewType.Multicolumn), icon: "columns" }); subItems.push({ description: "Multirow", event: () => func(CollectionViewType.Multirow), icon: "columns" }); @@ -263,7 +161,7 @@ export class CollectionView extends Touchable<CollectionViewProps> { !Doc.UserDoc().noviceMode && subItems.push({ description: "Map", event: () => func(CollectionViewType.Map), icon: "globe-americas" }); subItems.push({ description: "Grid", event: () => func(CollectionViewType.Grid), icon: "th-list" }); - if (!Doc.IsSystem(this.props.Document) && !this.props.Document.annotationOn) { + if (!Doc.IsSystem(this.rootDoc) && !this.rootDoc.annotationOn) { const existingVm = ContextMenu.Instance.findByDescription(category); const catItems = existingVm && "subitems" in existingVm ? existingVm.subitems : []; catItems.push({ description: "Add a Perspective...", addDivider: true, noexpand: true, subitems: subItems, icon: "eye" }); @@ -273,9 +171,9 @@ export class CollectionView extends Touchable<CollectionViewProps> { onContextMenu = (e: React.MouseEvent): void => { const cm = ContextMenu.Instance; - if (cm && !e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 + if (cm && !e.isPropagationStopped() && this.rootDoc[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 this.setupViewTypes("UI Controls...", vtype => { - const newRendition = Doc.MakeAlias(this.props.Document); + const newRendition = Doc.MakeAlias(this.rootDoc); newRendition._viewType = vtype; this.props.addDocTab(newRendition, "add:right"); return newRendition; @@ -283,34 +181,34 @@ export class CollectionView extends Touchable<CollectionViewProps> { const options = cm.findByDescription("Options..."); const optionItems = options && "subitems" in options ? options.subitems : []; - !Doc.UserDoc().noviceMode ? optionItems.splice(0, 0, { description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }) : null; - if (this.props.Document.childLayout instanceof Doc) { - optionItems.push({ description: "View Child Layout", event: () => this.props.addDocTab(this.props.Document.childLayout as Doc, "add:right"), icon: "project-diagram" }); + !Doc.UserDoc().noviceMode ? optionItems.splice(0, 0, { description: `${this.rootDoc.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.rootDoc.forceActive = !this.rootDoc.forceActive, icon: "project-diagram" }) : null; + if (this.rootDoc.childLayout instanceof Doc) { + optionItems.push({ description: "View Child Layout", event: () => this.props.addDocTab(this.rootDoc.childLayout as Doc, "add:right"), icon: "project-diagram" }); } - if (this.props.Document.childClickedOpenTemplateView instanceof Doc) { - optionItems.push({ description: "View Child Detailed Layout", event: () => this.props.addDocTab(this.props.Document.childClickedOpenTemplateView as Doc, "add:right"), icon: "project-diagram" }); + if (this.rootDoc.childClickedOpenTemplateView instanceof Doc) { + optionItems.push({ description: "View Child Detailed Layout", event: () => this.props.addDocTab(this.rootDoc.childClickedOpenTemplateView as Doc, "add:right"), icon: "project-diagram" }); } - !Doc.UserDoc().noviceMode && optionItems.push({ description: `${this.props.Document.isInPlaceContainer ? "Unset" : "Set"} inPlace Container`, event: () => this.props.Document.isInPlaceContainer = !this.props.Document.isInPlaceContainer, icon: "project-diagram" }); + !Doc.UserDoc().noviceMode && optionItems.push({ description: `${this.rootDoc.isInPlaceContainer ? "Unset" : "Set"} inPlace Container`, event: () => this.rootDoc.isInPlaceContainer = !this.rootDoc.isInPlaceContainer, icon: "project-diagram" }); optionItems.push({ - description: "Create Branch", event: async () => this.props.addDocTab(await BranchCreate(this.props.Document), "add:right"), icon: "project-diagram" + description: "Create Branch", event: async () => this.props.addDocTab(await BranchCreate(this.rootDoc), "add:right"), icon: "project-diagram" }); optionItems.push({ - description: "Pull Master", event: () => BranchTask(this.props.Document, "pull"), icon: "project-diagram" + description: "Pull Master", event: () => BranchTask(this.rootDoc, "pull"), icon: "project-diagram" }); optionItems.push({ - description: "Merge Branches", event: () => BranchTask(this.props.Document, "merge"), icon: "project-diagram" + description: "Merge Branches", event: () => BranchTask(this.rootDoc, "merge"), icon: "project-diagram" }); !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "hand-point-right" }); - if (!Doc.UserDoc().noviceMode && !this.props.Document.annotationOn) { + if (!Doc.UserDoc().noviceMode && !this.rootDoc.annotationOn) { const existingOnClick = cm.findByDescription("OnClick..."); const onClicks = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; const funcs = [{ key: "onChildClick", name: "On Child Clicked" }, { key: "onChildDoubleClick", name: "On Child Double Clicked" }]; funcs.map(func => onClicks.push({ description: `Edit ${func.name} script`, icon: "edit", event: (obj: any) => { - const alias = Doc.MakeAlias(this.props.Document); + const alias = Doc.MakeAlias(this.rootDoc); DocUtils.makeCustomViewClicked(alias, undefined, func.key); this.props.addDocTab(alias, "add:right"); } @@ -319,15 +217,15 @@ export class CollectionView extends Touchable<CollectionViewProps> { onClicks.push({ description: `Set child ${childClick.title}`, icon: "edit", - event: () => Doc.GetProto(this.props.Document)[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data)), + event: () => Doc.GetProto(this.rootDoc)[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data)), })); - !Doc.IsSystem(this.props.Document) && !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "mouse-pointer" }); + !Doc.IsSystem(this.rootDoc) && !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "mouse-pointer" }); } if (!Doc.UserDoc().noviceMode) { const more = cm.findByDescription("More..."); const moreItems = more && "subitems" in more ? more.subitems : []; - moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) }); + moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.rootDoc) }); !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); } } @@ -335,28 +233,26 @@ export class CollectionView extends Touchable<CollectionViewProps> { bodyPanelWidth = () => this.props.PanelWidth(); - childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null); - @computed get childLayoutString() { return StrCast(this.props.Document.childLayoutString); } + childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.rootDoc.childLayoutTemplate, Doc, null); + @computed get childLayoutString() { return StrCast(this.rootDoc.childLayoutString); } render() { TraceMobx(); const props: SubCollectionViewProps = { ...this.props, addDocument: this.addDocument, - removeDocument: this.removeDocument, moveDocument: this.moveDocument, - active: this.active, - whenActiveChanged: this.whenActiveChanged, - parentActive: this.props.parentActive, + removeDocument: this.removeDocument, + isContentActive: this.isContentActive, PanelWidth: this.bodyPanelWidth, PanelHeight: this.props.PanelHeight, + ScreenToLocalTransform: this.screenToLocalTransform, childLayoutTemplate: this.childLayoutTemplate, childLayoutString: this.childLayoutString, - ScreenToLocalTransform: this.screenToLocalTransform, CollectionView: this, }; return (<div className={"collectionView"} onContextMenu={this.onContextMenu} - style={{ pointerEvents: this.props.layerProvider?.(this.props.Document) === false ? "none" : undefined }}> + style={{ pointerEvents: this.props.layerProvider?.(this.rootDoc) === false ? "none" : undefined }}> {this.showIsTagged()} {this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)} </div>); diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx index 4005c751e..c91942c05 100644 --- a/src/client/views/collections/SchemaTable.tsx +++ b/src/client/views/collections/SchemaTable.tsx @@ -586,8 +586,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> { ContainingCollectionDoc={this.props.CollectionView?.props.Document} ContainingCollectionView={this.props.CollectionView} moveDocument={this.props.moveDocument} - parentActive={this.props.active} - whenActiveChanged={emptyFunction} + whenChildContentsActiveChanged={emptyFunction} addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} bringToFront={returnFalse}> diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index f333c4077..c413208d2 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -309,6 +309,7 @@ export class TabDocView extends React.Component<TabDocViewProps> { DataDoc={!Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} + isContentActive={returnFalse} PanelWidth={this.PanelWidth} PanelHeight={this.PanelHeight} layerProvider={this.layerProvider} @@ -322,8 +323,7 @@ export class TabDocView extends React.Component<TabDocViewProps> { ScreenToLocalTransform={this.ScreenToLocalTransform} dontCenter={"y"} rootSelected={returnTrue} - parentActive={this.active} - whenActiveChanged={emptyFunction} + whenChildContentsActiveChanged={emptyFunction} focus={this.focusFunc} docViewPath={returnEmptyDoclist} bringToFront={emptyFunction} @@ -368,7 +368,7 @@ interface TabMinimapViewProps { } @observer export class TabMinimapView extends React.Component<TabMinimapViewProps> { - static miniStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string): any => { + static miniStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any => { if (doc) { switch (property.split(":")[0]) { default: return DefaultStyleProvider(doc, props, property); @@ -417,12 +417,11 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> { CollectionView={undefined} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} - parentActive={returnFalse} docViewPath={returnEmptyDoclist} childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this. noOverlay={true} // don't render overlay Docs since they won't scale setHeight={returnFalse} - active={returnTrue} + isContentActive={returnTrue} select={emptyFunction} dropAction={undefined} isSelected={returnFalse} @@ -437,7 +436,7 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> { PanelHeight={this.returnMiniSize} ScreenToLocalTransform={Transform.Identity} renderDepth={0} - whenActiveChanged={emptyFunction} + whenChildContentsActiveChanged={emptyFunction} focus={DocUtils.DefaultFocus} styleProvider={TabMinimapView.miniStyleProvider} layerProvider={undefined} diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 0d7ccc4bd..9fba03e17 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -67,7 +67,7 @@ export interface TreeViewProps { onChildClick?: () => ScriptField; skipFields?: string[]; firstLevel: boolean; - whenActiveChanged: (isActive: boolean) => void; + whenChildContentsActiveChanged: (isActive: boolean) => void; parentTreeView: TreeView | CollectionTreeView | undefined; } @@ -331,7 +331,7 @@ export class TreeView extends React.Component<TreeViewProps> { this.props.treeView, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.titleStyleProvider, this.props.layerProvider, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, - [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView, this); + [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged, this.props.dontRegisterView, this); } else { contentElement = <EditableView key="editableView" contents={contents !== undefined ? Field.toString(contents as Field) : "null"} @@ -414,7 +414,7 @@ export class TreeView extends React.Component<TreeViewProps> { this.dataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.props.pinToPres, this.titleStyleProvider, this.props.layerProvider, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, - [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView, this)} + [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged, this.props.dontRegisterView, this)} </ul >; } else if (this.treeViewExpandedView === "fields") { return <ul key={this.doc[Id] + this.doc.title}> @@ -511,7 +511,7 @@ export class TreeView extends React.Component<TreeViewProps> { e.preventDefault(); } } - titleStyleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps | FieldViewProps>, property: string): any => { + titleStyleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps>, property: string): any => { if (!doc || doc !== this.doc) return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView switch (property.split(":")[0]) { @@ -527,7 +527,7 @@ export class TreeView extends React.Component<TreeViewProps> { case StyleProp.Decorations: return (null); } } - embeddedStyleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps | FieldViewProps>, property: string): any => { + embeddedStyleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps>, property: string): any => { if (property.startsWith(StyleProp.Decorations)) return (null); return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView } @@ -603,9 +603,10 @@ export class TreeView extends React.Component<TreeViewProps> { PanelHeight={() => 18} contextMenuItems={this.contextMenuItems} renderDepth={1} + isContentActive={returnTrue} + isDocumentActive={returnTrue} focus={returnTrue} - parentActive={returnTrue} - whenActiveChanged={this.props.whenActiveChanged} + whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} bringToFront={emptyFunction} cantBrush={this.props.treeView.props.cantBrush} dontRegisterView={BoolCast(this.props.treeView.props.Document.childDontRegisterViews)} @@ -676,6 +677,8 @@ export class TreeView extends React.Component<TreeViewProps> { ScreenToLocalTransform={this.docTransform} renderDepth={this.props.renderDepth + 1} rootSelected={returnTrue} + isContentActive={asText ? returnTrue : returnFalse} + isDocumentActive={asText ? returnTrue : returnFalse} styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider} layerProvider={this.props.layerProvider} docViewPath={this.props.treeView.props.docViewPath} @@ -687,8 +690,7 @@ export class TreeView extends React.Component<TreeViewProps> { addDocument={this.props.addDocument} moveDocument={this.move} removeDocument={this.props.removeDoc} - parentActive={this.props.active} - whenActiveChanged={this.props.whenActiveChanged} + whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} cantBrush={this.props.treeView.props.cantBrush} @@ -794,7 +796,7 @@ export class TreeView extends React.Component<TreeViewProps> { onChildClick: undefined | (() => ScriptField), skipFields: string[] | undefined, firstLevel: boolean, - whenActiveChanged: (isActive: boolean) => void, + whenChildContentsActiveChanged: (isActive: boolean) => void, dontRegisterView: boolean | undefined, parentTreeView: CollectionTreeView | TreeView | undefined ) { @@ -862,7 +864,7 @@ export class TreeView extends React.Component<TreeViewProps> { renderedIds={renderedIds} skipFields={skipFields} firstLevel={firstLevel} - whenActiveChanged={whenActiveChanged} + whenChildContentsActiveChanged={whenChildContentsActiveChanged} parentTreeView={parentTreeView} />; }); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index f0d99611a..950fc4a25 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -67,7 +67,6 @@ export const panZoomSchema = createSchema({ type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof collectionSchema, typeof documentSchema, typeof pageSchema]>; const PanZoomDocument = makeInterface(panZoomSchema, collectionSchema, documentSchema, pageSchema); export type collectionFreeformViewProps = { - parentActive: (outsideReaction: boolean) => boolean; annotationLayerHostsContent?: boolean; // whether to force scaling of content (needed by ImageBox) viewDefDivClick?: ScriptField; childPointerEvents?: boolean; @@ -117,7 +116,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P @computed get views() { return this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z).map(ele => ele.ele); } @computed get backgroundEvents() { return this.props.layerProvider?.(this.layoutDoc) === false && SnappingManager.GetIsDragging(); } - @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && (this.props.ContainingCollectionView?.active() || this.props.active()); } + @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && (this.props.ContainingCollectionView?.isContentActive() || this.props.isContentActive()); } @computed get fitToContentVals() { return { bounds: { ...this.contentBounds, cx: (this.contentBounds.x + this.contentBounds.r) / 2, cy: (this.contentBounds.y + this.contentBounds.b) / 2 }, @@ -152,7 +151,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P getKeyFrameEditing = () => this._keyframeEditing; onChildClickHandler = () => this.props.childClickScript || ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); - parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.props.parentActive?.(outsideReaction) || this.backgroundActive || this.layoutDoc._viewType === CollectionViewType.Pile ? true : false; elementFunc = () => this._layoutElements; shrinkWrap = () => { const vals = this.fitToContentVals; @@ -422,7 +420,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P } } - getClusterColor = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string) => { + getClusterColor = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => { let styleProp = this.props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1 if (property !== StyleProp.BackgroundColor) return styleProp; const cluster = NumCast(doc?.cluster); @@ -459,7 +457,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P return; } this._hitCluster = this.pickCluster(this.getTransform().transformPoint(e.clientX, e.clientY)); - if (e.button === 0 && !e.altKey && !e.ctrlKey && this.props.active(true)) { + if (e.button === 0 && !e.altKey && !e.ctrlKey && this.props.isContentActive(true)) { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointermove", this.onPointerMove); @@ -484,7 +482,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P const pt = me.changedTouches[0]; if (pt) { this._hitCluster = this.pickCluster(this.getTransform().transformPoint(pt.clientX, pt.clientY)); - if (!e.shiftKey && !e.altKey && !e.ctrlKey && this.props.active(true)) { + if (!e.shiftKey && !e.altKey && !e.ctrlKey && this.props.isContentActive(true)) { this.removeMoveListeners(); this.addMoveListeners(); this.removeEndListeners(); @@ -647,7 +645,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P if (this.props.Document._isGroup) return; // groups don't pan when dragged -- instead let the event go through to allow the group itself to drag if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) return; if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) { - if (this.props.active(true)) e.stopPropagation(); + if (this.props.isContentActive(true)) e.stopPropagation(); } else if (!e.cancelBubble) { if (CurrentUserUtils.SelectedTool === InkTool.None) { if (this.tryDragCluster(e, this._hitCluster)) { @@ -735,7 +733,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P @action handle2PointersDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>) => { - if (!e.nativeEvent.cancelBubble && this.props.active(true)) { + if (!e.nativeEvent.cancelBubble && this.props.isContentActive(true)) { // const pt1: React.Touch | null = e.targetTouches.item(0); // const pt2: React.Touch | null = e.targetTouches.item(1); // // if (!pt1 || !pt2) return; @@ -819,7 +817,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming e.stopPropagation(); } - else if (this.props.active(true) && !this.Document._isGroup) { + else if (this.props.isContentActive(true) && !this.Document._isGroup) { e.stopPropagation(); e.preventDefault(); this.zoom(e.clientX, e.clientY, e.deltaY); // if (!this.props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc? @@ -1007,6 +1005,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P }; } + isContentActive = () => this.props.isSelected() || this.props.isContentActive(); + getChildDocView(entry: PoolData) { const childLayout = entry.pair.layout; const childData = entry.pair.data; @@ -1030,14 +1030,15 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P docFilters={this.freeformDocFilters} docRangeFilters={this.freeformRangeDocFilters} searchFilterDocs={this.searchFilterDocs} + isContentActive={this.isAnnotationOverlay ? this.props.isContentActive : returnFalse} + isDocumentActive={this.isContentActive} focus={this.focusDocument} addDocTab={this.addDocTab} addDocument={this.props.addDocument} removeDocument={this.props.removeDocument} moveDocument={this.props.moveDocument} pinToPres={this.props.pinToPres} - whenActiveChanged={this.props.whenActiveChanged} - parentActive={this.parentActive} + whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} docViewPath={this.props.docViewPath} styleProvider={this.getClusterColor} layerProvider={this.props.layerProvider} @@ -1488,7 +1489,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P width: `${100 / (this.contentScaling || 1)}%`, height: this.isAnnotationOverlay && this.Document.scrollHeight ? this.Document.scrollHeight : `${100 / (this.contentScaling || 1)}%`// : this.isAnnotationOverlay ? (this.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}> - {this.Document._freeformLOD && !this.props.active() && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 ? + {this.Document._freeformLOD && !this.props.isContentActive() && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 ? this.placeholder : this.marqueeView} {this.props.noOverlay ? (null) : <CollectionFreeFormOverlayView elements={this.elementFunc} />} diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index af391a078..d7a0d3f34 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -167,7 +167,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque } else if (!e.ctrlKey && !e.metaKey && SelectionManager.Views().length < 2) { FormattedTextBox.SelectOnLoadChar = Doc.UserDoc().defaultTextLayout && !this.props.childLayoutString ? e.key : ""; FormattedTextBox.LiveTextUndo = UndoManager.StartBatch("live text batch"); - this.props.addLiveTextDocument(CurrentUserUtils.GetNewTextDoc("-typed text-", x, y, 200, 100, this.props.xMargin === 0, this.props.isAnnotationOverlay ? this.props.Document : undefined)); + this.props.addLiveTextDocument(CurrentUserUtils.GetNewTextDoc("-typed text-", x, y, 200, 100, this.props.xMargin === 0)); e.stopPropagation(); } } diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index e2feff5ed..b0030471d 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -171,7 +171,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { ScreenToLocalTransform={dxf} onClick={this.onChildClickHandler} renderDepth={this.props.renderDepth + 1} - parentActive={this.props.active} dontCenter={"y"} />; } @@ -296,7 +295,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { * Handles text document creation on double click. */ onPointerDown = (e: React.PointerEvent) => { - if (this.props.active(true)) { + if (this.props.isContentActive(true)) { setupMoveUpEvents(this, e, returnFalse, returnFalse, (e: PointerEvent, doubleTap?: boolean) => { if (doubleTap) { @@ -316,7 +315,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { render() { return ( <div className="collectionGridView-contents" ref={this.createDashEventsTarget} - style={{ pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined }} + style={{ pointerEvents: !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined }} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onDrop={this.onExternalDrop} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 0c0dbef9f..8b5c02b75 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -223,6 +223,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu LayoutTemplateString={this.props.childLayoutString} freezeDimensions={this.props.childFreezeDimensions} renderDepth={this.props.renderDepth + 1} + isContentActive={returnFalse} PanelWidth={width} PanelHeight={height} rootSelected={this.rootSelected} @@ -239,8 +240,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu addDocument={this.props.addDocument} moveDocument={this.props.moveDocument} removeDocument={this.props.removeDocument} - parentActive={this.props.active} - whenActiveChanged={this.props.whenActiveChanged} + whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} addDocTab={this.addDocTab} pinToPres={this.props.pinToPres} bringToFront={returnFalse} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 0a1000a20..2c5e40d02 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -232,6 +232,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) ScreenToLocalTransform={dxf} focus={this.props.focus} docFilters={this.docFilters} + isContentActive={returnFalse} docRangeFilters={this.docRangeFilters} searchFilterDocs={this.searchFilterDocs} ContainingCollectionDoc={this.props.CollectionView?.props.Document} @@ -239,8 +240,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) addDocument={this.props.addDocument} moveDocument={this.props.moveDocument} removeDocument={this.props.removeDocument} - parentActive={this.props.active} - whenActiveChanged={this.props.whenActiveChanged} + whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} addDocTab={this.addDocTab} pinToPres={this.props.pinToPres} bringToFront={returnFalse} |
