aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx23
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx7
-rw-r--r--src/client/views/nodes/PresBox.tsx12
-rw-r--r--src/client/views/presentationview/PresElementBox.tsx43
-rw-r--r--src/fields/Doc.ts2
-rw-r--r--src/fields/List.ts2
-rw-r--r--src/fields/util.ts2
-rw-r--r--src/server/websocket.ts3
9 files changed, 42 insertions, 54 deletions
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 3607b97d0..fc4ca3100 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -292,25 +292,14 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
if (super.onInternalDrop(e, de)) {
const newDocs = de.complete.docDragData.droppedDocuments;
const docs = this.childDocList;
+ DragManager.docsBeingDragged = [];
if (docs) {
newDocs.map((doc, i) => {
- if (i === 0) {
- if (doc.presentationTargetDoc) doc.dragging = false; //glr: so it only applies to items in presentation
- DragManager.docsBeingDragged = [];
- if (targInd === -1) targInd = docs.length;
- else targInd = docs.indexOf(this.filteredChildren[targInd]);
- const srcInd = docs.indexOf(doc);
- docs.splice(srcInd, 1);
- docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc);
- } else if (i < (newDocs.length / 2)) { //glr: for some reason dragged documents are duplicated
- if (doc.presentationTargetDoc) doc.dragging = false;
- DragManager.docsBeingDragged = [];
- if (targInd === -1) targInd = docs.length;
- else targInd = docs.indexOf(newDocs[0]) + 1;
- const srcInd = docs.indexOf(doc);
- docs.splice(srcInd, 1);
- docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc);
- }
+ targInd = targInd === -1 ? docs.length : targInd;
+ const srcInd = docs.indexOf(doc);
+ if (targInd !== -1) targInd = i === 0 ? docs.indexOf(this.filteredChildren[targInd]) : docs.indexOf(newDocs[0]) + 1;
+ docs.splice(srcInd, 1);
+ docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc);
});
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 8b9e84bd6..2d770898b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -922,6 +922,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
} else {
const layoutdoc = Doc.Layout(doc);
+ const savedState = { px: this.Document._panX, py: this.Document._panY, s: this.Document[this.scaleFieldKey], pt: this.Document._viewTransition };
willZoom && this.setScaleToZoom(layoutdoc, scale);
const newPanX = (NumCast(doc.x) + doc[WidthSym]() / 2) - (this.isAnnotationOverlay ? (NumCast(this.props.Document._nativeWidth)) / 2 / this.zoomScaling() : 0);
@@ -930,7 +931,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
newState.initializers![this.Document[Id]] = { panX: newPanX, panY: newPanY };
HistoryUtil.pushState(newState);
- const savedState = { px: this.Document._panX, py: this.Document._panY, s: this.Document[this.scaleFieldKey], pt: this.Document._viewTransition };
if (DocListCast(this.dataDoc[this.props.annotationsKey || this.props.fieldKey]).includes(doc)) {
// glr: freeform transform speed can be set by adjusting presTransition field - needs a way of knowing when presentation is not active...
if (!doc.z) this.setPan(newPanX, newPanY, doc.focusSpeed || doc.focusSpeed === 0 ? `transform ${doc.focusSpeed}ms` : "transform 500ms", true); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 369b53aa0..e980322d5 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -819,14 +819,15 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
zorderItems.push({ description: this.rootDoc._raiseWhenDragged !== false ? "Keep ZIndex when dragged" : "Allow ZIndex to change when dragged", event: this.toggleRaiseWhenDragged, icon: "expand-arrows-alt" });
!zorders && cm.addItem({ description: "ZOrder...", subitems: zorderItems, icon: "compass" });
+ onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" });
+ onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "concierge-bell" });
+
if (!this.Document.annotationOn) {
const options = cm.findByDescription("Options...");
const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
!this.props.treeViewDoc && this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Freeform && optionItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
!options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" });
- onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" });
- onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "concierge-bell" });
onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" });
onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: () => this.toggleFollowLink("inPlace", true, false), icon: "link" });
!this.Document.isLinkButton && onClicks.push({ description: "Follow Link on Right", event: () => this.toggleFollowLink("add:right", false, false), icon: "link" });
@@ -838,8 +839,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
onClicks.push({ description: "Select on Click", event: () => this.selectOnClick(), icon: "link" });
onClicks.push({ description: "Follow Link on Click", event: () => this.followLinkOnClick(undefined, false), icon: "link" });
onClicks.push({ description: "Toggle Link Target on Click", event: () => this.toggleTargetOnClick(), icon: "map-pin" });
- !existingOnClick && cm.addItem({ description: "OnClick...", addDivider: true, subitems: onClicks, icon: "mouse-pointer" });
}
+ !existingOnClick && cm.addItem({ description: "OnClick...", addDivider: true, subitems: onClicks, icon: "mouse-pointer" });
}
const funcs: ContextMenuProps[] = [];
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 8e2884968..352328ec6 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -599,13 +599,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
*/
@action
sortArray = (): Doc[] => {
- const sort: Doc[] = this._selectedArray;
- this.childDocs.forEach((doc, i) => {
- if (this._selectedArray.includes(doc)) {
- sort.push(doc);
- }
- });
- return sort;
+ return this.childDocs.filter(doc => this._selectedArray.includes(doc));
}
/**
@@ -1731,8 +1725,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const frameItems = frameList.map((value) => {
<div className="frameItem">
- </div>
- })
+ </div>;
+ });
return <div>
{frameItems}
</div>;
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 9052967e5..1d6721bca 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -1,5 +1,5 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, IReactionDisposer, reaction, runInAction } from "mobx";
+import { action, computed, IReactionDisposer, reaction, runInAction, observable } from "mobx";
import { observer } from "mobx-react";
import { Doc, DataSym, DocListCast } from "../../../fields/Doc";
import { documentSchema } from '../../../fields/documentSchemas';
@@ -8,13 +8,11 @@ import { createSchema, makeInterface, listSpec } from '../../../fields/Schema';
import { Cast, NumCast, BoolCast, ScriptCast, StrCast } from "../../../fields/Types";
import { emptyFunction, emptyPath, returnFalse, returnTrue, returnOne, returnZero, numberRange, setupMoveUpEvents } from "../../../Utils";
import { Transform } from "../../util/Transform";
-import { CollectionViewType } from '../collections/CollectionView';
import { ViewBoxBaseComponent } from '../DocComponent';
import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView';
import { FieldView, FieldViewProps } from '../nodes/FieldView';
import "./PresElementBox.scss";
import React = require("react");
-import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
import { PresBox, PresMovement } from "../nodes/PresBox";
import { DocumentType } from "../../documents/DocumentTypes";
import { Tooltip } from "@material-ui/core";
@@ -45,6 +43,8 @@ const PresDocument = makeInterface(presSchema, documentSchema);
export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDocument>(PresDocument) {
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); }
_heightDisposer: IReactionDisposer | undefined;
+
+ @observable _dragging = false;
// these fields are conditionally computed fields on the layout document that take this document as a parameter
@computed get indexInPres() { return Number(this.lookupField("indexInPres")); } // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements)
@computed get collapsedHeight() { return Number(this.lookupField("presCollapsedHeight")); } // the collapsed height changes depending on the state of the presBox. We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up
@@ -159,9 +159,9 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
e.preventDefault();
}
+ @action
stopDrag = (e: PointerEvent) => {
- const activeItem = this.rootDoc;
- activeItem.dragging = false;
+ this._dragging = false;
e.stopPropagation();
e.preventDefault();
}
@@ -172,12 +172,12 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
const dragItem: HTMLElement[] = [];
PresBox.Instance._dragArray.map(ele => {
const doc = ele;
- doc.className = "presItem-slide"
+ doc.className = "presItem-slide";
dragItem.push(doc);
});
if (activeItem) {
DragManager.StartDocumentDrag(dragItem.map(ele => ele), dragData, e.clientX, e.clientY);
- activeItem.dragging = true;
+ runInAction(() => this._dragging = true);
return true;
}
return false;
@@ -189,18 +189,20 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
}
onPointerMove = (e: PointerEvent) => {
- const slide = this._itemRef.current!;
- const rect = slide?.getBoundingClientRect();
- let y = e.clientY - rect.top; //y position within the element.
- let height = slide.clientHeight;
- let halfLine = height / 2;
- if (DragManager.docsBeingDragged.length > 1) {
- if (y <= halfLine) {
- slide.style.borderTop = "solid 2px #5B9FDD";
- slide.style.borderBottom = "0px";
- } else if (y > halfLine) {
- slide.style.borderTop = "0px";
- slide.style.borderBottom = "solid 2px #5B9FDD";
+ const slide = this._itemRef.current;
+ if (slide) {
+ const rect = slide.getBoundingClientRect();
+ const y = e.clientY - rect.top; //y position within the element.
+ const height = slide.clientHeight;
+ const halfLine = height / 2;
+ if (DragManager.docsBeingDragged.length) {
+ if (y <= halfLine) {
+ slide.style.borderTop = "solid 2px #5B9FDD";
+ slide.style.borderBottom = "0px";
+ } else if (y > halfLine) {
+ slide.style.borderTop = "0px";
+ slide.style.borderBottom = "solid 2px #5B9FDD";
+ }
}
}
document.removeEventListener("pointermove", this.onPointerMove);
@@ -244,7 +246,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
@computed get mainItem() {
const isSelected: boolean = PresBox.Instance._selectedArray.includes(this.rootDoc);
- const isDragging: boolean = BoolCast(this.rootDoc.dragging);
const toolbarWidth: number = PresBox.Instance.toolbarWidth;
const showMore: boolean = PresBox.Instance.toolbarWidth >= 300;
const targetDoc: Doc = Cast(this.rootDoc.presentationTargetDoc, Doc, null);
@@ -252,7 +253,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
return (
<div className={`presItem-container`} key={this.props.Document[Id] + this.indexInPres}
ref={this._itemRef}
- style={{ backgroundColor: isSelected ? "#AEDDF8" : "rgba(0,0,0,0)", opacity: isDragging ? 0.3 : 1 }}
+ style={{ backgroundColor: isSelected ? "#AEDDF8" : "rgba(0,0,0,0)", opacity: this._dragging ? 0.3 : 1 }}
onClick={e => {
e.stopPropagation();
e.preventDefault();
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index c8d28b4a2..4cf681482 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -399,7 +399,7 @@ export namespace Doc {
// and returns the document who's proto is undefined or whose proto is marked as a base prototype ('isPrototype').
export function GetProto(doc: Doc): Doc {
if (doc instanceof Promise) {
- console.log("GetProto: warning: got Promise insead of Doc");
+ // console.log("GetProto: warning: got Promise insead of Doc");
}
const proto = doc && (Doc.GetT(doc, "isPrototype", "boolean", true) ? doc : (doc.proto || doc));
return proto === doc ? proto : Doc.GetProto(proto);
diff --git a/src/fields/List.ts b/src/fields/List.ts
index a0cbebaf5..215dff34b 100644
--- a/src/fields/List.ts
+++ b/src/fields/List.ts
@@ -78,7 +78,7 @@ const listHandlers: any = {
}
const res = list.__fields.splice(start, deleteCount, ...items);
this[Update](items.length === 0 && deleteCount ? { op: "$remFromSet", items: removed, length: list.__fields.length } :
- items.length && !deleteCount ? { op: "$addToSet", items, length: list.__fields.length } : undefined);
+ items.length && !deleteCount && start === list.__fields.length ? { op: "$addToSet", items, length: list.__fields.length } : undefined);
return res.map(toRealField);
}),
unshift(...items: any[]) {
diff --git a/src/fields/util.ts b/src/fields/util.ts
index d48011194..15571ff8c 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -162,7 +162,7 @@ export function GetEffectiveAcl(target: any, user?: string): symbol {
}
function getPropAcl(target: any, prop: string | symbol | number) {
- if (prop === UpdatingFromServer || target[UpdatingFromServer] || prop == AclSym) return AclAdmin; // requesting the UpdatingFromServer prop or AclSym must always go through to keep the local DB consistent
+ if (prop === UpdatingFromServer || target[UpdatingFromServer] || prop === AclSym) return AclAdmin; // requesting the UpdatingFromServer prop or AclSym must always go through to keep the local DB consistent
if (prop && DocServer.PlaygroundFields?.includes(prop.toString())) return AclEdit; // playground props are always editable
return GetEffectiveAcl(target);
}
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index 1e02b9e58..e5692a7dd 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -313,6 +313,9 @@ export namespace WebSocket {
function UpdateField(socket: Socket, diff: Diff) {
if (diff.diff.$addToSet) return GetRefField([diff.id, (result?: Transferable) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
if (diff.diff.$remFromSet) return GetRefField([diff.id, (result?: Transferable) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
+ return GetRefField([diff.id, (result?: Transferable) => SetField(socket, diff, result)]);
+ }
+ function SetField(socket: Socket, diff: Diff, curListItems?: Transferable) {
Database.Instance.update(diff.id, diff.diff,
() => socket.broadcast.emit(MessageStore.UpdateField.Message, diff), false);
const docfield = diff.diff.$set || diff.diff.$unset;