From 5816840af60f97a34318a52a5276482cab392496 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 16 Oct 2020 15:48:54 -0400 Subject: updated user initialization code to not generate server traffic when creating a new account. set user accounts to update their cache 2.5s after login. --- src/client/util/CurrentUserUtils.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index dcbeba8cd..f43b6df44 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -878,7 +878,7 @@ export class CurrentUserUtils { // Sharing sidebar is where shared documents are contained static async setupSharingSidebar(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) { if (doc.myLinkDatabase === undefined) { - let linkDocs = await DocServer.GetRefField(linkDatabaseId); + let linkDocs = Docs.newAccount ? undefined : await DocServer.GetRefField(linkDatabaseId); if (!linkDocs) { linkDocs = new Doc(linkDatabaseId, true); (linkDocs as Doc).author = Doc.CurrentUserEmail; @@ -888,7 +888,7 @@ export class CurrentUserUtils { doc.myLinkDatabase = new PrefetchProxy(linkDocs); } if (doc.mySharedDocs === undefined) { - let sharedDocs = await DocServer.GetRefField(sharingDocumentId + "outer"); + let sharedDocs = Docs.newAccount ? undefined : await DocServer.GetRefField(sharingDocumentId + "outer"); if (!sharedDocs) { sharedDocs = Docs.Create.StackingDocument([], { title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, @@ -1024,6 +1024,7 @@ export class CurrentUserUtils { // Doc.AddDocToList(Cast(doc["template-notes"], Doc, null), "data", deleg); // } // }); + setTimeout(() => DocServer.UPDATE_SERVER_CACHE(), 2500); return doc; } @@ -1047,8 +1048,12 @@ export class CurrentUserUtils { await rp.get(Utils.prepend("/getUserDocumentIds")).then(ids => { const { userDocumentId, sharingDocumentId, linkDatabaseId } = JSON.parse(ids); if (userDocumentId !== "guest") { - return DocServer.GetRefField(userDocumentId).then(async field => - this.updateUserDocument(Doc.SetUserDoc(field instanceof Doc ? field : new Doc(userDocumentId, true)), sharingDocumentId, linkDatabaseId)); + return DocServer.GetRefField(userDocumentId).then(async field => { + Docs.newAccount = !(field instanceof Doc); + await Docs.Prototypes.initialize(); + const userDoc = Docs.newAccount ? new Doc(userDocumentId, true) : field as Doc; + return this.updateUserDocument(Doc.SetUserDoc(userDoc), sharingDocumentId, linkDatabaseId); + }); } else { throw new Error("There should be a user id! Why does Dash think there isn't one?"); } @@ -1108,7 +1113,7 @@ export class CurrentUserUtils { const response = await fetch(upload, { method: "POST", body: formData }); const json = await response.json(); if (json !== "error") { - const doc = await DocServer.GetRefField(json); + const doc = Docs.newAccount ? undefined : await DocServer.GetRefField(json); if (doc instanceof Doc) { setTimeout(() => SearchUtil.Search(`{!join from=id to=proto_i}id:link*`, true, {}).then(docs => docs.docs.forEach(d => LinkManager.Instance.addLink(d))), 2000); // need to give solr some time to update so that this query will find any link docs we've added. -- cgit v1.2.3-70-g09d2 From 56adc48fdd0e63b1c7768a88f2f46664397ffc23 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Sun, 18 Oct 2020 02:09:47 +0800 Subject: dragging has optional dropEvent argument + Changes presStatus -> enum --- src/client/util/DragManager.ts | 10 ++++- src/client/views/nodes/PresBox.tsx | 46 +++++++++++++--------- .../views/presentationview/PresElementBox.tsx | 25 +----------- 3 files changed, 39 insertions(+), 42 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 3a0f306f3..9e91b4f55 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -201,7 +201,14 @@ export namespace DragManager { } // drag a document and drop it (or make an alias/copy on drop) - export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) { + export function StartDocumentDrag( + eles: HTMLElement[], + dragData: DocumentDragData, + downX: number, + downY: number, + options?: DragOptions, + dropEvent?: () => any + ) { const addAudioTag = (dropDoc: any) => { dropDoc && !dropDoc.creationDate && (dropDoc.creationDate = new DateField); dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(dropDoc); @@ -209,6 +216,7 @@ export namespace DragManager { }; const finishDrag = (e: DragCompleteEvent) => { const docDragData = e.docDragData; + if (dropEvent) dropEvent(); // glr: optional additional function to be called - in this case with presentation trails if (docDragData && !docDragData.droppedDocuments.length) { docDragData.dropAction = dragData.userDropAction || dragData.dropAction; docDragData.droppedDocuments = diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index e5f0099a1..088d0020a 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -46,6 +46,12 @@ export enum PresEffect { None = "none", } +enum PresStatus { + Autoplay = "auto", + Manual = "manual", + Edit = "edit" +} + type PresBoxSchema = makeInterface<[typeof documentSchema]>; const PresBoxDocument = makeInterface(documentSchema); @@ -125,7 +131,7 @@ export class PresBox extends ViewBoxBaseComponent this.rootDoc.presBox = this.rootDoc; this.rootDoc._forceRenderEngine = "timeline"; this.rootDoc._replacedChrome = "replaced"; - this.layoutDoc.presStatus = "edit"; + this.layoutDoc.presStatus = PresStatus.Edit; this.layoutDoc._gridGap = 0; this.layoutDoc._yMargin = 0; this.turnOffEdit(true); @@ -164,7 +170,7 @@ export class PresBox extends ViewBoxBaseComponent else targetDoc.editing = true; // if (activeItem.zoomProgressivize) this.zoomProgressivizeNext(targetDoc); // Case 2: 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played - } else if ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && !activeItem.playAuto && activeItem.playNow && this.layoutDoc.presStatus !== 'auto') { + } else if ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && !activeItem.playAuto && activeItem.playNow && this.layoutDoc.presStatus !== PresStatus.Autoplay) { if (targetDoc.type === DocumentType.AUDIO) AudioBox.Instance.playFrom(NumCast(activeItem.presStartTime)); // if (targetDoc.type === DocumentType.VID) { VideoBox.Instance.Play() }; activeItem.playNow = false; @@ -286,7 +292,7 @@ export class PresBox extends ViewBoxBaseComponent collectionDocView ? collectionDocView.props.addDocTab(activeItem, "replace") : this.props.addDocTab(activeItem, "replace:left"); } else //docToJump stayed same meaning, it was not in the group or was the last element in the group - if (activeItem.zoomProgressivize && this.rootDoc.presStatus !== 'edit') { + if (activeItem.zoomProgressivize && this.rootDoc.presStatus !== PresStatus.Edit) { this.zoomProgressivizeNext(targetDoc); } else if (docToJump === curDoc) { //checking if curDoc has navigation open @@ -426,13 +432,13 @@ export class PresBox extends ViewBoxBaseComponent if (i === this.childDocs.length - 1) { setTimeout(() => { clearTimeout(this._presTimer); - if (this.layoutDoc.presStatus === 'auto' && !this.layoutDoc.presLoop) this.layoutDoc.presStatus = "manual"; + if (this.layoutDoc.presStatus === 'auto' && !this.layoutDoc.presLoop) this.layoutDoc.presStatus = PresStatus.Manual; else if (this.layoutDoc.presLoop) this.startAutoPres(0); }, duration); } } }; - this.layoutDoc.presStatus = "auto"; + this.layoutDoc.presStatus = PresStatus.Auto; this.startPresentation(startSlide); this.gotoDocument(startSlide, this.itemIndex); load(); @@ -440,9 +446,9 @@ export class PresBox extends ViewBoxBaseComponent @action pauseAutoPres = () => { - if (this.layoutDoc.presStatus === "auto") { + if (this.layoutDoc.presStatus === PresStatus.Auto) { if (this._presTimer) clearTimeout(this._presTimer); - this.layoutDoc.presStatus = "manual"; + this.layoutDoc.presStatus = PresStatus.Manual; this.layoutDoc.presLoop = false; } } @@ -499,12 +505,12 @@ export class PresBox extends ViewBoxBaseComponent updateMinimize = () => { const docView = DocumentManager.Instance.getDocumentView(this.layoutDoc); if (this.layoutDoc.inOverlay) { - this.layoutDoc.presStatus = 'edit'; + this.layoutDoc.presStatus = PresStatus.Edit; Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc); CollectionDockingView.AddSplit(this.rootDoc, "right"); this.layoutDoc.inOverlay = false; } else if (this.layoutDoc.context && docView) { - this.layoutDoc.presStatus = 'edit'; + this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); this.rootDoc.x = pt[0] + (this.props.PanelWidth() - 250); @@ -514,7 +520,7 @@ export class PresBox extends ViewBoxBaseComponent docView.props.removeDocument?.(this.layoutDoc); Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc); } else { - this.layoutDoc.presStatus = 'edit'; + this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); this.rootDoc.x = pt[0] + (this.props.PanelWidth() - 250); @@ -601,7 +607,7 @@ export class PresBox extends ViewBoxBaseComponent return true; } childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement; - @undoBatch removeDocument = (doc: Doc) => { Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); }; + removeDocument = (doc: Doc) => { return Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); }; getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight panelHeight = () => this.props.PanelHeight() - 40; active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc._isBackground) && @@ -670,7 +676,7 @@ export class PresBox extends ViewBoxBaseComponent // Key for when the presentaiton is active @undoBatch - keyEvents = action((e: KeyboardEvent) => { + keyEvents = action(async (e: KeyboardEvent) => { if (e.target instanceof HTMLInputElement) return; let handled = false; const anchorNode = document.activeElement as HTMLDivElement; @@ -695,15 +701,19 @@ export class PresBox extends ViewBoxBaseComponent if (this._presTimer) clearTimeout(this._presTimer); handled = true; } if (e.keyCode === 32) { // spacebar to 'present' or autoplay - if (this.layoutDoc.presStatus !== "edit") this.startAutoPres(0); - else this.next(); + if (this.layoutDoc.presStatus === "manual") this.startAutoPres(this.itemIndex); + else if (this.layoutDoc.presStatus === "auto") if (this._presTimer) clearTimeout(this._presTimer); handled = true; } if (e.keyCode === 8) { // delete selected items if (this.layoutDoc.presStatus === "edit") { - this._selectedArray.forEach((doc, i) => this.removeDocument(doc)); - this._selectedArray = []; - this._eleArray = []; - this._dragArray = []; + await Promise.all(this._selectedArray.map((doc, i): boolean => { + const removed: boolean = this.removeDocument(doc); + console.log("Is removed? : " + i + " | " + removed); + return removed; + })); + action(() => this._selectedArray = []); + action(() => this._eleArray = []); + action(() => this._dragArray = []); handled = true; } } if (handled) { diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 41a1b5a93..3c2761a2e 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -177,30 +177,9 @@ export class PresElementBox extends ViewBoxBaseComponent { - dropDoc && !dropDoc.creationDate && (dropDoc.creationDate = new DateField); - dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(dropDoc); - return dropDoc; - }; - const finishDrag = (e: DragManager.DragCompleteEvent) => { - const docDragData = e.docDragData; - activeItem.dragging = false; - if (docDragData && !docDragData.droppedDocuments.length) { - docDragData.dropAction = dragData.userDropAction || dragData.dropAction; - docDragData.droppedDocuments = - dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) : - docDragData.dropAction === "alias" ? Doc.MakeAlias(d) : - docDragData.dropAction === "copy" ? Doc.MakeClone(d) : d); - docDragData.dropAction !== "same" && docDragData.droppedDocuments.forEach((drop: Doc, i: number) => { - const dragProps = Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), []); - const remProps = (dragData?.removeDropProperties || []).concat(Array.from(dragProps)); - remProps.map(prop => drop[prop] = undefined); - }); - } - return e; - }; + const dropEvent = () => runInAction(() => this._dragging = false); if (activeItem) { - DragManager.StartDrag(dragItem.map(ele => ele), dragData, e.clientX, e.clientY, undefined, finishDrag); + DragManager.StartDocumentDrag(dragItem.map(ele => ele), dragData, e.clientX, e.clientY, undefined, dropEvent); runInAction(() => this._dragging = true); return true; } -- cgit v1.2.3-70-g09d2 From 2b0647b7281b1e48210a61967fdde56992b2ec75 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Sun, 18 Oct 2020 02:40:41 +0800 Subject: documents that are not in current collection open in new tab instead of on right --- src/client/util/DocumentManager.ts | 15 ++++++++++----- src/client/views/nodes/PresBox.tsx | 12 +++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index dc911ea75..2670de7a6 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -128,19 +128,24 @@ export class DocumentManager { } - static addRightSplit = (doc: Doc, finished?: () => void) => { - CollectionDockingView.AddSplit(doc, "right"); - finished?.(); + static addView = (doc: Doc, finished?: () => void, presCollection?: Doc) => { + if (presCollection) { + const collectionDocView = DocumentManager.Instance.getDocumentView(presCollection); + if (collectionDocView) collectionDocView.props.addDocTab(doc, "replace"); + } else { + CollectionDockingView.AddSplit(doc, "right"); + finished?.(); + } } public jumpToDocument = async ( targetDoc: Doc, // document to display willZoom: boolean, // whether to zoom doc to take up most of screen - createViewFunc = DocumentManager.addRightSplit, // how to create a view of the doc if it doesn't exist + createViewFunc = DocumentManager.addView, // how to create a view of the doc if it doesn't exist docContext?: Doc, // context to load that should contain the target linkDoc?: Doc, // link that's being followed closeContextIfNotFound: boolean = false, // after opening a context where the document should be, this determines whether the context should be closed if the Doc isn't actually there originatingDoc: Opt = undefined, // doc that initiated the display of the target odoc - finished?: () => void + finished?: () => void, ): Promise => { const getFirstDocView = DocumentManager.Instance.getFirstDocumentView; const focusAndFinish = () => { finished?.(); return false; }; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 088d0020a..43a3b2db4 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -270,7 +270,7 @@ export class PresBox extends ViewBoxBaseComponent const targetDoc: Doc = this.targetDoc; const srcContext = await DocCastAsync(targetDoc.context); const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); - const collectionDocView = presCollection ? await DocumentManager.Instance.getDocumentView(presCollection) : undefined; + const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined; this.turnOffEdit(); if (this.itemIndex >= 0) { if (srcContext && targetDoc) { @@ -286,10 +286,12 @@ export class PresBox extends ViewBoxBaseComponent this.updateCurrentPresentation(); const docToJump = curDoc; const willZoom = false; - + const openInTab = () => { + collectionDocView ? collectionDocView.props.addDocTab(activeItem, "replace") : this.props.addDocTab(activeItem, "replace:left"); + } // If openDocument is selected then it should open the document for the user if (activeItem.openDocument) { - collectionDocView ? collectionDocView.props.addDocTab(activeItem, "replace") : this.props.addDocTab(activeItem, "replace:left"); + openInTab(); } else //docToJump stayed same meaning, it was not in the group or was the last element in the group if (activeItem.zoomProgressivize && this.rootDoc.presStatus !== PresStatus.Edit) { @@ -297,10 +299,10 @@ export class PresBox extends ViewBoxBaseComponent } else if (docToJump === curDoc) { //checking if curDoc has navigation open if (curDoc.presMovement === PresMovement.Pan && targetDoc) { - await DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext); + await DocumentManager.Instance.jumpToDocument(targetDoc, false, () => { openInTab() }, srcContext); // documents open in new tab instead of on right } else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) { //awaiting jump so that new scale can be found, since jumping is async - await DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext); + await DocumentManager.Instance.jumpToDocument(targetDoc, true, () => { openInTab() }, srcContext); // documents open in new tab instead of on right } } else { //awaiting jump so that new scale can be found, since jumping is async -- cgit v1.2.3-70-g09d2 From 3a369686b42710db36506e7e880d8d7fafe1cece Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Oct 2020 22:18:30 -0400 Subject: fixed getFirstDocumenView() to choose a visible document view over the first one in its list which may be in a hidden tab. --- src/client/util/DocumentManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/util') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 2670de7a6..805e0e897 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -110,7 +110,7 @@ export class DocumentManager { public getFirstDocumentView = (toFind: Doc, originatingDoc: Opt = undefined): DocumentView | undefined => { const views = this.getDocumentViews(toFind).filter(view => view.props.Document !== originatingDoc); - return views?.find(view => view.props.focus !== returnFalse) || (views.length ? views[0] : undefined); + return views?.find(view => view.ContentDiv?.getBoundingClientRect().width && view.props.focus !== returnFalse) || views?.find(view => view.props.focus !== returnFalse) || (views.length ? views[0] : undefined); } public getDocumentViews(toFind: Doc): DocumentView[] { const toReturn: DocumentView[] = []; -- cgit v1.2.3-70-g09d2 From 6cfd2a37494bf531c88e26ea89b5b776805d31a8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Oct 2020 23:36:45 -0400 Subject: fixes for overlayDocs for undo/redo in presBox - undo/redo of minimize/show sidebar. --- src/client/util/CurrentUserUtils.ts | 1 + src/client/views/OverlayView.tsx | 9 ++------- .../collectionFreeForm/CollectionFreeFormView.tsx | 5 +++-- src/client/views/nodes/DocumentView.tsx | 8 ++++---- src/client/views/nodes/PresBox.tsx | 19 +++++++++---------- src/fields/documentSchemas.ts | 1 - 6 files changed, 19 insertions(+), 24 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index f43b6df44..38bfe3fb6 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1190,6 +1190,7 @@ export class CurrentUserUtils { public static get MyRecentlyClosed() { return Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc, null); } public static get MyDashboards() { return Cast(Doc.UserDoc().myDashboards, Doc, null); } public static get EmptyPane() { return Cast(Doc.UserDoc().emptyPane, Doc, null); } + public static get OverlayDocs() { return DocListCast((Doc.UserDoc().myOverlayDocs as Doc)?.data); } } Scripting.addGlobal(function openDragFactory(dragFactory: Doc) { diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index b40c9edfb..7d47abdce 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -14,6 +14,7 @@ import { Scripting } from "../util/Scripting"; import { ScriptingRepl } from './ScriptingRepl'; import { DragManager } from "../util/DragManager"; import { List } from "../../fields/List"; +import { CurrentUserUtils } from "../util/CurrentUserUtils"; export type OverlayDisposer = () => void; @@ -146,12 +147,7 @@ export class OverlayView extends React.Component { @computed get overlayDocs() { - const userDocOverlays = Doc.UserDoc().myOverlayDocs; - if (!userDocOverlays) { - return null; - } - return userDocOverlays instanceof Doc && DocListCast(userDocOverlays.data).map(d => { - setTimeout(() => d.inOverlay = true, 0); + return CurrentUserUtils.OverlayDocs?.map(d => { let offsetx = 0, offsety = 0; const dref = React.createRef(); const onPointerMove = action((e: PointerEvent, down: number[]) => { @@ -161,7 +157,6 @@ export class OverlayView extends React.Component { } if (e.metaKey) { const dragData = new DragManager.DocumentDragData([d]); - d.removeDropProperties = new List(["inOverlay"]); dragData.offset = [-offsetx, -offsety]; dragData.dropAction = "move"; dragData.removeDocument = (doc: Doc | Doc[]) => { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 56624f42d..fdcfb00d8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -46,6 +46,7 @@ import "./CollectionFreeFormView.scss"; import { MarqueeOptionsMenu } from "./MarqueeOptionsMenu"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); +import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; export const panZoomSchema = createSchema({ _panX: "number", @@ -803,7 +804,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (this.layoutDoc._lockedTransform || this.props.Document.inOverlay || this.props.Document.treeViewOutlineMode) return; + if (this.layoutDoc._lockedTransform || CurrentUserUtils.OverlayDocs.includes(this.props.Document) || this.props.Document.treeViewOutlineMode) return; if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming e.stopPropagation(); } @@ -839,7 +840,7 @@ export class CollectionFreeFormView extends CollectionSubView(Docu this._downX = touch.clientX; this._downY = touch.clientY; if (!e.nativeEvent.cancelBubble) { - if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) e.stopPropagation(); + if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) e.stopPropagation(); this.removeMoveListeners(); this.addMoveListeners(); this.removeEndListeners(); @@ -438,7 +438,7 @@ export class DocumentView extends DocComponent(Docu if (e.cancelBubble && this.active) { this.removeMoveListeners(); } - else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) { + else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { const touch = me.touchEvent.changedTouches.item(0); if (touch && (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3)) { @@ -554,7 +554,7 @@ export class DocumentView extends DocComponent(Docu if ((this.active || this.layoutDoc.onDragStart) && !e.ctrlKey && (e.button === 0 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) && - !this.layoutDoc.inOverlay) { + !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { e.stopPropagation(); if (SelectionManager.IsSelected(this, true) && this.layoutDoc._viewType !== CollectionViewType.Docking) e.preventDefault(); // goldenlayout needs to be able to move its tabs, so can't preventDefault for it } @@ -573,7 +573,7 @@ export class DocumentView extends DocComponent(Docu if (e.cancelBubble && this.active) { document.removeEventListener("pointermove", this.onPointerMove); // stop listening to pointerMove if something else has stopPropagated it (e.g., the MarqueeView) } - else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) { + else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) { document.removeEventListener("pointermove", this.onPointerMove); diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 53b2433e8..9723937a7 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -520,11 +520,10 @@ export class PresBox extends ViewBoxBaseComponent @action updateMinimize = () => { const docView = DocumentManager.Instance.getDocumentView(this.layoutDoc); - if (this.layoutDoc.inOverlay) { + if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { this.layoutDoc.presStatus = PresStatus.Edit; Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc); CollectionDockingView.AddSplit(this.rootDoc, "right"); - this.layoutDoc.inOverlay = false; } else if (this.layoutDoc.context && docView) { this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); @@ -716,7 +715,7 @@ export class PresBox extends ViewBoxBaseComponent const anchorNode = document.activeElement as HTMLDivElement; if (anchorNode && anchorNode.className?.includes("lm_title")) return; if (e.keyCode === 27) { // Escape key - if (this.layoutDoc.inOverlay) { this.updateMinimize(); } + if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { this.updateMinimize(); } else if (this.layoutDoc.presStatus === "edit") { this._selectedArray = []; this._eleArray = []; this._dragArray = []; } else this.layoutDoc.presStatus = "edit"; if (this._presTimer) clearTimeout(this._presTimer); @@ -1360,10 +1359,10 @@ export class PresBox extends ViewBoxBaseComponent @computed get presentDropdown() { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> -
{ this.updateMinimize(); this.turnOffEdit(true); }))}> +
{ this.updateMinimize(); this.turnOffEdit(true); })))}> Minimize
-
{ this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); }))}> +
{ this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); })))}> Sidebar view
@@ -1949,8 +1948,8 @@ export class PresBox extends ViewBoxBaseComponent {this.playButtonFrames}
- {this.props.PanelWidth() > 250 ?
{ this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }}>EXIT
- :
this.layoutDoc.presStatus = "edit"}> + {this.props.PanelWidth() > 250 ?
{ this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT
+ :
this.layoutDoc.presStatus = "edit"))}>
}
); @@ -1968,7 +1967,7 @@ export class PresBox extends ViewBoxBaseComponent // needed to ensure that the childDocs are loaded for looking up fields this.childDocs.slice(); const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; - return this.layoutDoc.inOverlay ? + return CurrentUserUtils.OverlayDocs.includes(this.rootDoc) ?
{"Loop"}
}>
this.layoutDoc.presLoop = !this.layoutDoc.presLoop}>
@@ -1982,11 +1981,11 @@ export class PresBox extends ViewBoxBaseComponent {this.playButtonFrames}
-
{ this.updateMinimize(); this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }}>EXIT
+
{ this.updateMinimize(); this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT
: -
+
{this.topPanel} {this.toolbar} {this.newDocumentToolbarDropdown} diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 71294c59c..311aaa769 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -19,7 +19,6 @@ export const documentSchema = createSchema({ activeFrame: "number", // the active frame of a frame based animated document _currentTimecode: "number", // current play back time of a temporal document (video / audio) displayTimecode: "number", // the time that a document should be displayed (e.g., time an annotation should be displayed on a video) - inOverlay: "boolean", // whether the document is rendered in an OverlayView which handles selection/dragging differently isLabel: "boolean", // whether the document is a label or not (video / audio) audioStart: "number", // the time frame where the audio should begin playing audioEnd: "number", // the time frame where the audio should stop playing -- cgit v1.2.3-70-g09d2 From 040d65234f52dc3337483acdb2c1c6d0cc8fefa2 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Oct 2020 13:30:01 -0400 Subject: added alert for uknown filetype uploads --- src/client/util/CurrentUserUtils.ts | 3 +++ src/client/views/collections/CollectionSubView.tsx | 2 ++ 2 files changed, 5 insertions(+) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 38bfe3fb6..07447b93c 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1124,6 +1124,9 @@ export class CurrentUserUtils { const disposer = OverlayView.ShowSpinner(); DocListCastAsync(importDocs.data).then(async list => { const results = await DocUtils.uploadFilesToDocs(Array.from(input.files || []), {}); + if (results.length !== input.files?.length) { + alert("Error uploading files - possibly due to unsupported file types") + } list?.splice(0, 0, ...results); disposer(); }); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 5c3c70be2..0dd033e47 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -482,6 +482,8 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: } else { if (text && !text.includes("https://")) { UndoManager.RunInBatch(() => this.addDocument(Docs.Create.TextDocument(text, { ...options, title: text.substring(0, 20), _width: 400, _height: 315 })), "drop"); + } else { + alert("Document updloaded failed - possibly an unsupported file type.") } } disposer(); -- cgit v1.2.3-70-g09d2 From 749873972fba8ed8d5b34b73b43947d6356b882e Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Oct 2020 22:23:39 -0400 Subject: added more caching for linkManager queries. --- src/client/util/CurrentUserUtils.ts | 4 +- src/client/util/LinkManager.ts | 106 ++++++--------------- src/client/views/collections/CollectionMenu.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 2 +- 5 files changed, 33 insertions(+), 83 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 07447b93c..5886aa13f 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1125,7 +1125,7 @@ export class CurrentUserUtils { DocListCastAsync(importDocs.data).then(async list => { const results = await DocUtils.uploadFilesToDocs(Array.from(input.files || []), {}); if (results.length !== input.files?.length) { - alert("Error uploading files - possibly due to unsupported file types") + alert("Error uploading files - possibly due to unsupported file types"); } list?.splice(0, 0, ...results); disposer(); @@ -1212,7 +1212,5 @@ Scripting.addGlobal(function createNewPresentation() { return MainView.Instance. "creates a new presentation when called"); Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); }, "returns all the links to the document or its annotations", "(doc: any)"); -Scripting.addGlobal(function directLinks(doc: any) { return new List(LinkManager.Instance.getAllDirectLinks(doc)); }, - "returns all the links directly to the document", "(doc: any)"); Scripting.addGlobal(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 1ba6cff6d..c3ab7c6e7 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -25,94 +25,52 @@ export class LinkManager { public static currentLink: Opt; - public static get Instance(): LinkManager { - return this._instance || (this._instance = new this()); - } - - private constructor() { - } - + public static get Instance(): LinkManager { return this._instance || (this._instance = new this()); } - public getAllLinks(): Doc[] { - const lset = new Set(DocListCast(Doc.LinkDBDoc().data)); - SharingManager.Instance.users.forEach(user => { - DocListCast(user.linkDatabase?.data).map(doc => { - lset.add(doc); - }); - }); - return Array.from(lset); - } + public addLink(linkDoc: Doc) { return Doc.AddDocToList(Doc.LinkDBDoc(), "data", linkDoc); } - public addLink(linkDoc: Doc): boolean { - return Doc.AddDocToList(Doc.LinkDBDoc(), "data", linkDoc); - } + public deleteLink(linkDoc: Doc) { return Doc.RemoveDocFromList(Doc.LinkDBDoc(), "data", linkDoc); } - public deleteLink(linkDoc: Doc): boolean { - return Doc.RemoveDocFromList(Doc.LinkDBDoc(), "data", linkDoc); - } + public deleteAllLinksOnAnchor(anchor: Doc) { LinkManager.Instance.getAllRelatedLinks(anchor).forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc)); } - // finds all links that contain the given anchor - public getAllDirectLinks(anchor: Doc): Doc[] { - const related = LinkManager.Instance.getAllLinks().filter(link => link).filter(link => { - const a1 = Cast(link.anchor1, Doc, null); - const a2 = Cast(link.anchor2, Doc, null); - const protomatch1 = Doc.AreProtosEqual(anchor, a1); - const protomatch2 = Doc.AreProtosEqual(anchor, a2); - return ((a1?.author !== undefined && a2?.author !== undefined) || link.author === Doc.CurrentUserEmail) && (protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor)); - }); - return related; - } + public getAllRelatedLinks(anchor: Doc) { return this.relatedLinker(anchor); } // finds all links that contain the given anchor - relatedLinker = computedFn(function realtedLinker(this: any, anchor: Doc) { - const related = LinkManager.Instance.getAllDirectLinks(anchor); - DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).map(anno => { - related.push(...LinkManager.Instance.getAllRelatedLinks(anno)); - }); - return related; - }.bind(this), true); + public getAllDirectLinks(anchor: Doc): Doc[] { return this.directLinker(anchor); } // finds all links that contain the given anchor - // finds all links that contain the given anchor - public getAllRelatedLinks(anchor: Doc): Doc[] { - return this.relatedLinker(anchor); - } + public getAllLinks(): Doc[] { return this.allLinks(); } - public deleteAllLinksOnAnchor(anchor: Doc) { - const related = LinkManager.Instance.getAllRelatedLinks(anchor); - related.forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc)); - } + allLinks = computedFn(function allLinks(this: any) { + const lset = new Set(DocListCast(Doc.LinkDBDoc().data)); + SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).map(doc => lset.add(doc))); + return Array.from(lset); + }, true); - // gets the groups associates with an anchor in a link - public getAnchorGroups(linkDoc: Doc, anchor?: Doc): Array { - if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, null))) { - return DocListCast(linkDoc.anchor1Groups); - } else { - return DocListCast(linkDoc.anchor2Groups); - } - } - public addGroupToAnchor(linkDoc: Doc, anchor: Doc, groupDoc: Doc, replace: boolean = false) { - Doc.GetProto(linkDoc).linkRelationship = groupDoc.linkRelationship; - } + directLinker = computedFn(function directLinker(this: any, anchor: Doc) { + return LinkManager.Instance.getAllLinks().filter(link => { + const a1 = Cast(link?.anchor1, Doc, null); + const a2 = Cast(link?.anchor2, Doc, null); + return link && ((a1?.author !== undefined && a2?.author !== undefined) || link.author === Doc.CurrentUserEmail) && (Doc.AreProtosEqual(anchor, a1) || Doc.AreProtosEqual(anchor, a2) || Doc.AreProtosEqual(link, anchor)); + }); + }, true); - // removes group doc of given group type only from given anchor on given link - public removeGroupFromAnchor(linkDoc: Doc, anchor: Doc, groupType: string) { - Doc.GetProto(linkDoc).linkRelationship = "-ungrouped-"; - } + relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc) { + const related = LinkManager.Instance.directLinker(anchor); + DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).map(anno => related.push(...LinkManager.Instance.getAllRelatedLinks(anno))); + return related; + }, true); // returns map of group type to anchor's links in that group type public getRelatedGroupedLinks(anchor: Doc): Map> { - const related = this.getAllRelatedLinks(anchor); const anchorGroups = new Map>(); - related.forEach(link => { + this.getAllRelatedLinks(anchor).forEach(link => { if (!link.linkRelationship || link?.linkRelationship !== "-ungrouped-") { const group = anchorGroups.get(StrCast(link.linkRelationship)); anchorGroups.set(StrCast(link.linkRelationship), group ? [...group, link] : [link]); - } else { // if link is in no groups then put it in default group const group = anchorGroups.get("*"); anchorGroups.set("*", group ? [...group, link] : [link]); } - }); return anchorGroups; } @@ -120,21 +78,15 @@ export class LinkManager { // returns a list of all metadata docs associated with the given group type public getAllMetadataDocsInGroup(groupType: string): Array { const md: Doc[] = []; - const allLinks = LinkManager.Instance.getAllLinks(); - allLinks.forEach(linkDoc => { - if (StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase()) { md.push(linkDoc); } - }); + LinkManager.Instance.getAllLinks().forEach(linkDoc => StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase() && md.push(linkDoc)); return md; } // checks if a link with the given anchors exists public doesLinkExist(anchor1: Doc, anchor2: Doc): boolean { - const allLinks = LinkManager.Instance.getAllLinks(); - const index = allLinks.findIndex(linkDoc => { - return (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor2)) || - (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor1)); - }); - return index !== -1; + return -1 !== LinkManager.Instance.getAllLinks().findIndex(linkDoc => + (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor2)) || + (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor1))); } // finds the opposite anchor of a given anchor in a link diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index fed9be062..abad23e0d 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -429,7 +429,7 @@ export class CollectionViewBaseChrome extends React.Component; const targetDoc = this.selectedDoc; {/* return (!targetDoc || (targetDoc._viewType !== CollectionViewType.Freeform && targetDoc.type !== DocumentType.IMG)) ? (null) :
{"Pin to presentation trail with current view"}
} placement="top"> */ } - return (targetDoc && targetDoc.type !== DocumentType.PRES && (targetDoc._viewType === CollectionViewType.Freeform || targetDoc._viewType === CollectionViewType.Stacking || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.VIDEO || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.COMPARISON)) ?
{"Pin to presentation trail with current view"}
} placement="top"> + return (targetDoc && targetDoc.type !== DocumentType.PRES && (targetDoc._viewType === CollectionViewType.Freeform || targetDoc._viewType === CollectionViewType.Stacking || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.COMPARISON)) ?
{"Pin to presentation trail with current view"}
} placement="top">