aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-11-02 19:30:19 -0400
committerbobzel <zzzman@gmail.com>2023-11-02 19:30:19 -0400
commiteec81f7e0b53395e3e2ea25663a9ea06ec83085d (patch)
treebb10e997cf9d5d0719049723de5728279bf67b0d /src/client/views/collections/collectionFreeForm
parent1bba63b1d15cfe76393424a768d2dbc0f0b8cffb (diff)
performance fixes - don't invalidate as much by using reactions in place of computd values; don't make things active when things are dragged unless CanEmbed; fix for linkBox to use reaction.
Diffstat (limited to 'src/client/views/collections/collectionFreeForm')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx107
1 files changed, 66 insertions, 41 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d80ea2cb2..2897cac0e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1280,12 +1280,20 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
@computed get childPointerEvents() {
const engine = this.props.layoutEngine?.() || StrCast(this.props.Document._layoutEngine);
- const pointerEvents = DocumentView.Interacting
+ const pointerevents = DocumentView.Interacting
? 'none'
- : this.props.childPointerEvents?.() ?? (this.props.viewDefDivClick || (engine === computePassLayout.name && !this.props.isSelected(true)) || this.isContentActive() === false ? 'none' : this.props.pointerEvents?.());
- return pointerEvents;
+ : this.props.childPointerEvents?.() ??
+ (this.props.viewDefDivClick || //
+ (engine === computePassLayout.name && !this.props.isSelected(true)) ||
+ this.isContentActive() === false
+ ? 'none'
+ : this.props.pointerEvents?.());
+ console.log(`${this.rootDoc.title} pe = ` + pointerevents);
+ return pointerevents;
}
- childPointerEventsFunc = () => this.childPointerEvents;
+
+ @observable _childPointerEvents: 'none' | 'all' | 'visiblepainted' | undefined;
+ childPointerEventsFunc = () => this._childPointerEvents;
childContentsActive = () => (this.props.childContentsActive ?? this.isContentActive() === false ? returnFalse : emptyFunction)();
getChildDocView(entry: PoolData) {
const childLayout = entry.pair.layout;
@@ -1372,9 +1380,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
});
@observable _lightboxDoc: Opt<Doc>;
- getCalculatedPositions(params: { pair: { layout: Doc; data?: Doc }; index: number; collection: Doc }): PoolData {
+ getCalculatedPositions(pair: { layout: Doc; data?: Doc }): PoolData {
const random = (min: number, max: number, x: number, y: number) => /* min should not be equal to max */ min + (((Math.abs(x * y) * 9301 + 49297) % 233280) / 233280) * (max - min);
- const childDoc = params.pair.layout;
+ const childDoc = pair.layout;
const childDocLayout = Doc.Layout(childDoc);
const layoutFrameNumber = Cast(this.Document._currentFrame, 'number'); // frame number that container is at which determines layout frame values
const contentFrameNumber = Cast(childDocLayout._currentFrame, 'number', layoutFrameNumber ?? null); // frame number that content is at which determines what content is displayed
@@ -1400,7 +1408,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
width: _width,
height: _height,
transition: StrCast(childDocLayout.dataTransition),
- pair: params.pair,
+ pair,
pointerEvents: Cast(childDoc.pointerEvents, 'string', null),
replica: '',
};
@@ -1480,7 +1488,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
doFreeformLayout(poolData: Map<string, PoolData>) {
- this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => poolData.set(pair.layout[Id], this.getCalculatedPositions({ pair, index: i, collection: this.Document })));
+ this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => poolData.set(pair.layout[Id], this.getCalculatedPositions(pair)));
return [] as ViewDefResult[];
}
@@ -1502,38 +1510,39 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@observable _numLoaded = 1;
_lastPoolSize = 0;
- get doLayoutComputation() {
- const { newPool, computedElementData } = this.doInternalLayoutComputation;
+ @action
+ doLayoutComputation = (newPool: Map<string, PoolData>, computedElementData: ViewDefResult[]) => {
const array = Array.from(newPool.entries());
- let somethingChanged = array.length !== this._lastPoolSize;
this._lastPoolSize = array.length;
- runInAction(() => {
- for (const entry of array) {
- const lastPos = this._cachedPool.get(entry[0]); // last computed pos
- const newPos = entry[1];
- if (
- !lastPos ||
- newPos.color !== lastPos.color ||
- newPos.backgroundColor !== lastPos.backgroundColor ||
- newPos.opacity !== lastPos.opacity ||
- newPos.x !== lastPos.x ||
- newPos.y !== lastPos.y ||
- newPos.z !== lastPos.z ||
- newPos.rotation !== lastPos.rotation ||
- newPos.zIndex !== lastPos.zIndex ||
- newPos.transition !== lastPos.transition ||
- newPos.pointerEvents !== lastPos.pointerEvents
- ) {
- this._layoutPoolData.set(entry[0], newPos);
- somethingChanged = true;
- }
- if (!lastPos || newPos.height !== lastPos.height || newPos.width !== lastPos.width) {
- this._layoutSizeData.set(entry[0], { width: newPos.width, height: newPos.height });
- somethingChanged = true;
- }
+ for (const entry of array) {
+ const lastPos = this._cachedPool.get(entry[0]); // last computed pos
+ const newPos = entry[1];
+ if (
+ !lastPos ||
+ newPos.color !== lastPos.color ||
+ newPos.backgroundColor !== lastPos.backgroundColor ||
+ newPos.opacity !== lastPos.opacity ||
+ newPos.x !== lastPos.x ||
+ newPos.y !== lastPos.y ||
+ newPos.z !== lastPos.z ||
+ newPos.rotation !== lastPos.rotation ||
+ newPos.zIndex !== lastPos.zIndex ||
+ newPos.transition !== lastPos.transition ||
+ newPos.pointerEvents !== lastPos.pointerEvents
+ ) {
+ this._layoutPoolData.set(entry[0], newPos);
}
- });
- if (!somethingChanged) return undefined;
+ if (!lastPos || newPos.height !== lastPos.height || newPos.width !== lastPos.width) {
+ this._layoutSizeData.set(entry[0], { width: newPos.width, height: newPos.height });
+ }
+ }
+ // by returning undefined, we prevent an edit being made to layoutElements when nothing has happened
+ // this short circuit, prevents lots of downstream mobx invalidations which would have no effect but cause
+ // a distinct lag at the start of dragging.
+ // The reason we're here in the first place without a change is that when dragging a document,
+ // filters are changed on the annotation layers (eg. WebBox) which invalidate the childDoc list
+ // for the overlay views -- however, in many cases, this filter change doesn't actually affect anything
+ // (e.g, no annotations, or only opaque annotations).
this._cachedPool.clear();
Array.from(newPool.entries()).forEach(k => this._cachedPool.set(k[0], k[1]));
const elements = computedElementData.slice();
@@ -1551,7 +1560,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this.Document._freeform_useClusters && !this._clusterSets.length && this.childDocs.length && this.updateClusters(true);
return elements;
- }
+ };
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
// create an anchor that saves information about the current state of the freeform view (pan, zoom, view type)
@@ -1605,10 +1614,26 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
{ fireImmediately: true }
);
+ this._disposers.pointerevents = reaction(
+ () => {
+ const engine = this.props.layoutEngine?.() || StrCast(this.props.Document._layoutEngine);
+ return DocumentView.Interacting
+ ? 'none'
+ : this.props.childPointerEvents?.() ??
+ (this.props.viewDefDivClick || //
+ (engine === computePassLayout.name && !this.props.isSelected(true)) ||
+ this.isContentActive() === false
+ ? 'none'
+ : this.props.pointerEvents?.());
+ },
+ pointerevents => (this._childPointerEvents = pointerevents as any),
+ { fireImmediately: true }
+ );
+
this._disposers.layoutComputation = reaction(
- () => this.doLayoutComputation,
- elements => elements !== undefined && (this._layoutElements = elements || []),
- { fireImmediately: true, name: 'doLayout' }
+ () => this.doInternalLayoutComputation,
+ ({ newPool, computedElementData }) => (this._layoutElements = this.doLayoutComputation(newPool, computedElementData)),
+ { fireImmediately: true, name: 'layoutComputationReaction' }
);
this._disposers.active = reaction(