diff options
-rw-r--r-- | src/client/util/DocumentManager.ts | 11 | ||||
-rw-r--r-- | src/client/views/collections/CollectionMenu.tsx | 5 | ||||
-rw-r--r-- | src/client/views/collections/TabDocView.tsx | 7 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 7 | ||||
-rw-r--r-- | src/client/views/nodes/PresBox.tsx | 191 |
5 files changed, 109 insertions, 112 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 805e0e897..14aaeaec0 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -128,14 +128,9 @@ export class DocumentManager { } - 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?.(); - } + static addView = (doc: Doc, finished?: () => void) => { + CollectionDockingView.AddSplit(doc, "right"); + finished?.(); } public jumpToDocument = async ( targetDoc: Doc, // document to display diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 34a1c0697..338b067fa 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -400,7 +400,10 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp pinWithView = (targetDoc: Opt<Doc>) => { if (targetDoc) { TabDocView.PinDoc(targetDoc, false); - const activeDoc = PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.length - 1]; + const presArray: Doc[] = PresBox.Instance?.sortArray(); + const size: number = PresBox.Instance?._selectedArray.size; + const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined; + const activeDoc = presSelected ? PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.indexOf(presSelected) + 1] : PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.length - 1]; if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { const scroll = targetDoc._scrollTop; activeDoc.presPinView = true; diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index dcd94a7e6..82530c26d 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -134,7 +134,10 @@ export class TabDocView extends React.Component<TabDocViewProps> { pinDoc.title = doc.title + " - Slide"; pinDoc.presMovement = PresMovement.Zoom; pinDoc.context = curPres; - Doc.AddDocToList(curPres, "data", pinDoc); + const presArray: Doc[] = PresBox.Instance?.sortArray(); + const size: number = PresBox.Instance?._selectedArray.size; + const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined; + Doc.AddDocToList(curPres, "data", pinDoc, presSelected); if (pinDoc.type === "audio" && !audioRange) { pinDoc.presStartTime = 0; pinDoc.presEndTime = doc.duration; @@ -149,6 +152,8 @@ export class TabDocView extends React.Component<TabDocViewProps> { tabdocs?.push(curPres); // bcz: Argh! this is annoying. if multiple documents are pinned, this will get called multiple times before the presentation view is drawn. Thus it won't be in the tabdocs list and it will get created multple times. so need to explicilty add the presbox to the list of open tabs CollectionDockingView.AddSplit(curPres, "right"); } + PresBox.Instance?._selectedArray.clear(); + pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array DocumentManager.Instance.jumpToDocument(doc, false, undefined); batch.end(); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index c6d1c9da2..efbe85f1a 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -25,7 +25,7 @@ import "./MarqueeView.scss"; import React = require("react"); import { Id } from "../../../../fields/FieldSymbols"; import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; -import { PresMovement } from "../../nodes/PresBox"; +import { PresBox, PresMovement } from "../../nodes/PresBox"; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -399,7 +399,10 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque pinDoc.presMovement = PresMovement.Zoom; pinDoc.context = curPres; pinDoc.title = doc.title + " - Slide"; - Doc.AddDocToList(curPres, "data", pinDoc); + const presArray: Doc[] = PresBox.Instance?.sortArray(); + const size: number = PresBox.Instance?._selectedArray.size; + const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined; + Doc.AddDocToList(curPres, "data", pinDoc, presSelected); if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true; if (!DocumentManager.Instance.getDocumentView(curPres)) { CollectionDockingView.AddSplit(curPres, "right"); diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 0e92044e0..f8f794a4b 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -155,9 +155,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> this.layoutDoc.presStatus = PresStatus.Edit; this.layoutDoc._gridGap = 0; this.layoutDoc._yMargin = 0; - document.removeEventListener("keydown", PresBox.keyEventsWrapper, true); - document.addEventListener("keydown", PresBox.keyEventsWrapper, true); - this._presKeyEventsActive = true; this.turnOffEdit(true); DocListCastAsync((Doc.UserDoc().myPresentations as Doc).data).then(pres => !pres?.includes(this.rootDoc) && Doc.AddDocToList(Doc.UserDoc().myPresentations as Doc, "data", this.rootDoc)); @@ -171,75 +168,80 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> else Doc.UserDoc().activePresentation = this.rootDoc; document.removeEventListener("keydown", PresBox.keyEventsWrapper, true); document.addEventListener("keydown", PresBox.keyEventsWrapper, true); + this._presKeyEventsActive = true; PresBox.Instance = this; } - /** - * Called when the user moves to the next slide in the presentation trail. - */ + // There are still other internal frames and should go through all frames before going to next slide + nextInternalFrame = (targetDoc: Doc, activeItem: Doc) => { + const currentFrame = Cast(targetDoc?._currentFrame, "number", null); + const childDocs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); + targetDoc._viewTransition = "all 1s"; + setTimeout(() => targetDoc._viewTransition = undefined, 1010); + this.nextKeyframe(targetDoc, activeItem); + if (activeItem.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, targetDoc); + else targetDoc.editing = true; + } + + // 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played + nextAudioVideo = (targetDoc: Doc, activeItem: Doc) => { + if (targetDoc.type === DocumentType.AUDIO) AudioBox.Instance.playFrom(NumCast(activeItem.presStartTime)); + // if (targetDoc.type === DocumentType.VID) { VideoBox.Instance.Play() }; + activeItem.playNow = false; + } + + // No more frames in current doc and next slide is defined, therefore move to next slide + nextSlide = (targetDoc: Doc, activeNext: Doc) => { + const nextSelected = this.itemIndex + 1; + if (targetDoc.type === DocumentType.AUDIO) { if (AudioBox.Instance._ele) AudioBox.Instance.pause(); } + // if (targetDoc.type === DocumentType.VID) { if (AudioBox.Instance._ele) VideoBox.Instance.Pause(); } + const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); + // If next slide is audio / video 'Play automatically' then the next slide should be played + if (activeNext && (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && activeNext.playAuto) { + console.log('play next automatically'); + if (targetNext.type === DocumentType.AUDIO) AudioBox.Instance.playFrom(NumCast(activeNext.presStartTime)); + // if (targetNext.type === DocumentType.VID) { VideoBox.Instance.Play() }; + } else if (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) { activeNext.playNow = true; console.log('play next after it is navigated to'); } + this.gotoDocument(nextSelected); + } + + // Called when the user activates 'next' - to move to the next part of the pres. trail @action next = () => { - this.updateCurrentPresentation(); const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null); const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - const currentFrame = Cast(targetDoc?._currentFrame, "number", null); const lastFrame = Cast(targetDoc?.lastFrame, "number", null); const curFrame = NumCast(targetDoc?._currentFrame); let internalFrames: boolean = false; if (activeItem.presProgressivize || activeItem.zoomProgressivize || targetDoc.scrollProgressivize) internalFrames = true; - // Case 1: There are still other frames and should go through all frames before going to next slide + if (internalFrames && lastFrame !== undefined && curFrame < lastFrame) { - const childDocs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); - targetDoc._viewTransition = "all 1s"; - setTimeout(() => targetDoc._viewTransition = undefined, 1010); - // targetDoc._currentFrame = curFrame + 1; - this.nextKeyframe(targetDoc, activeItem); - if (activeItem.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, targetDoc); - 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 + // Case 1: There are still other frames and should go through all frames before going to next slide + this.nextInternalFrame(targetDoc, activeItem); } 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; - // Case 3: No more frames in current doc and next slide is defined, therefore move to next slide + // Case 2: 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played + this.nextAudioVideo(targetDoc, activeItem); } else if (this.childDocs[this.itemIndex + 1] !== undefined) { - if (activeNext.presPinView || activeNext.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(), 0); - else this.selectPres(); - const nextSelected = this.itemIndex + 1; - if (targetDoc.type === DocumentType.AUDIO) { if (AudioBox.Instance._ele) AudioBox.Instance.pause(); } - // if (targetDoc.type === DocumentType.VID) { if (AudioBox.Instance._ele) VideoBox.Instance.Pause(); } - const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); - // If next slide is audio / video 'Play automatically' then the next slide should be played - if (activeNext && (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && activeNext.playAuto) { - console.log('play next automatically'); - if (targetNext.type === DocumentType.AUDIO) AudioBox.Instance.playFrom(NumCast(activeNext.presStartTime)); - // if (targetNext.type === DocumentType.VID) { VideoBox.Instance.Play() }; - } else if (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) { activeNext.playNow = true; console.log('play next after it is navigated to'); } - this.gotoDocument(nextSelected); + // Case 3: No more frames in current doc and next slide is defined, therefore move to next slide + this.nextSlide(targetDoc, activeNext); } else if (this.childDocs[this.itemIndex + 1] === undefined && this.layoutDoc.presLoop) { + // Case 4: Last slide and presLoop is toggled ON this.gotoDocument(0); } } - /** - * Called when the user moves back - * Design choice: If there are frames within the presentation, moving back will not - * got back through the frames but instead directly to the next point in the presentation. - */ + // Called when the user activates 'back' - to move to the previous part of the pres. trail @action back = () => { - this.updateCurrentPresentation(); const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; const prevItem = Cast(this.childDocs[Math.max(0, this.itemIndex - 1)], Doc, null); const prevTargetDoc = Cast(prevItem.presentationTargetDoc, Doc, null); const lastFrame = Cast(targetDoc.lastFrame, "number", null); const curFrame = NumCast(targetDoc._currentFrame); - if (prevItem.presPinView || prevTargetDoc === this.layoutDoc.presCollection) { setTimeout(() => this.updateCurrentPresentation(), 0); } - else this.selectPres(); if (lastFrame !== undefined && curFrame >= 1) { + // Case 1: There are still other frames and should go through all frames before going to previous slide this.prevKeyframe(targetDoc, activeItem); } else if (activeItem) { let prevSelected = this.itemIndex; @@ -257,17 +259,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> this.rootDoc._itemIndex = index; const activeItem: Doc = this.activeItem; const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null); - if (activeItem.presPinView) { - const bestTarget = DocumentManager.Instance.getFirstDocumentView(presTargetDoc)?.props.Document; - bestTarget && runInAction(() => { - if (activeItem.presMovement === PresMovement.Jump) { - bestTarget._viewTransition = '0s'; - } else { - bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 1s'; - setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 1010); - } - }); - } else if (presTargetDoc) { + if (presTargetDoc) { presTargetDoc && runInAction(() => { if (activeItem.presMovement === PresMovement.Jump) presTargetDoc.focusSpeed = 0; else presTargetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500; @@ -279,12 +271,33 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> } this._selectedArray.clear(); this.childDocs[index] && this._selectedArray.set(this.childDocs[index], undefined); //Update selected array - //Handles movement to element - if (this.layoutDoc._viewType === "stacking") this.navigateToElement(this.childDocs[index]); + if (this.layoutDoc._viewType === "stacking") this.navigateToElement(this.childDocs[index]); //Handles movement to element only when presTrail is list this.onHideDocument(); //Handles hide after/before } }); + _navTimer!: NodeJS.Timeout; + navigateToView = (targetDoc: Doc, activeItem: Doc) => { + clearTimeout(this._navTimer); + const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document; + bestTarget && runInAction(() => { + if (bestTarget.type === DocumentType.PDF || bestTarget.type === DocumentType.WEB || bestTarget.type === DocumentType.RTF || bestTarget._viewType === CollectionViewType.Stacking) { + bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s'; + bestTarget._scrollY = activeItem.presPinViewScroll; + } else if (bestTarget.type === DocumentType.COMPARISON) { + bestTarget._clipWidth = activeItem.presPinClipWidth; + } else if (bestTarget.type === DocumentType.VID) { + bestTarget._currentTimecode = activeItem.presPinTimecode; + } else { + bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s'; + bestTarget._panX = activeItem.presPinViewX; + bestTarget._panY = activeItem.presPinViewY; + bestTarget._viewScale = activeItem.presPinViewScale; + } + this._navTimer = setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510); + }); + } + /** * This method makes sure that cursor navigates to the element that * has the option open and last in the group. @@ -299,14 +312,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> const srcContext = await DocCastAsync(targetDoc?.context); const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined; + const includesDoc: boolean = DocListCast(presCollection?.data).includes(targetDoc); this.turnOffEdit(); - if (this.itemIndex >= 0) { - if (srcContext && targetDoc) { - this.layoutDoc.presCollection = srcContext; - } else if (targetDoc) this.layoutDoc.presCollection = targetDoc; - } - const docToJump = curDoc; - const willZoom = false; + if (includesDoc) { + this.layoutDoc.presCollection = srcContext; + } else if (targetDoc) this.layoutDoc.presCollection = targetDoc; const presStatus = this.rootDoc.presStatus; const selViewCache = Array.from(this._selectedArray.keys()); const dragViewCache = Array.from(this._dragArray); @@ -330,47 +340,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> // If openDocument is selected then it should open the document for the user if (activeItem.openDocument) { 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) { - // this.zoomProgressivizeNext(targetDoc); - // } else - if (docToJump === curDoc) { - //checking if curDoc has navigation open - if (curDoc.presMovement === PresMovement.Pan && targetDoc) { - 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, openInTab, srcContext, undefined, undefined, undefined, resetSelection); // documents open in new tab instead of on right - } - } else { - //awaiting jump so that new scale can be found, since jumping is async - targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext); - } + } else if (curDoc.presMovement === PresMovement.Pan && targetDoc) { + await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext, undefined, undefined, undefined, includesDoc ? undefined : resetSelection); // 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, openInTab, srcContext, undefined, undefined, undefined, includesDoc ? undefined : resetSelection); // documents open in new tab instead of on right } // After navigating to the document, if it is added as a presPinView then it will // adjust the pan and scale to that of the pinView when it was added. if (activeItem.presPinView) { // if targetDoc is not displayed but one of its aliases is, then we need to modify that alias, not the original target - const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document; - bestTarget && runInAction(() => { - if (bestTarget.type === DocumentType.PDF || bestTarget.type === DocumentType.WEB || bestTarget.type === DocumentType.RTF || bestTarget._viewType === CollectionViewType.Stacking) { - bestTarget._scrollY = activeItem.presPinViewScroll; - } else if (bestTarget.type === DocumentType.COMPARISON) { - bestTarget._clipWidth = activeItem.presPinClipWidth; - } else if (bestTarget.type === DocumentType.VID) { - bestTarget._currentTimecode = activeItem.presPinTimecode; - } else { - bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s'; - bestTarget._panX = activeItem.presPinViewX; - bestTarget._panY = activeItem.presPinViewY; - bestTarget._viewScale = activeItem.presPinViewScale; - } - }); - //setTimeout(() => targetDoc._viewTransition = undefined, 1010); + this.navigateToView(targetDoc, activeItem); } - // If website and has presWebsite data associated then on click it should - // go back to that specific website // TODO: Add progressivize for navigating web (storing websites for given frames) } @@ -682,10 +663,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> this._selectedArray.set(doc, undefined); this._eleArray.push(ref); this._dragArray.push(drag); + } else { + this._selectedArray.delete(doc); + this.removeFromArray(this._eleArray, doc); + this.removeFromArray(this._dragArray, doc); } this.selectPres(); } + removeFromArray = (arr: any[], val: any) => { + const index: number = arr.indexOf(val); + const ret: any[] = arr.splice(index, 1); + arr = ret; + } + //Shift click @action shiftSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => { @@ -1608,12 +1599,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> @action turnOffEdit = (paths?: boolean) => { + // Turn off paths if (paths) { - // Turn off paths const srcContext = Cast(this.rootDoc.presCollection, Doc, null); if (srcContext) this.togglePath(srcContext, true); } - // Turn off the progressivize editors for each + // Turn off the progressivize editors for each document this.childDocs.forEach((doc) => { doc.editSnapZoomProgressivize = false; doc.editZoomProgressivize = false; |