aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.tsx2
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx7
-rw-r--r--src/client/views/collections/CollectionSubView.tsx1
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx4
-rw-r--r--src/client/views/collections/CollectionView.tsx4
-rw-r--r--src/client/views/collections/TabDocView.tsx8
-rw-r--r--src/client/views/collections/TreeView.tsx99
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx55
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx2
9 files changed, 94 insertions, 88 deletions
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 6035871cd..fbf7db892 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -54,7 +54,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
const needsUnsetCategory = this.childDocs.some(d => !d[this.notetakingCategoryField] && !columnHeaders?.find(sh => sh.heading === 'unset'));
if (needsUnsetCategory || columnHeaders === undefined || columnHeaders.length === 0) {
setTimeout(() => {
- const columnHeaders = Array.from(Cast(this.dataDoc.columnHeaders, listSpec(SchemaHeaderField), null));
+ const columnHeaders = Array.from(Cast(this.dataDoc.columnHeaders, listSpec(SchemaHeaderField), null) ?? []);
const needsUnsetCategory = this.childDocs.some(d => !d[this.notetakingCategoryField] && !columnHeaders?.find(sh => sh.heading === 'unset'));
if (needsUnsetCategory || columnHeaders.length === 0) {
columnHeaders.push(new SchemaHeaderField('unset', undefined, undefined, 1));
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 572fbfec2..5bdff347c 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -2,7 +2,7 @@ import React = require('react');
import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
-import { Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc';
+import { Doc, Opt, StrListCast } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
@@ -15,6 +15,7 @@ import { DocumentType } from '../../documents/DocumentTypes';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager } from '../../util/DragManager';
import { LinkFollower } from '../../util/LinkFollower';
+import { LinkManager } from '../../util/LinkManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SelectionManager } from '../../util/SelectionManager';
import { SnappingManager } from '../../util/SnappingManager';
@@ -740,14 +741,14 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
() => this.props.currentTimecode(),
time => {
const dictationDoc = Cast(this.props.layoutDoc['data-dictation'], Doc, null);
- const isDictation = dictationDoc && DocListCast(this.props.mark.links).some(link => Cast(link.anchor1, Doc, null)?.annotationOn === dictationDoc);
+ const isDictation = dictationDoc && LinkManager.Links(this.props.mark).some(link => Cast(link.anchor1, Doc, null)?.annotationOn === dictationDoc);
if (
!LightboxView.LightboxDoc &&
// bcz: when should links be followed? we don't want to move away from the video to follow a link but we can open it in a sidebar/etc. But we don't know that upfront.
// for now, we won't follow any links when the lightbox is oepn to avoid "losing" the video.
/*(isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc))*/
!this.props.layoutDoc.dontAutoFollowLinks &&
- DocListCast(this.props.mark.links).length &&
+ LinkManager.Links(this.props.mark).length &&
time > NumCast(this.props.mark[this.props.startTag]) &&
time < NumCast(this.props.mark[this.props.endTag]) &&
this._lastTimecode < NumCast(this.props.mark[this.props.startTag]) - 1e-5
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index c88ae314e..e46220f02 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -1,5 +1,4 @@
import { action, computed, observable } from 'mobx';
-import ReactLoading from 'react-loading';
import * as rp from 'request-promise';
import CursorField from '../../../fields/CursorField';
import { AclPrivate, Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc';
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 330e116d1..553967b95 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -38,8 +38,8 @@ export type collectionTreeViewProps = {
onCheckedClick?: () => ScriptField;
onChildClick?: () => ScriptField;
// TODO: [AL] add these fields
- AddToMap?: (treeViewDoc: Doc, index: number[]) => Doc[];
- RemFromMap?: (treeViewDoc: Doc, index: number[]) => Doc[];
+ AddToMap?: (treeViewDoc: Doc, index: number[]) => void;
+ RemFromMap?: (treeViewDoc: Doc, index: number[]) => void;
hierarchyIndex?: number[];
};
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 316f1e4e9..48e5748a0 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -64,8 +64,8 @@ interface CollectionViewProps_ extends FieldViewProps {
childClickScript?: ScriptField;
childDoubleClickScript?: ScriptField;
//TODO: [AL] add these fields
- AddToMap?: (treeViewDoc: Doc, index: number[]) => Doc[];
- RemFromMap?: (treeViewDoc: Doc, index: number[]) => Doc[];
+ AddToMap?: (treeViewDoc: Doc, index: number[]) => void;
+ RemFromMap?: (treeViewDoc: Doc, index: number[]) => void;
hierarchyIndex?: number[]; // hierarchical index of a document up to the rendering root (primarily used for tree views)
}
export interface CollectionViewProps extends React.PropsWithChildren<CollectionViewProps_> {}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 99283996e..9459aaf1e 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -263,9 +263,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
pinDoc.treeViewFieldKey = 'data'; // tree view will treat the 'data' field as the field where the hierarchical children are located instead of using the document's layout string field
pinDoc.treeViewExpandedView = 'data'; // in case the data doc has an expandedView set, this will mask that field and use the 'data' field when expanding the tree view
pinDoc.treeViewHideHeaderIfTemplate = true; // this will force the document to render itself as the tree view header
- const presArray: Doc[] = PresBox.Instance?.sortArray();
- const size: number = PresBox.Instance?.selectedArray.size;
- const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined;
const duration = NumCast(doc[`${Doc.LayoutFieldKey(pinDoc)}-duration`], null);
if (!pinProps?.audioRange && duration !== undefined) {
@@ -274,10 +271,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
pinDoc.presStartTime = NumCast(doc.clipStart);
pinDoc.presEndTime = NumCast(doc.clipEnd, duration);
}
- //PresBox.pinDocView(pinDoc, pinProps.pinDocContent ? { ...pinProps, pinData: PresBox.pinDataTypes(doc) } : pinProps, anchorDoc && anchorDoc !== doc && !anchorDoc.unrendered ? anchorDoc : doc);
- pinDoc.onClick = ScriptField.MakeFunction('navigateToDoc(self.presentationTargetDoc, self)');
- Doc.AddDocToList(curPres, 'data', pinDoc, presSelected);
- //save position
if (pinProps?.activeFrame !== undefined) {
pinDoc.presActiveFrame = pinProps?.activeFrame;
pinDoc.title = doc.title + ' (move)';
@@ -294,6 +287,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
pinDoc.presMovement = PresMovement.None;
}
if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
+ Doc.AddDocToList(curPres, 'data', pinDoc, PresBox.Instance?.sortArray()?.lastElement());
PresBox.Instance?.clearSelectedArray();
pinDoc && PresBox.Instance?.addToSelectedArray(pinDoc); //Update selected array
});
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 0d2968ba1..2bdcf472f 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -1,6 +1,6 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { DataSym, Doc, DocListCast, DocListCastOrNull, Field, HeightSym, Opt, StrListCast, WidthSym } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
@@ -8,13 +8,14 @@ import { List } from '../../../fields/List';
import { RichTextField } from '../../../fields/RichTextField';
import { listSpec } from '../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, simulateMouseClick, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager, dropActionType } from '../../util/DragManager';
+import { LinkManager } from '../../util/LinkManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SelectionManager } from '../../util/SelectionManager';
import { SnappingManager } from '../../util/SnappingManager';
@@ -32,7 +33,6 @@ import { CollectionTreeView, TreeViewType } from './CollectionTreeView';
import { CollectionView } from './CollectionView';
import './TreeView.scss';
import React = require('react');
-import { render } from 'react-dom';
export interface TreeViewProps {
treeView: CollectionTreeView;
@@ -66,8 +66,8 @@ export interface TreeViewProps {
skipFields?: string[];
firstLevel: boolean;
// TODO: [AL] add these
- AddToMap?: (treeViewDoc: Doc, index: number[]) => Doc[];
- RemFromMap?: (treeViewDoc: Doc, index: number[]) => Doc[];
+ AddToMap?: (treeViewDoc: Doc, index: number[]) => void;
+ RemFromMap?: (treeViewDoc: Doc, index: number[]) => void;
hierarchyIndex?: number[];
}
@@ -169,23 +169,6 @@ export class TreeView extends React.Component<TreeViewProps> {
@computed get selected() {
return SelectionManager.IsSelected(this._docRef);
}
- // SelectionManager.Views().lastElement()?.props.Document === this.props.document; }
-
- @observable _presTimer!: NodeJS.Timeout;
- @observable _presKeyEventsActive: boolean = false;
-
- @observable _selectedArray: ObservableMap = new ObservableMap<Doc, any>();
- // the selected item's index
- @computed get itemIndex() {
- return NumCast(this.doc._itemIndex);
- }
- // the item that's active
- @computed get activeItem() {
- return this.childDocs ? Cast(this.childDocs[NumCast(this.doc._itemIndex)], Doc, null) : undefined;
- }
- @computed get targetDoc() {
- return Cast(this.activeItem?.presentationTargetDoc, Doc, null);
- }
childDocList(field: string) {
const layout = Cast(Doc.LayoutField(this.doc), Doc, null);
@@ -195,11 +178,17 @@ export class TreeView extends React.Component<TreeViewProps> {
DocListCastOrNull(this.doc[field])
); // otherwise use the document's data field
}
+ moving: boolean = false;
@undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
if (this.doc !== target && addDoc !== returnFalse) {
+ const canAdd1 = (this.props.parentTreeView as any).dropping || !(ComputedField.WithoutComputed(() => FieldValue(this.props.parentTreeView?.doc.data)) instanceof ComputedField);
+
// bcz: this should all be running in a Temp undo batch instead of hackily testing for returnFalse
- if (this.props.removeDoc?.(doc) === true) {
- return addDoc(doc);
+ if (canAdd1 && this.props.removeDoc?.(doc) === true) {
+ this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.moving = true);
+ const res = addDoc(doc);
+ this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.moving = false);
+ return res;
}
}
return false;
@@ -207,6 +196,7 @@ export class TreeView extends React.Component<TreeViewProps> {
@undoBatch @action remove = (doc: Doc | Doc[], key: string) => {
this.props.treeView.props.select(false);
const ind = this.dataDoc[key].indexOf(doc);
+
const res = (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && Doc.RemoveDocFromList(this.dataDoc, key, doc), true);
res && ind > 0 && DocumentManager.Instance.getDocumentView(this.dataDoc[key][ind - 1], this.props.treeView.props.CollectionView)?.select(false);
return res;
@@ -378,20 +368,32 @@ export class TreeView extends React.Component<TreeViewProps> {
const docDragData = de.complete.docDragData;
if (docDragData && pt[0] < rect.left + rect.width) {
if (docDragData.draggedDocuments[0] === this.doc) return true;
- if (this.dropDocuments(docDragData.droppedDocuments, before, inside, docDragData.dropAction, docDragData.moveDocument, docDragData.treeViewDoc === this.props.treeView.props.Document)) {
+ if (this.dropDocuments(docDragData.droppedDocuments, before, inside, docDragData.dropAction, docDragData.removeDocument, docDragData.moveDocument, docDragData.treeViewDoc === this.props.treeView.props.Document)) {
e.stopPropagation();
}
}
};
- dropDocuments(droppedDocuments: Doc[], before: boolean, inside: number | boolean, dropAction: dropActionType, moveDocument: DragManager.MoveFunction | undefined, forceAdd: boolean) {
+ dropping: boolean = false;
+ dropDocuments(droppedDocuments: Doc[], before: boolean, inside: number | boolean, dropAction: dropActionType, removeDocument: DragManager.RemoveFunction | undefined, moveDocument: DragManager.MoveFunction | undefined, forceAdd: boolean) {
const parentAddDoc = (doc: Doc | Doc[]) => this.props.addDocument(doc, undefined, before);
- const canAdd = (!this.props.treeView.outlineMode && !StrCast((inside ? this.props.document : this.props.containerCollection)?.freezeChildren).includes('add')) || forceAdd;
- const localAdd = (doc: Doc) => (Doc.AddDocToList(this.dataDoc, this.fieldKey, doc) && ((doc.context = this.doc.context) || true) ? true : false);
- const addDoc = !inside ? parentAddDoc : (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc), true as boolean);
+ const localAdd = (doc: Doc | Doc[]) => {
+ const innerAdd = (doc: Doc) => {
+ const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[this.fieldKey])) instanceof ComputedField;
+ const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, this.fieldKey, doc);
+ dataIsComputed && (doc.context = this.doc.context);
+ return added;
+ };
+ return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && innerAdd(doc), true as boolean);
+ };
+ const addDoc = inside ? localAdd : parentAddDoc;
const move = (!dropAction || dropAction === 'proto' || dropAction === 'move' || dropAction === 'same') && moveDocument;
+ const canAdd = (!this.props.treeView.outlineMode && !StrCast((inside ? this.props.document : this.props.containerCollection)?.freezeChildren).includes('add')) || forceAdd;
if (canAdd) {
- return UndoManager.RunInTempBatch(() => droppedDocuments.reduce((added, d) => (move ? move(d, undefined, addDoc) || (dropAction === 'proto' ? addDoc(d) : false) : addDoc(d)) || added, false));
+ this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.dropping = true);
+ const res = UndoManager.RunInTempBatch(() => droppedDocuments.reduce((added, d) => (move ? move(d, undefined, addDoc) || (dropAction === 'proto' ? addDoc(d) : false) : addDoc(d)) || added, false));
+ this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.dropping = false);
+ return res;
}
return false;
}
@@ -437,12 +439,16 @@ export class TreeView extends React.Component<TreeViewProps> {
const expandedWidth = () => this.props.panelWidth() - leftOffset.width;
if (contents instanceof Doc || (Cast(contents, listSpec(Doc)) && Cast(contents, listSpec(Doc))!.length && Cast(contents, listSpec(Doc))![0] instanceof Doc)) {
const remDoc = (doc: Doc | Doc[]) => this.remove(doc, key);
- const localAdd = (doc: Doc, addBefore?: Doc, before?: boolean) => {
- const added = Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
- added && (doc.context = this.doc.context);
- return added;
+ const moveDoc = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.move(doc, target, addDoc);
+ const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => {
+ const innerAdd = (doc: Doc) => {
+ const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[key])) instanceof ComputedField;
+ const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
+ dataIsComputed && (doc.context = this.doc.context);
+ return added;
+ };
+ return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && innerAdd(doc), true as boolean);
};
- const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc, addBefore, before), true);
contentElement = TreeView.GetChildElements(
contents instanceof Doc ? [contents] : DocListCast(contents),
this.props.treeView,
@@ -453,7 +459,7 @@ export class TreeView extends React.Component<TreeViewProps> {
this.props.prevSibling,
addDoc,
remDoc,
- this.move,
+ moveDoc,
this.props.dropAction,
this.props.addDocTab,
this.titleStyleProvider,
@@ -533,6 +539,7 @@ export class TreeView extends React.Component<TreeViewProps> {
);
const key = (expandKey === 'annotations' ? `${this.fieldKey}-` : '') + expandKey;
const remDoc = (doc: Doc | Doc[]) => this.remove(doc, key);
+ const moveDoc = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.move(doc, target, addDoc);
const localAdd = (doc: Doc, addBefore?: Doc, before?: boolean) => {
// if there's a sort ordering specified that can be modified on drop (eg, zorder can be modified, alphabetical can't),
// then the modification would be done here
@@ -543,8 +550,10 @@ export class TreeView extends React.Component<TreeViewProps> {
docs.push(doc);
docs.sort((a, b) => (NumCast(a.zIndex) > NumCast(b.zIndex) ? 1 : -1)).forEach((d, i) => (d.zIndex = i));
}
- const added = Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
- added && (doc.context = this.doc.context);
+ const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[key])) instanceof ComputedField;
+ const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
+ !dataIsComputed && added && (doc.context = this.doc.context);
+
return added;
};
const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc, addBefore, before), true);
@@ -593,7 +602,7 @@ export class TreeView extends React.Component<TreeViewProps> {
this.props.prevSibling,
addDoc,
remDoc,
- this.move,
+ moveDoc,
StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType,
this.props.addDocTab,
this.titleStyleProvider,
@@ -700,7 +709,7 @@ export class TreeView extends React.Component<TreeViewProps> {
@computed get validExpandViewTypes() {
const annos = () => (DocListCast(this.doc[this.fieldKey + '-annotations']).length && !this.props.treeView.dashboardMode ? 'annotations' : '');
- const links = () => (DocListCast(this.doc.links).length && !this.props.treeView.dashboardMode ? 'links' : '');
+ const links = () => (LinkManager.Links(this.doc).length && !this.props.treeView.dashboardMode ? 'links' : '');
const data = () => (this.childDocs || this.props.treeView.dashboardMode ? this.fieldKey : '');
const aliases = () => (this.props.treeView.dashboardMode ? '' : 'aliases');
const fields = () => (Doc.noviceMode ? '' : 'fields');
@@ -1028,7 +1037,9 @@ export class TreeView extends React.Component<TreeViewProps> {
// renders the text version of a document as the header. This is used in the file system mode and in other vanilla tree views.
@computed get renderTitleAsHeader() {
- return (
+ return this.props.treeView.Document.treeViewHideUnrendered && this.doc.unrendered && !this.doc.treeViewFieldKey ? (
+ <div></div>
+ ) : (
<>
{this.renderBullet}
{this.renderTitle}
@@ -1062,7 +1073,7 @@ export class TreeView extends React.Component<TreeViewProps> {
const before = pt[1] < rect.top + rect.height / 2;
const inside = this.props.treeView.fileSysMode && !this.doc.isFolder ? false : pt[0] > Math.min(rect.left + 75, rect.left + rect.width * 0.75) || (!before && this.treeViewOpen && this.childDocs?.length ? true : false);
- const docs = this.props.treeView.onTreeDrop(de, (docs: Doc[]) => this.dropDocuments(docs, before, inside, 'copy', undefined, false));
+ const docs = this.props.treeView.onTreeDrop(de, (docs: Doc[]) => this.dropDocuments(docs, before, inside, 'copy', undefined, undefined, false));
};
render() {
@@ -1146,8 +1157,8 @@ export class TreeView extends React.Component<TreeViewProps> {
unobserveHeight: (ref: any) => void,
contextMenuItems: { script: ScriptField; filter: ScriptField; label: string; icon: string }[],
// TODO: [AL] add these
- AddToMap?: (treeViewDoc: Doc, index: number[]) => Doc[],
- RemFromMap?: (treeViewDoc: Doc, index: number[]) => Doc[],
+ AddToMap?: (treeViewDoc: Doc, index: number[]) => void,
+ RemFromMap?: (treeViewDoc: Doc, index: number[]) => void,
hierarchyIndex?: number[],
renderCount?: number
) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 63b566f28..15d8144fc 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -74,7 +74,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@observable
public static ShowPresPaths = false;
- private _lastNudge: any;
+ private _panZoomTransitionTimer: any;
private _lastX: number = 0;
private _lastY: number = 0;
private _downX: number = 0;
@@ -94,9 +94,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
private _brushtimer: any;
private _brushtimer1: any;
- // private isWritingMode: boolean = true;
- // private writingModeDocs: Doc[] = [];
-
private get isAnnotationOverlay() {
return this.props.isAnnotationOverlay;
}
@@ -111,7 +108,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@observable _panZoomTransition: number = 0; // sets the pan/zoom transform ease time- used by nudge(), focus() etc to smoothly zoom/pan. set to 0 to use document's transition time or default of 0
@observable _hLines: number[] | undefined;
@observable _vLines: number[] | undefined;
- @observable _firstRender = true; // this turns off rendering of the collection's content so that there's instant feedback when a tab is switched of what content will be shown.
+ @observable _firstRender = false; // this turns off rendering of the collection's content so that there's instant feedback when a tab is switched of what content will be shown. could be used for performance improvement
@observable _showAnimTimeline = false;
@observable _clusterSets: Doc[][] = [];
@observable _deleteList: DocumentView[] = [];
@@ -139,7 +136,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
}
@computed get fitContentsToBox() {
- return (this.props.fitContentsToBox?.() || this.Document._fitContentsToBox || this.Document.isGroup) && !this.isAnnotationOverlay;
+ return (this.props.fitContentsToBox?.() || this.Document._fitContentsToBox) && !this.isAnnotationOverlay;
}
@computed get contentBounds() {
const cb = Cast(this.rootDoc.contentBounds, listSpec('number'));
@@ -181,8 +178,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return this.getContainerTransform().translate(-this.cachedCenteringShiftX, -this.cachedCenteringShiftY).transform(this.cachedGetLocalTransform);
}
- _keyTimer: NodeJS.Timeout | undefined;
-
public static gotoKeyframe(timer: NodeJS.Timeout | undefined, docs: Doc[], duration: number) {
if (timer) clearTimeout(timer);
return DocumentView.SetViewTransition(docs, 'all', duration, undefined, true);
@@ -208,6 +203,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return newTimer;
}
+ _keyTimer: NodeJS.Timeout | undefined; // timer for turning off transition flag when key frame change has completed. Need to clear this if you do a second navigation before first finishes, or else first timer can go off during second naviation.
changeKeyFrame = (back = false) => {
const currentFrame = Cast(this.Document._currentFrame, 'number', null);
if (currentFrame === undefined) {
@@ -520,7 +516,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._clusterSets.push([doc]);
} else if (this._clusterSets.length) {
for (let i = this._clusterSets.length; i <= doc.cluster; i++) !this._clusterSets[i] && this._clusterSets.push([]);
- this._clusterSets[doc.cluster].push(doc);
+ this._clusterSets[doc.cluster ?? 0].push(doc);
}
}
}
@@ -583,14 +579,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
!InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) &&
!InteractionUtils.IsType(e, InteractionUtils.PENTYPE)
) {
+ // prettier-ignore
switch (Doc.ActiveTool) {
- case InkTool.Highlighter:
- break;
- // TODO: nda - this where we want to create the new "writingDoc" collection that we add strokes to
- case InkTool.Write:
- break;
- case InkTool.Pen:
- break; // the GestureOverlay handles ink stroke input -- either as gestures, or drying as ink strokes that are added to document views
+ case InkTool.Highlighter: break;
+ case InkTool.Write: break;
+ case InkTool.Pen: break; // the GestureOverlay handles ink stroke input -- either as gestures, or drying as ink strokes that are added to document views
case InkTool.Eraser:
this._batch = UndoManager.StartBatch('collectionErase');
setupMoveUpEvents(this, e, this.onEraserMove, this.onEraserUp, emptyFunction);
@@ -1142,7 +1135,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
}
if (!this.layoutDoc._lockedTransform || LightboxView.LightboxDoc || DocListCast(Doc.MyOverlayDocs?.data).includes(this.Document)) {
- this._panZoomTransition = panTime;
+ this.setPanZoomTransition(panTime);
const scale = this.getLocalTransform().inverse().Scale;
const minScale = NumCast(this.rootDoc._viewScaleMin, 1);
const minPanX = NumCast(this.rootDoc._panXMin, 0);
@@ -1176,12 +1169,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@action
nudge = (x: number, y: number, nudgeTime: number = 500) => {
if (this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform || this.props.ContainingCollectionDoc._panX !== undefined) {
- // bcz: this isn't ideal, but want to try it out...
- this.setPan(NumCast(this.layoutDoc._panX) + ((this.props.PanelWidth() / 2) * x) / this.zoomScaling(), NumCast(this.layoutDoc._panY) + ((this.props.PanelHeight() / 2) * -y) / this.zoomScaling(), nudgeTime, true);
- this._lastNudge && clearTimeout(this._lastNudge);
- this._lastNudge = setTimeout(
- action(() => (this._panZoomTransition = 0)),
- nudgeTime
+ this.setPan(
+ NumCast(this.layoutDoc._panX) + ((this.props.PanelWidth() / 2) * x) / this.zoomScaling(), // nudge x,y as a function of panel dimension and scale
+ NumCast(this.layoutDoc._panY) + ((this.props.PanelHeight() / 2) * -y) / this.zoomScaling(),
+ nudgeTime,
+ true
);
return true;
}
@@ -1207,9 +1199,19 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
@action
+ setPanZoomTransition = (transitionTime: number) => {
+ this._panZoomTransition = transitionTime;
+ this._panZoomTransitionTimer && clearTimeout(this._panZoomTransitionTimer);
+ this._panZoomTransitionTimer = setTimeout(
+ action(() => (this._panZoomTransition = 0)),
+ transitionTime
+ );
+ };
+
+ @action
zoomSmoothlyAboutPt(docpt: number[], scale: number, transitionTime = 500) {
if (this.Document._isGroup) return;
- this._panZoomTransition = transitionTime;
+ this.setPanZoomTransition(transitionTime);
const screenXY = this.getTransform().inverse().transformPoint(docpt[0], docpt[1]);
this.layoutDoc[this.scaleFieldKey] = scale;
const newScreenXY = this.getTransform().inverse().transformPoint(docpt[0], docpt[1]);
@@ -1217,7 +1219,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const newpan = this.getTransform().transformDirection(scrDelta.x, scrDelta.y);
this.layoutDoc._panX = NumCast(this.layoutDoc._panX) - newpan[0];
this.layoutDoc._panY = NumCast(this.layoutDoc._panY) - newpan[1];
- return new Promise<number>(res => setTimeout(() => res(runInAction(() => (this._panZoomTransition = 0))), this._panZoomTransition)); // set transition to be smooth, then reset
}
calculatePanIntoView = (doc: Doc, xf: Transform, scale?: number) => {
@@ -1553,7 +1554,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
// create an anchor that saves information about the current state of the freeform view (pan, zoom, view type)
const anchor = Docs.Create.CollectionAnchorDocument({ title: 'ViewSpec - ' + StrCast(this.layoutDoc._viewType), unrendered: true, presTransition: 500, annotationOn: this.rootDoc });
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), pannable: true, viewType: true, filters: true } }, this.rootDoc);
+ PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), pannable: !this.Document._isGroup, viewType: true, filters: true } }, this.rootDoc);
if (addAsAnnotation) {
if (Cast(this.dataDoc[this.props.fieldKey + '-annotations'], listSpec(Doc), null) !== undefined) {
@@ -1574,7 +1575,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._firstRender = false;
this._disposers.groupBounds = reaction(
() => {
- if (this.props.Document._isGroup && this.childDocs.length === this.childDocList?.length) {
+ if (this.Document._isGroup && this.childDocs.length === this.childDocList?.length) {
const clist = this.childDocs.map(cd => ({ x: NumCast(cd.x), y: NumCast(cd.y), width: cd[WidthSym](), height: cd[HeightSym]() }));
return aggregateBounds(clist, NumCast(this.layoutDoc._xPadding), NumCast(this.layoutDoc._yPadding));
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index a73627165..0714bffbc 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -396,7 +396,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
newCollection.forceActive = makeGroup;
newCollection.x = this.Bounds.left;
newCollection.y = this.Bounds.top;
- newCollection.fitwidth = true;
+ newCollection.fitWidth = true;
selected.forEach(d => (d.context = newCollection));
this.hideMarquee();
return newCollection;