diff options
| author | bobzel <zzzman@gmail.com> | 2022-07-07 13:02:33 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2022-07-07 13:02:33 -0400 |
| commit | dd16695b0c5fe8c54bc276a230381ae36e19e5ac (patch) | |
| tree | 0544131ca2fb0d6f3cfae81aa5bbbb8b603b61ac /src/client/views/nodes/trails/PresBox.tsx | |
| parent | a9f704fbd5676bb9a8adf4c4f7ea61bf9b3f7603 (diff) | |
trying to fix errors in compiles
Diffstat (limited to 'src/client/views/nodes/trails/PresBox.tsx')
| -rw-r--r-- | src/client/views/nodes/trails/PresBox.tsx | 2285 |
1 files changed, 1455 insertions, 830 deletions
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 7045d6d5d..91f8d1efc 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -1,55 +1,57 @@ -import React = require("react"); -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Tooltip } from "@material-ui/core"; -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; -import { observer } from "mobx-react"; -import { ColorState, SketchPicker } from "react-color"; +import React = require('react'); +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Tooltip } from '@material-ui/core'; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; +import { observer } from 'mobx-react'; +import { ColorState, SketchPicker } from 'react-color'; import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal'; -import { Doc, DocListCast, DocListCastAsync, FieldResult } from "../../../../fields/Doc"; -import { InkTool } from "../../../../fields/InkField"; -import { List } from "../../../../fields/List"; -import { PrefetchProxy } from "../../../../fields/Proxy"; -import { listSpec } from "../../../../fields/Schema"; -import { BoolCast, Cast, DocCast, NumCast, StrCast } from "../../../../fields/Types"; +import { Doc, DocListCast, DocListCastAsync, FieldResult } from '../../../../fields/Doc'; +import { InkTool } from '../../../../fields/InkField'; +import { List } from '../../../../fields/List'; +import { PrefetchProxy } from '../../../../fields/Proxy'; +import { listSpec } from '../../../../fields/Schema'; +import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types'; import { emptyFunction, returnFalse, returnOne, returnTrue, setupMoveUpEvents } from '../../../../Utils'; -import { Docs } from "../../../documents/Documents"; -import { DocumentType } from "../../../documents/DocumentTypes"; -import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; -import { DocumentManager } from "../../../util/DocumentManager"; -import { SelectionManager } from "../../../util/SelectionManager"; -import { undoBatch, UndoManager } from "../../../util/UndoManager"; -import { CollectionDockingView } from "../../collections/CollectionDockingView"; -import { MarqueeViewBounds } from "../../collections/collectionFreeForm"; -import { CollectionView, CollectionViewType } from "../../collections/CollectionView"; -import { TabDocView } from "../../collections/TabDocView"; -import { ViewBoxBaseComponent } from "../../DocComponent"; -import { Colors } from "../../global/globalEnums"; -import { LightboxView } from "../../LightboxView"; -import { CollectionFreeFormDocumentView } from "../CollectionFreeFormDocumentView"; +import { Docs } from '../../../documents/Documents'; +import { DocumentType } from '../../../documents/DocumentTypes'; +import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; +import { DocumentManager } from '../../../util/DocumentManager'; +import { SelectionManager } from '../../../util/SelectionManager'; +import { undoBatch, UndoManager } from '../../../util/UndoManager'; +import { CollectionDockingView } from '../../collections/CollectionDockingView'; +import { MarqueeViewBounds } from '../../collections/collectionFreeForm'; +import { CollectionView, CollectionViewType } from '../../collections/CollectionView'; +import { TabDocView } from '../../collections/TabDocView'; +import { ViewBoxBaseComponent } from '../../DocComponent'; +import { Colors } from '../../global/globalEnums'; +import { LightboxView } from '../../LightboxView'; +import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; -import "./PresBox.scss"; -import { PresEffect, PresMovement, PresStatus } from "./PresEnums"; -import { ScriptingGlobals } from "../../../util/ScriptingGlobals"; -import { PresElementBox } from "."; +import './PresBox.scss'; +import { PresEffect, PresMovement, PresStatus } from './PresEnums'; +import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; +import { PresElementBox } from '.'; export interface PinProps { audioRange?: boolean; setPosition?: boolean; hidePresBox?: boolean; pinWithView?: PinViewProps; - pinDocView?: boolean; // whether the current view specs of the document should be saved the pinned document - panelWidth?: number; // panel width and height of the document (used to compute the bounds of the pinned view area) - panelHeight?: number + pinDocView?: boolean; // whether the current view specs of the document should be saved the pinned document + panelWidth?: number; // panel width and height of the document (used to compute the bounds of the pinned view area) + panelHeight?: number; } export interface PinViewProps { - bounds: MarqueeViewBounds; - scale: number; + bounds: MarqueeViewBounds; + scale: number; } @observer export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); } + public static LayoutString(fieldKey: string) { + return FieldView.LayoutString(PresBox, fieldKey); + } /** * transitions & effects for documents @@ -67,22 +69,27 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc, }; switch (presDoc.presEffect) { - case PresEffect.Zoom: return (<Zoom {...effectProps}>{renderDoc}</Zoom>); - case PresEffect.Fade: return (<Fade {...effectProps}>{renderDoc}</Fade>); - case PresEffect.Flip: return (<Flip {...effectProps}>{renderDoc}</Flip>); - case PresEffect.Rotate: return (<Rotate {...effectProps}>{renderDoc}</Rotate>); - case PresEffect.Bounce: return (<Bounce {...effectProps}>{renderDoc}</Bounce>); - case PresEffect.Roll: return (<Roll {...effectProps}>{renderDoc}</Roll>); - case PresEffect.Lightspeed: return (<LightSpeed {...effectProps}>{renderDoc}</LightSpeed>); + case PresEffect.Zoom: + return <Zoom {...effectProps}>{renderDoc}</Zoom>; + case PresEffect.Fade: + return <Fade {...effectProps}>{renderDoc}</Fade>; + case PresEffect.Flip: + return <Flip {...effectProps}>{renderDoc}</Flip>; + case PresEffect.Rotate: + return <Rotate {...effectProps}>{renderDoc}</Rotate>; + case PresEffect.Bounce: + return <Bounce {...effectProps}>{renderDoc}</Bounce>; + case PresEffect.Roll: + return <Roll {...effectProps}>{renderDoc}</Roll>; + case PresEffect.Lightspeed: + return <LightSpeed {...effectProps}>{renderDoc}</LightSpeed>; case PresEffect.None: - default: return renderDoc; + default: + return renderDoc; } } public static EffectsProvider(layoutDoc: Doc, renderDoc: any) { - return PresBox.Instance && layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc ? - PresBox.renderEffectsDoc(renderDoc, layoutDoc, PresBox.Instance.childDocs[PresBox.Instance.itemIndex]) - : - renderDoc; + return PresBox.Instance && layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc ? PresBox.renderEffectsDoc(renderDoc, layoutDoc, PresBox.Instance.childDocs[PresBox.Instance.itemIndex]) : renderDoc; } @observable public static Instance: PresBox; @@ -107,10 +114,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @observable private openMovementDropdown: boolean = false; @observable private openEffectDropdown: boolean = false; @observable private presentTools: boolean = false; - @computed get isTreeOrStack() {return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._viewType) as any) } - @computed get isTree() { return this.layoutDoc._viewType === CollectionViewType.Tree;} - @computed get presFieldKey() { return StrCast(this.layoutDoc.presFieldKey, "data"); } - @computed get childDocs() { return DocListCast(this.rootDoc[this.presFieldKey]); } + @computed get isTreeOrStack() { + return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._viewType) as any); + } + @computed get isTree() { + return this.layoutDoc._viewType === CollectionViewType.Tree; + } + @computed get presFieldKey() { + return StrCast(this.layoutDoc.presFieldKey, 'data'); + } + @computed get childDocs() { + return DocListCast(this.rootDoc[this.presFieldKey]); + } @observable _treeViewMap: Map<Doc, number> = new Map(); @computed get tagDocs() { @@ -121,9 +136,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } return tagDocs; } - @computed get itemIndex() { return NumCast(this.rootDoc._itemIndex); } - @computed get activeItem() { return Cast(this.childDocs[NumCast(this.rootDoc._itemIndex)], Doc, null); } - @computed get targetDoc() { return Cast(this.activeItem?.presentationTargetDoc, Doc, null); } + @computed get itemIndex() { + return NumCast(this.rootDoc._itemIndex); + } + @computed get activeItem() { + return Cast(this.childDocs[NumCast(this.rootDoc._itemIndex)], Doc, null); + } + @computed get targetDoc() { + return Cast(this.activeItem?.presentationTargetDoc, Doc, null); + } @computed get scrollable(): boolean { if (this.targetDoc.type === DocumentType.PDF || this.targetDoc.type === DocumentType.WEB || this.targetDoc.type === DocumentType.RTF || this.targetDoc._viewType === CollectionViewType.Stacking) return true; else return false; @@ -134,7 +155,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } constructor(props: any) { super(props); - if (CurrentUserUtils.ActivePresentation = this.rootDoc) runInAction(() => PresBox.Instance = this); + if ((CurrentUserUtils.ActivePresentation = this.rootDoc)) runInAction(() => (PresBox.Instance = this)); this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox } @computed get selectedDocumentView() { @@ -142,21 +163,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (this._selectedArray.size) return DocumentManager.Instance.getDocumentView(this.rootDoc); } @computed get isPres(): boolean { - document.removeEventListener("keydown", PresBox.keyEventsWrapper, true); + document.removeEventListener('keydown', PresBox.keyEventsWrapper, true); if (this.selectedDoc?.type === DocumentType.PRES) { - document.removeEventListener("keydown", PresBox.keyEventsWrapper, true); - document.addEventListener("keydown", PresBox.keyEventsWrapper, true); + document.removeEventListener('keydown', PresBox.keyEventsWrapper, true); + document.addEventListener('keydown', PresBox.keyEventsWrapper, true); return true; } return false; } - @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } + @computed get selectedDoc() { + return this.selectedDocumentView?.rootDoc; + } _unmounting = false; @action componentWillUnmount() { this._unmounting = true; - document.removeEventListener("keydown", PresBox.keyEventsWrapper, true); + document.removeEventListener('keydown', PresBox.keyEventsWrapper, true); this._presKeyEventsActive = false; this.resetPresentation(); // Turn of progressivize editors @@ -167,37 +190,38 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @action componentDidMount() { this._unmounting = false; - this.rootDoc._forceRenderEngine = "timeline"; + this.rootDoc._forceRenderEngine = 'timeline'; this.layoutDoc.presStatus = PresStatus.Edit; this.layoutDoc._gridGap = 0; this.layoutDoc._yMargin = 0; this.turnOffEdit(true); - DocListCastAsync(CurrentUserUtils.MyTrails.data).then(pres => - !pres?.includes(this.rootDoc) && Doc.AddDocToList(CurrentUserUtils.MyTrails, "data", this.rootDoc)); - this._disposers.selection = reaction(() => SelectionManager.Views(), - views => views.some(view => view.props.Document === this.rootDoc) && this.updateCurrentPresentation()); + DocListCastAsync(CurrentUserUtils.MyTrails.data).then(pres => !pres?.includes(this.rootDoc) && Doc.AddDocToList(CurrentUserUtils.MyTrails, 'data', this.rootDoc)); + this._disposers.selection = reaction( + () => SelectionManager.Views(), + views => views.some(view => view.props.Document === this.rootDoc) && this.updateCurrentPresentation() + ); } @action updateCurrentPresentation = (pres?: Doc) => { if (pres) CurrentUserUtils.ActivePresentation = pres; else CurrentUserUtils.ActivePresentation = this.rootDoc; - document.removeEventListener("keydown", PresBox.keyEventsWrapper, true); - document.addEventListener("keydown", PresBox.keyEventsWrapper, true); + document.removeEventListener('keydown', PresBox.keyEventsWrapper, true); + document.addEventListener('keydown', PresBox.keyEventsWrapper, true); this._presKeyEventsActive = true; PresBox.Instance = this; - } + }; // 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 currentFrame = Cast(targetDoc?._currentFrame, 'number', null); const childDocs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); - targetDoc._viewTransition = "all 1s"; - setTimeout(() => targetDoc._viewTransition = undefined, 1010); + targetDoc._viewTransition = 'all 1s'; + setTimeout(() => (targetDoc._viewTransition = undefined), 1010); this.nextKeyframe(targetDoc, activeItem); if (activeItem.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, targetDoc); else targetDoc.keyFrameEditing = true; - } + }; _mediaTimer!: [NodeJS.Timeout, Doc]; // 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played @@ -207,7 +231,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const targMedia = DocumentManager.Instance.getDocumentView(targetDoc); targMedia?.ComponentView?.playFrom?.(NumCast(activeItem.presStartTime), NumCast(activeItem.presStartTime) + duration); } - } + }; stopTempMedia = (targetDocField: FieldResult) => { const targetDoc = Cast(targetDocField, Doc, null); @@ -215,11 +239,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const targMedia = DocumentManager.Instance.getDocumentView(targetDoc); targMedia?.ComponentView?.Pause?.(); } - } + }; - //TODO: al: it seems currently that tempMedia doesn't stop onslidechange after clicking the button; the time the tempmedia stop depends on the start & end time + //TODO: al: it seems currently that tempMedia doesn't stop onslidechange after clicking the button; the time the tempmedia stop depends on the start & end time // TODO: to handle child slides (entering into subtrail and exiting), also the next() and back() functions - // No more frames in current doc and next slide is defined, therefore move to next slide + // No more frames in current doc and next slide is defined, therefore move to next slide nextSlide = (activeNext: Doc) => { const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); console.info('nextSlide', activeNext.title, targetNext?.title); @@ -229,11 +253,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (!this.childDocs[nextSelected].groupWithUp) { break; } else { - console.log("Title: " + this.childDocs[nextSelected].title); + console.log('Title: ' + this.childDocs[nextSelected].title); this.gotoDocument(nextSelected, this.activeItem, true); } } - } + }; // Called when the user activates 'next' - to move to the next part of the pres. trail @action @@ -241,7 +265,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null); const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - const lastFrame = Cast(targetDoc?.lastFrame, "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; @@ -249,13 +273,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // Case 1: There are still other frames and should go through all frames before going to next slide this.nextInternalFrame(targetDoc, activeItem); } else if (this.childDocs[this.itemIndex + 1] !== undefined) { - // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide + // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide this.nextSlide(activeNext); } else if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) { // Case 3: Last slide and presLoop is toggled ON or it is in Edit mode this.gotoDocument(0, this.activeItem); } - } + }; // Called when the user activates 'back' - to move to the previous part of the pres. trail @action @@ -264,7 +288,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { 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 lastFrame = Cast(targetDoc.lastFrame, 'number', null); const curFrame = NumCast(targetDoc._currentFrame); let prevSelected = this.itemIndex; // Functionality for group with up @@ -284,7 +308,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // Case 3: Pres loop is on so it should go to the last slide this.gotoDocument(this.childDocs.length - 1, activeItem); } - } + }; //The function that is called when a document is clicked or reached through next or back. //it'll also execute the necessary actions if presentation is playing. @@ -297,20 +321,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (from?.mediaStopTriggerList && this.layoutDoc.presStatus !== PresStatus.Edit) { DocListCast(from.mediaStopTriggerList).forEach(this.stopTempMedia); } - if (from?.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) { + if (from?.mediaStop === 'auto' && this.layoutDoc.presStatus !== PresStatus.Edit) { this.stopTempMedia(from.presentationTargetDoc); } // If next slide is audio / video 'Play automatically' then the next slide should be played - if (this.layoutDoc.presStatus !== PresStatus.Edit && (targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && (activeItem.mediaStart === "auto")) { + if (this.layoutDoc.presStatus !== PresStatus.Edit && (targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && activeItem.mediaStart === 'auto') { this.startTempMedia(targetDoc, activeItem); } if (targetDoc) { - Doc.linkFollowHighlight((targetDoc.annotationOn instanceof Doc) ? [targetDoc, targetDoc.annotationOn] : targetDoc); - targetDoc && runInAction(() => { - if (activeItem.presMovement === PresMovement.Jump) targetDoc.focusSpeed = 0; - else targetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500; - }); - setTimeout(() => targetDoc.focusSpeed = 500, this.activeItem.presTransition ? NumCast(this.activeItem.presTransition) + 10 : 510); + Doc.linkFollowHighlight(targetDoc.annotationOn instanceof Doc ? [targetDoc, targetDoc.annotationOn] : targetDoc); + targetDoc && + runInAction(() => { + if (activeItem.presMovement === PresMovement.Jump) targetDoc.focusSpeed = 0; + else targetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500; + }); + setTimeout(() => (targetDoc.focusSpeed = 500), this.activeItem.presTransition ? NumCast(this.activeItem.presTransition) + 10 : 510); } if (targetDoc?.lastFrame !== undefined) { targetDoc._currentFrame = 0; @@ -327,14 +352,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { clearTimeout(this._navTimer); const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document; if (bestTarget) console.log(bestTarget.title, bestTarget.type); - else console.log("no best target"); - if (bestTarget) this._navTimer = PresBox.navigateToDoc(bestTarget, activeItem, false); - } + else console.log('no best target'); + if (bestTarget) this._navTimer = PresBox.navigateToDoc(bestTarget, activeItem, false); + }; // navigates to the bestTarget document by making sure it is on screen, - // then it applies the view specs stored in activeItem to + // then it applies the view specs stored in activeItem to @action - static navigateToDoc(bestTarget:Doc, activeItem:Doc, jumpToDoc:boolean) { + static navigateToDoc(bestTarget: Doc, activeItem: Doc, jumpToDoc: boolean) { 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._scrollTop = activeItem.presPinViewScroll; @@ -343,32 +368,31 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } else if ([DocumentType.AUDIO, DocumentType.VID].includes(bestTarget.type as any)) { bestTarget._currentTimecode = activeItem.presStartTime; } else { - const contentBounds= Cast(activeItem.contentBounds, listSpec("number")); + const contentBounds = Cast(activeItem.contentBounds, listSpec('number')); bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s'; if (contentBounds) { - bestTarget._panX = (contentBounds[0] + contentBounds[2])/2; - bestTarget._panY = (contentBounds[1] + contentBounds[3])/2; + bestTarget._panX = (contentBounds[0] + contentBounds[2]) / 2; + bestTarget._panY = (contentBounds[1] + contentBounds[3]) / 2; const dv = DocumentManager.Instance.getDocumentView(bestTarget); if (dv) { - bestTarget._viewScale = Math.min(dv.props.PanelHeight() / (contentBounds[3] - contentBounds[1]), - dv.props.PanelWidth() / (contentBounds[2]- contentBounds[0])); - }; + bestTarget._viewScale = Math.min(dv.props.PanelHeight() / (contentBounds[3] - contentBounds[1]), dv.props.PanelWidth() / (contentBounds[2] - contentBounds[0])); + } } else { bestTarget._panX = activeItem.presPinViewX; bestTarget._panY = activeItem.presPinViewY; bestTarget._viewScale = activeItem.presPinViewScale; } } - return setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510); + return 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. - * Design choice: If the next document is not in presCollection or + * has the option open and last in the group. + * Design choice: If the next document is not in presCollection or * presCollection itself then if there is a presCollection it will add * a new tab. If presCollection is undefined it will open the document - * on the right. + * on the right. */ navigateToElement = async (curDoc: Doc) => { const activeItem: Doc = this.activeItem; @@ -401,7 +425,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { self._eleArray.splice(0, self._eleArray.length, ...eleViewCache); }); const openInTab = (doc: Doc, finished?: () => void) => { - collectionDocView ? collectionDocView.props.addDocTab(doc, "") : this.props.addDocTab(doc, ""); + collectionDocView ? collectionDocView.props.addDocTab(doc, '') : this.props.addDocTab(doc, ''); this.layoutDoc.presCollection = targetDoc; // this still needs some fixing setTimeout(resetSelection, 500); @@ -417,21 +441,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // openInTab(targetDoc); } else if (curDoc.presMovement === PresMovement.Pan && targetDoc) { LightboxView.SetLightboxDoc(undefined); - await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext ? [srcContext]:[], undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true); // documents open in new tab instead of on right + await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext ? [srcContext] : [], undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true); // documents open in new tab instead of on right } else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) { LightboxView.SetLightboxDoc(undefined); - //awaiting jump so that new scale can be found, since jumping is async - await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext ? [srcContext]:[], undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true, NumCast(curDoc.presZoom)); // documents open in new tab instead of on right + //awaiting jump so that new scale can be found, since jumping is async + await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext ? [srcContext] : [], undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true, NumCast(curDoc.presZoom)); // 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) { console.log(targetDoc.title); - console.log("presPinView in PresBox.tsx:420"); + console.log('presPinView in PresBox.tsx:420'); // if targetDoc is not displayed but one of its aliases is, then we need to modify that alias, not the original target this.navigateToView(targetDoc, activeItem); } - } + }; /** * Uses the viewfinder to progressivize through the different views of a single collection. @@ -441,10 +465,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const targetDoc: Doc = this.targetDoc; const srcContext = Cast(targetDoc?.context, Doc, null); const docView = DocumentManager.Instance.getDocumentView(targetDoc); - const vfLeft = this.checkList(targetDoc, activeItem["viewfinder-left-indexed"]); - const vfWidth = this.checkList(targetDoc, activeItem["viewfinder-width-indexed"]); - const vfTop = this.checkList(targetDoc, activeItem["viewfinder-top-indexed"]); - const vfHeight = this.checkList(targetDoc, activeItem["viewfinder-height-indexed"]); + const vfLeft = this.checkList(targetDoc, activeItem['viewfinder-left-indexed']); + const vfWidth = this.checkList(targetDoc, activeItem['viewfinder-width-indexed']); + const vfTop = this.checkList(targetDoc, activeItem['viewfinder-top-indexed']); + const vfHeight = this.checkList(targetDoc, activeItem['viewfinder-height-indexed']); // Case 1: document that is not a Golden Layout tab if (srcContext) { const srcDocView = DocumentManager.Instance.getDocumentView(srcContext); @@ -455,8 +479,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const newPanX = NumCast(targetDoc.x) + NumCast(layoutdoc._width) / 2; const newPanY = NumCast(targetDoc.y) + NumCast(layoutdoc._height) / 2; const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight); - srcContext._panX = newPanX + (vfLeft + (vfWidth / 2)); - srcContext._panY = newPanY + (vfTop + (vfHeight / 2)); + srcContext._panX = newPanX + (vfLeft + vfWidth / 2); + srcContext._panY = newPanY + (vfTop + vfHeight / 2); srcContext._viewScale = newScale; } } @@ -465,8 +489,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const panelWidth: number = docView.props.PanelWidth(); const panelHeight: number = docView.props.PanelHeight(); const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight); - targetDoc._panX = vfLeft + (vfWidth / 2); - targetDoc._panY = vfTop + (vfWidth / 2); + targetDoc._panX = vfLeft + vfWidth / 2; + targetDoc._panY = vfTop + vfWidth / 2; targetDoc._viewScale = newScale; } const resize = document.getElementById('resizable'); @@ -476,7 +500,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { resize.style.top = vfTop + 'px'; resize.style.left = vfLeft + 'px'; } - } + }; /** * For 'Hide Before' and 'Hide After' buttons making sure that @@ -490,18 +514,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (tagDoc) tagDoc.opacity = 1; const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, tagDoc); const curInd: number = itemIndexes.indexOf(index); - if (tagDoc === this.layoutDoc.presCollection) { tagDoc.opacity = 1; } - else { - if (itemIndexes.length > 1 && curDoc.presHideBefore && curInd !== 0) { } - else if (curDoc.presHideBefore) { + if (tagDoc === this.layoutDoc.presCollection) { + tagDoc.opacity = 1; + } else { + if (itemIndexes.length > 1 && curDoc.presHideBefore && curInd !== 0) { + } else if (curDoc.presHideBefore) { if (index > this.itemIndex) { tagDoc.opacity = 0; } else if (!curDoc.presHideAfter) { tagDoc.opacity = 1; } } - if (itemIndexes.length > 1 && curDoc.presHideAfter && curInd !== (itemIndexes.length - 1)) { } - else if (curDoc.presHideAfter) { + if (itemIndexes.length > 1 && curDoc.presHideAfter && curInd !== itemIndexes.length - 1) { + } else if (curDoc.presHideAfter) { if (index < this.itemIndex) { tagDoc.opacity = 0; } else if (!curDoc.presHideBefore) { @@ -510,9 +535,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } } }); - } - - + }; //The function that starts or resets presentaton functionally, depending on presStatus of the layoutDoc @action @@ -521,13 +544,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { let activeItem: Doc = this.activeItem; let targetDoc: Doc = this.targetDoc; let duration = NumCast(activeItem.presDuration) + NumCast(activeItem.presTransition); - const timer = (ms: number) => new Promise(res => this._presTimer = setTimeout(res, ms)); - const load = async () => { // Wrap the loop into an async function for this to work + const timer = (ms: number) => new Promise(res => (this._presTimer = setTimeout(res, ms))); + const load = async () => { + // Wrap the loop into an async function for this to work for (var i = startSlide; i < this.childDocs.length; i++) { activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); duration = NumCast(activeItem.presDuration) + NumCast(activeItem.presTransition); - if (duration < 100) { duration = 2500; } + if (duration < 100) { + duration = 2500; + } if (NumCast(targetDoc.lastFrame) > 0) { for (var f = 0; f < NumCast(targetDoc.lastFrame); f++) { await timer(duration / NumCast(targetDoc.lastFrame)); @@ -535,7 +561,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } } - await timer(duration); this.next(); // then the created Promise can be awaited + await timer(duration); + this.next(); // then the created Promise can be awaited if (i === this.childDocs.length - 1) { setTimeout(() => { clearTimeout(this._presTimer); @@ -549,7 +576,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this.startPresentation(startSlide); this.gotoDocument(startSlide, activeItem); load(); - } + }; // The function pauses the auto presentation @action @@ -560,20 +587,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this.layoutDoc.presLoop = false; this.childDocs.forEach(this.stopTempMedia); } - } + }; //The function that resets the presentation by removing every action done by it. It also //stops the presentaton. resetPresentation = () => { this.rootDoc._itemIndex = 0; - this.childDocs.map(doc => Cast(doc.presentationTargetDoc, Doc, null)).filter(doc => doc instanceof Doc).forEach(doc => { - try { - doc.opacity = 1; - } catch (e) { - console.log("Reset presentation error: ", e); - } - }); - } + this.childDocs + .map(doc => Cast(doc.presentationTargetDoc, Doc, null)) + .filter(doc => doc instanceof Doc) + .forEach(doc => { + try { + doc.opacity = 1; + } catch (e) { + console.log('Reset presentation error: ', e); + } + }); + }; // The function allows for viewing the pres path on toggle @action togglePath = (srcContext: Doc, off?: boolean) => { @@ -581,19 +611,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this._pathBoolean = false; srcContext.presPathView = false; } else { - runInAction(() => this._pathBoolean = !this._pathBoolean); + runInAction(() => (this._pathBoolean = !this._pathBoolean)); srcContext.presPathView = this._pathBoolean; } - } + }; // The function allows for expanding the view of pres on toggle @action toggleExpandMode = () => { - runInAction(() => this._expandBoolean = !this._expandBoolean); + runInAction(() => (this._expandBoolean = !this._expandBoolean)); this.rootDoc.expandBoolean = this._expandBoolean; - this.childDocs.forEach((doc) => { + this.childDocs.forEach(doc => { doc.presExpandInlineButton = this._expandBoolean; }); - } + }; /** * The function that starts the presentation at the given index, also checking if actions should be applied @@ -611,7 +641,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { tagDoc.opacity = 0; } }); - } + }; /** * The method called to open the presentation as a minimized view @@ -621,7 +651,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.layoutDoc)) { this.layoutDoc.presStatus = PresStatus.Edit; Doc.RemoveDocFromList(CurrentUserUtils.MyOverlayDocs, undefined, this.rootDoc); - CollectionDockingView.AddSplit(this.rootDoc, "right"); + CollectionDockingView.AddSplit(this.rootDoc, 'right'); } else { this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); @@ -633,7 +663,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { Doc.AddDocToList(CurrentUserUtils.MyOverlayDocs, undefined, this.rootDoc); this.props.removeDocument?.(this.layoutDoc); } - } + }; /** * Called when the user changes the view type @@ -643,7 +673,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { viewChanged = action((e: React.ChangeEvent) => { //@ts-ignore const viewType = e.target.selectedOptions[0].value as CollectionViewType; - this.layoutDoc.presFieldKey = this.fieldKey+(viewType === CollectionViewType.Tree ?"-linearized":""); + this.layoutDoc.presFieldKey = this.fieldKey + (viewType === CollectionViewType.Tree ? '-linearized' : ''); // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here [CollectionViewType.Tree || CollectionViewType.Stacking].includes(viewType) && (this.rootDoc._pivotField = undefined); this.rootDoc._viewType = viewType; @@ -677,20 +707,30 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } }); - setMovementName = action((movement: any, activeItem: Doc): string => { let output: string = 'none'; switch (movement) { - case PresMovement.Zoom: output = 'Pan & Zoom'; break; //Pan and zoom - case PresMovement.Pan: output = 'Pan'; break; //Pan - case PresMovement.Jump: output = 'Jump cut'; break; //Jump Cut - case PresMovement.None: output = 'None'; break; //None - default: output = 'Zoom'; activeItem.presMovement = 'zoom'; break; //default set as zoom + case PresMovement.Zoom: + output = 'Pan & Zoom'; + break; //Pan and zoom + case PresMovement.Pan: + output = 'Pan'; + break; //Pan + case PresMovement.Jump: + output = 'Jump cut'; + break; //Jump Cut + case PresMovement.None: + output = 'None'; + break; //None + default: + output = 'Zoom'; + activeItem.presMovement = 'zoom'; + break; //default set as zoom } return output; }); - whenChildContentsActiveChanged = action((isActive: boolean) => this.props.whenChildContentsActiveChanged(this._isChildActive = isActive)); + whenChildContentsActiveChanged = action((isActive: boolean) => this.props.whenChildContentsActiveChanged((this._isChildActive = isActive))); // For dragging documents into the presentation trail addDocumentFilter = (docs: Doc[]) => { docs.forEach((doc, i) => { @@ -698,8 +738,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (doc.type === DocumentType.LABEL) { const audio = Cast(doc.annotationOn, Doc, null); if (audio) { - audio.mediaStart = "manual"; - audio.mediaStop = "manual"; + audio.mediaStart = 'manual'; + audio.mediaStop = 'manual'; audio.presStartTime = NumCast(doc._timecodeToShow /* audioStart */, NumCast(doc._timecodeToShow /* videoStart */)); audio.presEndTime = NumCast(doc._timecodeToHide /* audioEnd */, NumCast(doc._timecodeToHide /* videoEnd */)); audio.presDuration = audio.presStartTime - audio.presEndTime; @@ -714,7 +754,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { setTimeout(() => this.removeDocument(doc), 0); return false; } else { - if (!doc.presentationTargetDoc) doc.title = doc.title + " - Slide"; + if (!doc.presentationTargetDoc) doc.title = doc.title + ' - Slide'; doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf); doc.presMovement = PresMovement.Zoom; if (this._expandBoolean) doc.presExpandInlineButton = true; @@ -722,13 +762,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } }); return true; - } - childLayoutTemplate = () => !this.isTreeOrStack ? undefined : DocCast(Doc.UserDoc().presElement); + }; + childLayoutTemplate = () => (!this.isTreeOrStack ? undefined : DocCast(Doc.UserDoc().presElement)); removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.rootDoc, this.fieldKey, doc); - getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight + getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65); // listBox padding-left and pres-box-cont minHeight panelHeight = () => this.props.PanelHeight() - 40; - isContentActive = (outsideReaction?: boolean) => ((CurrentUserUtils.ActiveTool === InkTool.None && !this.layoutDoc._lockedPosition) && - (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) + isContentActive = (outsideReaction?: boolean) => + CurrentUserUtils.ActiveTool === InkTool.None && !this.layoutDoc._lockedPosition && (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false; /** * For sorting the array so that the order is maintained when it is dropped. @@ -736,7 +776,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @action sortArray = (): Doc[] => { return this.childDocs.filter(doc => this._selectedArray.has(doc)); - } + }; /** * Method to get the list of selected items in the order in which they have been selected @@ -745,9 +785,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const list = Array.from(this._selectedArray.keys()).map((doc: Doc, index: any) => { const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); - if (curDoc && curDoc === this.activeItem) return <div key={index} className="selectedList-items"><b>{index + 1}. {curDoc.title}</b></div>; - else if (tagDoc) return <div key={index} className="selectedList-items">{index + 1}. {curDoc.title}</div>; - else if (curDoc) return <div key={index} className="selectedList-items">{index + 1}. {curDoc.title}</div>; + if (curDoc && curDoc === this.activeItem) + return ( + <div key={index} className="selectedList-items"> + <b> + {index + 1}. {curDoc.title} + </b> + </div> + ); + else if (tagDoc) + return ( + <div key={index} className="selectedList-items"> + {index + 1}. {curDoc.title} + </div> + ); + else if (curDoc) + return ( + <div key={index} className="selectedList-items"> + {index + 1}. {curDoc.title} + </div> + ); }); return list; } @@ -756,7 +813,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { selectPres = () => { const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc); presDocView && SelectionManager.SelectView(presDocView, false); - } + }; //Regular click @action @@ -766,12 +823,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (doc.presPinView || doc.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(context), 0); else this.updateCurrentPresentation(context); - if (this.activeItem.setPosition && - this.activeItem.y !== undefined && - this.activeItem.x !== undefined && - this.targetDoc.x !== undefined && - this.targetDoc.y !== undefined) { - const timer = (ms: number) => new Promise(res => this._presTimer = setTimeout(res, ms)); + if (this.activeItem.setPosition && this.activeItem.y !== undefined && this.activeItem.x !== undefined && this.targetDoc.x !== undefined && this.targetDoc.y !== undefined) { + const timer = (ms: number) => new Promise(res => (this._presTimer = setTimeout(res, ms))); const time = 10; const ydiff = NumCast(this.activeItem.y) - NumCast(this.targetDoc.y); const xdiff = NumCast(this.activeItem.x) - NumCast(this.targetDoc.x); @@ -782,7 +835,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { await timer(0.1); } } - } + }; //Command click @action @@ -797,13 +850,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { 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 @@ -818,7 +871,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } } this.selectPres(); - } + }; //regular click @action @@ -829,17 +882,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this._dragArray.splice(0, this._dragArray.length, drag); focus && this.selectElement(doc); selectPres && this.selectPres(); - } + }; modifierSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, cmdClick: boolean, shiftClick: boolean) => { if (cmdClick) this.multiSelect(doc, ref, drag); else if (shiftClick) this.shiftSelect(doc, ref, drag); else this.regularSelect(doc, ref, drag, focus); - } + }; static keyEventsWrapper = (e: KeyboardEvent) => { PresBox.Instance.keyEvents(e); - } + }; // Key for when the presentaiton is active @action @@ -847,57 +900,75 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (e.target instanceof HTMLInputElement) return; let handled = false; const anchorNode = document.activeElement as HTMLDivElement; - if (anchorNode && anchorNode.className?.includes("lm_title")) return; + if (anchorNode && anchorNode.className?.includes('lm_title')) return; switch (e.key) { - case "Backspace": - if (this.layoutDoc.presStatus === "edit") { - undoBatch(action(() => { - for (const doc of Array.from(this._selectedArray.keys())) { - this.removeDocument(doc); - } - this._selectedArray.clear(); - this._eleArray.length = 0; - this._dragArray.length = 0; - }))(); + case 'Backspace': + if (this.layoutDoc.presStatus === 'edit') { + undoBatch( + action(() => { + for (const doc of Array.from(this._selectedArray.keys())) { + this.removeDocument(doc); + } + this._selectedArray.clear(); + this._eleArray.length = 0; + this._dragArray.length = 0; + }) + )(); handled = true; } break; - case "Escape": - if (DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.layoutDoc)) { this.updateMinimize(); } - else if (this.layoutDoc.presStatus === "edit") { this._selectedArray.clear(); this._eleArray.length = this._dragArray.length = 0; } - else this.layoutDoc.presStatus = "edit"; + case 'Escape': + if (DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.layoutDoc)) { + this.updateMinimize(); + } else if (this.layoutDoc.presStatus === 'edit') { + this._selectedArray.clear(); + this._eleArray.length = this._dragArray.length = 0; + } else this.layoutDoc.presStatus = 'edit'; if (this._presTimer) clearTimeout(this._presTimer); handled = true; break; - case "Down": case "ArrowDown": - case "Right": case "ArrowRight": - if (e.shiftKey && this.itemIndex < this.childDocs.length - 1) { // TODO: update to work properly + case 'Down': + case 'ArrowDown': + case 'Right': + case 'ArrowRight': + if (e.shiftKey && this.itemIndex < this.childDocs.length - 1) { + // TODO: update to work properly this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) + 1; this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined); } else { this.next(); - if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } + if (this._presTimer) { + clearTimeout(this._presTimer); + this.layoutDoc.presStatus = PresStatus.Manual; + } } handled = true; break; - case "Up": case "ArrowUp": - case "Left": case "ArrowLeft": - if (e.shiftKey && this.itemIndex !== 0) { // TODO: update to work properly + case 'Up': + case 'ArrowUp': + case 'Left': + case 'ArrowLeft': + if (e.shiftKey && this.itemIndex !== 0) { + // TODO: update to work properly this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) - 1; this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined); } else { this.back(); - if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } + if (this._presTimer) { + clearTimeout(this._presTimer); + this.layoutDoc.presStatus = PresStatus.Manual; + } } handled = true; break; - case "Spacebar": case " ": + case 'Spacebar': + case ' ': if (this.layoutDoc.presStatus === PresStatus.Manual) this.startAutoPres(this.itemIndex); else if (this.layoutDoc.presStatus === PresStatus.Autoplay) if (this._presTimer) clearTimeout(this._presTimer); handled = true; break; - case "a": - if ((e.metaKey || e.altKey) && this.layoutDoc.presStatus === "edit") { + case 'a': + if ((e.metaKey || e.altKey) && this.layoutDoc.presStatus === 'edit') { this._selectedArray.clear(); this.childDocs.forEach(doc => this._selectedArray.set(doc, undefined)); handled = true; @@ -909,10 +980,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { e.stopPropagation(); e.preventDefault(); } - } + }; /** - * + * */ @action viewPaths = () => { @@ -920,7 +991,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (srcContext) { this.togglePath(srcContext); } - } + }; getAllIndexes = (arr: Doc[], val: Doc): number[] => { const indexes = []; @@ -928,7 +999,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { arr[i] === val && indexes.push(i); } return indexes; - } + }; // Adds the index in the pres path graphically @computed get order() { @@ -936,61 +1007,64 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const docs: Doc[] = []; const presCollection = Cast(this.rootDoc.presCollection, Doc, null); const dv = DocumentManager.Instance.getDocumentView(presCollection); - this.childDocs.filter(doc => Cast(doc.presentationTargetDoc, Doc, null)).forEach((doc, index) => { - const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); - const srcContext = Cast(tagDoc.context, Doc, null); - const width = NumCast(tagDoc._width) / 10; - const height = Math.max(NumCast(tagDoc._height) / 10, 15); - const edge = Math.max(width, height); - const fontSize = edge * 0.8; - const gap = 2; - if (presCollection === srcContext) { - // Case A: Document is contained within the collection - if (docs.includes(tagDoc)) { - const prevOccurances: number = this.getAllIndexes(docs, tagDoc).length; - docs.push(tagDoc); - order.push( - <div className="pathOrder" - key={tagDoc.id + 'pres' + index} - style={{ top: NumCast(tagDoc.y) + (prevOccurances * (edge + gap) - (edge / 2)), left: NumCast(tagDoc.x) - (edge / 2), width: edge, height: edge, fontSize: fontSize }} - onClick={() => this.selectElement(doc)}> - <div className="pathOrder-frame">{index + 1}</div> - </div>); - } else { + this.childDocs + .filter(doc => Cast(doc.presentationTargetDoc, Doc, null)) + .forEach((doc, index) => { + const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); + const srcContext = Cast(tagDoc.context, Doc, null); + const width = NumCast(tagDoc._width) / 10; + const height = Math.max(NumCast(tagDoc._height) / 10, 15); + const edge = Math.max(width, height); + const fontSize = edge * 0.8; + const gap = 2; + if (presCollection === srcContext) { + // Case A: Document is contained within the collection + if (docs.includes(tagDoc)) { + const prevOccurances: number = this.getAllIndexes(docs, tagDoc).length; + docs.push(tagDoc); + order.push( + <div + className="pathOrder" + key={tagDoc.id + 'pres' + index} + style={{ top: NumCast(tagDoc.y) + (prevOccurances * (edge + gap) - edge / 2), left: NumCast(tagDoc.x) - edge / 2, width: edge, height: edge, fontSize: fontSize }} + onClick={() => this.selectElement(doc)}> + <div className="pathOrder-frame">{index + 1}</div> + </div> + ); + } else { + docs.push(tagDoc); + order.push( + <div + className="pathOrder" + key={tagDoc.id + 'pres' + index} + style={{ top: NumCast(tagDoc.y) - edge / 2, left: NumCast(tagDoc.x) - edge / 2, width: edge, height: edge, fontSize: fontSize }} + onClick={() => this.selectElement(doc)}> + <div className="pathOrder-frame">{index + 1}</div> + </div> + ); + } + } else if (doc.presPinView && presCollection === tagDoc && dv) { + // Case B: Document is presPinView and is presCollection + const scale: number = 1 / NumCast(doc.presPinViewScale); + const height: number = dv.props.PanelHeight() * scale; + const width: number = dv.props.PanelWidth() * scale; + const indWidth = width / 10; + const indHeight = Math.max(height / 10, 15); + const indEdge = Math.max(indWidth, indHeight); + const indFontSize = indEdge * 0.8; + const xLoc: number = NumCast(doc.presPinViewX) - width / 2; + const yLoc: number = NumCast(doc.presPinViewY) - height / 2; docs.push(tagDoc); order.push( - <div className="pathOrder" - key={tagDoc.id + 'pres' + index} - style={{ top: NumCast(tagDoc.y) - (edge / 2), left: NumCast(tagDoc.x) - (edge / 2), width: edge, height: edge, fontSize: fontSize }} - onClick={() => this.selectElement(doc)}> - <div className="pathOrder-frame">{index + 1}</div> - </div>); + <> + <div className="pathOrder" key={tagDoc.id + 'pres' + index} style={{ top: yLoc - indEdge / 2, left: xLoc - indEdge / 2, width: indEdge, height: indEdge, fontSize: indFontSize }} onClick={() => this.selectElement(doc)}> + <div className="pathOrder-frame">{index + 1}</div> + </div> + <div className="pathOrder-presPinView" style={{ top: yLoc, left: xLoc, width: width, height: height, borderWidth: indEdge / 10 }}></div> + </> + ); } - } else if (doc.presPinView && presCollection === tagDoc && dv) { - // Case B: Document is presPinView and is presCollection - const scale: number = 1 / NumCast(doc.presPinViewScale); - const height: number = dv.props.PanelHeight() * scale; - const width: number = dv.props.PanelWidth() * scale; - const indWidth = width / 10; - const indHeight = Math.max(height / 10, 15); - const indEdge = Math.max(indWidth, indHeight); - const indFontSize = indEdge * 0.8; - const xLoc: number = NumCast(doc.presPinViewX) - (width / 2); - const yLoc: number = NumCast(doc.presPinViewY) - (height / 2); - docs.push(tagDoc); - order.push( - <> - <div className="pathOrder" - key={tagDoc.id + 'pres' + index} - style={{ top: yLoc - (indEdge / 2), left: xLoc - (indEdge / 2), width: indEdge, height: indEdge, fontSize: indFontSize }} - onClick={() => this.selectElement(doc)} - > - <div className="pathOrder-frame">{index + 1}</div> - </div> - <div className="pathOrder-presPinView" style={{ top: yLoc, left: xLoc, width: width, height: height, borderWidth: indEdge / 10 }}></div> - </>); - } - }); + }); return order; } @@ -1003,37 +1077,39 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { * collection) */ @computed get paths() { - let pathPoints = ""; + let pathPoints = ''; const presCollection = Cast(this.rootDoc.presCollection, Doc, null); this.childDocs.forEach((doc, index) => { const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); const srcContext = Cast(tagDoc?.context, Doc, null); if (tagDoc && presCollection === srcContext) { - const n1x = NumCast(tagDoc.x) + (NumCast(tagDoc._width) / 2); - const n1y = NumCast(tagDoc.y) + (NumCast(tagDoc._height) / 2); - if (index = 0) pathPoints = n1x + "," + n1y; - else pathPoints = pathPoints + " " + n1x + "," + n1y; + const n1x = NumCast(tagDoc.x) + NumCast(tagDoc._width) / 2; + const n1y = NumCast(tagDoc.y) + NumCast(tagDoc._height) / 2; + if ((index = 0)) pathPoints = n1x + ',' + n1y; + else pathPoints = pathPoints + ' ' + n1x + ',' + n1y; } else if (doc.presPinView && presCollection === tagDoc) { const n1x = NumCast(doc.presPinViewX); const n1y = NumCast(doc.presPinViewY); - if (index = 0) pathPoints = n1x + "," + n1y; - else pathPoints = pathPoints + " " + n1x + "," + n1y; + if ((index = 0)) pathPoints = n1x + ',' + n1y; + else pathPoints = pathPoints + ' ' + n1x + ',' + n1y; } }); - return (<polyline - points={pathPoints} - style={{ - opacity: 1, - stroke: "#69a6db", - strokeWidth: 5, - strokeDasharray: '10 5', - boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)', - }} - fill="none" - markerStart="url(#markerArrow)" - markerMid="url(#markerSquare)" - markerEnd="url(#markerSquareFilled)" - />); + return ( + <polyline + points={pathPoints} + style={{ + opacity: 1, + stroke: '#69a6db', + strokeWidth: 5, + strokeDasharray: '10 5', + boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)', + }} + fill="none" + markerStart="url(#markerArrow)" + markerMid="url(#markerSquare)" + markerEnd="url(#markerSquareFilled)" + /> + ); } // Converts seconds to ms and updates presTransition @@ -1042,8 +1118,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (change) timeInMS += change; if (timeInMS < 100) timeInMS = 100; if (timeInMS > 10000) timeInMS = 10000; - Array.from(this._selectedArray.keys()).forEach((doc) => doc.presTransition = timeInMS); - } + Array.from(this._selectedArray.keys()).forEach(doc => (doc.presTransition = timeInMS)); + }; // Converts seconds to ms and updates presTransition setZoom = (number: String, change?: number) => { @@ -1051,8 +1127,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (change) scale += change; if (scale < 0.01) scale = 0.01; if (scale > 1.5) scale = 1.5; - Array.from(this._selectedArray.keys()).forEach((doc) => doc.presZoom = scale); - } + Array.from(this._selectedArray.keys()).forEach(doc => (doc.presZoom = scale)); + }; // Converts seconds to ms and updates presDuration setDurationTime = (number: String, change?: number) => { @@ -1060,8 +1136,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (change) timeInMS += change; if (timeInMS < 100) timeInMS = 100; if (timeInMS > 20000) timeInMS = 20000; - Array.from(this._selectedArray.keys()).forEach((doc) => doc.presDuration = timeInMS); - } + Array.from(this._selectedArray.keys()).forEach(doc => (doc.presDuration = timeInMS)); + }; /** * When the movement dropdown is changes @@ -1069,7 +1145,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @undoBatch updateMovement = action((movement: any, all?: boolean) => { const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys()); - array.forEach((doc) => { + array.forEach(doc => { switch (movement) { case PresMovement.Zoom: //Pan and zoom doc.presMovement = PresMovement.Zoom; @@ -1081,7 +1157,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { doc.presJump = true; doc.presMovement = PresMovement.Jump; break; - case PresMovement.None: default: + case PresMovement.None: + default: doc.presMovement = PresMovement.None; break; } @@ -1092,31 +1169,31 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @action updateHideBefore = (activeItem: Doc) => { activeItem.presHideBefore = !activeItem.presHideBefore; - Array.from(this._selectedArray.keys()).forEach((doc) => doc.presHideBefore = activeItem.presHideBefore); - } + Array.from(this._selectedArray.keys()).forEach(doc => (doc.presHideBefore = activeItem.presHideBefore)); + }; @undoBatch @action updateHideAfter = (activeItem: Doc) => { activeItem.presHideAfter = !activeItem.presHideAfter; - Array.from(this._selectedArray.keys()).forEach((doc) => doc.presHideAfter = activeItem.presHideAfter); - } + Array.from(this._selectedArray.keys()).forEach(doc => (doc.presHideAfter = activeItem.presHideAfter)); + }; @undoBatch @action updateOpenDoc = (activeItem: Doc) => { activeItem.openDocument = !activeItem.openDocument; - Array.from(this._selectedArray.keys()).forEach((doc) => { + Array.from(this._selectedArray.keys()).forEach(doc => { doc.openDocument = activeItem.openDocument; }); - } + }; @undoBatch @action updateEffectDirection = (effect: any, all?: boolean) => { const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys()); - array.forEach((doc) => { - const tagDoc = doc;// Cast(doc.presentationTargetDoc, Doc, null); + array.forEach(doc => { + const tagDoc = doc; // Cast(doc.presentationTargetDoc, Doc, null); switch (effect) { case PresEffect.Left: tagDoc.presEffectDirection = PresEffect.Left; @@ -1130,19 +1207,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { case PresEffect.Bottom: tagDoc.presEffectDirection = PresEffect.Bottom; break; - case PresEffect.Center: default: + case PresEffect.Center: + default: tagDoc.presEffectDirection = PresEffect.Center; break; } }); - } + }; @undoBatch @action updateEffect = (effect: any, all?: boolean) => { const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys()); - array.forEach((doc) => { - const tagDoc = doc;//Cast(doc.presentationTargetDoc, Doc, null); + array.forEach(doc => { + const tagDoc = doc; //Cast(doc.presentationTargetDoc, Doc, null); switch (effect) { case PresEffect.Bounce: tagDoc.presEffect = PresEffect.Bounce; @@ -1159,19 +1237,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { case PresEffect.Rotate: tagDoc.presEffect = PresEffect.Rotate; break; - case PresEffect.None: default: + case PresEffect.None: + default: tagDoc.presEffect = PresEffect.None; break; } }); - } + }; _batch: UndoManager.Batch | undefined = undefined; @computed get transitionDropdown() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - const isPresCollection: boolean = (targetDoc === this.layoutDoc.presCollection); + const isPresCollection: boolean = targetDoc === this.layoutDoc.presCollection; const isPinWithView: boolean = BoolCast(activeItem.presPinView); if (activeItem && targetDoc) { const type = targetDoc.type; @@ -1182,155 +1261,301 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const effect = this.activeItem.presEffect ? this.activeItem.presEffect : 'None'; activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom'; return ( - <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === PresStatus.Edit ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = false; this.openEffectDropdown = false; })}> + <div + className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === PresStatus.Edit ? 'active' : ''}`} + onPointerDown={e => e.stopPropagation()} + onPointerUp={e => e.stopPropagation()} + onClick={action(e => { + e.stopPropagation(); + this.openMovementDropdown = false; + this.openEffectDropdown = false; + })}> <div className="ribbon-box"> Movement - {isPresCollection || (isPresCollection && isPinWithView) ? + {isPresCollection || (isPresCollection && isPinWithView) ? ( <div className="ribbon-property" style={{ marginLeft: 0, height: 25, textAlign: 'left', paddingLeft: 5, paddingRight: 5, fontSize: 10 }}> - {this.scrollable ? "Scroll to pinned view" : !isPinWithView ? "No movement" : "Pan & Zoom to pinned view"} + {this.scrollable ? 'Scroll to pinned view' : !isPinWithView ? 'No movement' : 'Pan & Zoom to pinned view'} </div> - : - <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown; })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}> + ) : ( + <div + className="presBox-dropdown" + onClick={action(e => { + e.stopPropagation(); + this.openMovementDropdown = !this.openMovementDropdown; + })} + style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}> {this.setMovementName(activeItem.presMovement, activeItem)} - <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openMovementDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={"angle-down"} /> - <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onPointerDown={e => e.stopPropagation()} style={{ display: this.openMovementDropdown ? "grid" : "none" }}> - <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.None ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.None)}>None</div> - <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Zoom ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Zoom)}>Pan {"&"} Zoom</div> - <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Pan ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Pan)}>Pan</div> - <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Jump ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Jump)}>Jump cut</div> + <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this.openMovementDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} /> + <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onPointerDown={e => e.stopPropagation()} style={{ display: this.openMovementDropdown ? 'grid' : 'none' }}> + <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.None ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.None)}> + None + </div> + <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Zoom ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Zoom)}> + Pan {'&'} Zoom + </div> + <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Pan ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Pan)}> + Pan + </div> + <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Jump ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Jump)}> + Jump cut + </div> </div> </div> - } - <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Zoom ? "inline-flex" : "none" }}> + )} + <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Zoom ? 'inline-flex' : 'none' }}> <div className="presBox-subheading">Zoom (% screen filled)</div> <div className="ribbon-property"> - <input className="presBox-input" - type="number" value={zoom} - onChange={action((e) => this.setZoom(e.target.value))} />% + <input className="presBox-input" type="number" value={zoom} onChange={action(e => this.setZoom(e.target.value))} />% </div> <div className="ribbon-propertyUpDown"> <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), 0.1))}> - <FontAwesomeIcon icon={"caret-up"} /> + <FontAwesomeIcon icon={'caret-up'} /> </div> <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), -0.1))}> - <FontAwesomeIcon icon={"caret-down"} /> + <FontAwesomeIcon icon={'caret-down'} /> </div> </div> </div> - <input type="range" step="1" min="0" max="150" value={zoom} - className={`toolbar-slider ${activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`} + <input + type="range" + step="1" + min="0" + max="150" + value={zoom} + className={`toolbar-slider ${activeItem.presMovement === PresMovement.Zoom ? '' : 'none'}`} id="toolbar-slider" - onPointerDown={() => this._batch = UndoManager.StartBatch("presZoom")} + onPointerDown={() => (this._batch = UndoManager.StartBatch('presZoom'))} onPointerUp={() => this._batch?.end()} onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setZoom(e.target.value); - }} /> - <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "inline-flex" : "none" }}> + }} + /> + <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? 'inline-flex' : 'none' }}> <div className="presBox-subheading">Movement Speed</div> <div className="ribbon-property"> - <input className="presBox-input" - type="number" value={transitionSpeed} - onKeyDown={e => e.stopPropagation()} - onChange={action((e) => this.setTransitionTime(e.target.value))} /> s + <input className="presBox-input" type="number" value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.setTransitionTime(e.target.value))} /> s </div> <div className="ribbon-propertyUpDown"> <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setTransitionTime(String(transitionSpeed), 1000))}> - <FontAwesomeIcon icon={"caret-up"} /> + <FontAwesomeIcon icon={'caret-up'} /> </div> <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setTransitionTime(String(transitionSpeed), -1000))}> - <FontAwesomeIcon icon={"caret-down"} /> + <FontAwesomeIcon icon={'caret-down'} /> </div> </div> </div> - <input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed} - className={`toolbar-slider ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`} + <input + type="range" + step="0.1" + min="0.1" + max="10" + value={transitionSpeed} + className={`toolbar-slider ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? '' : 'none'}`} id="toolbar-slider" - onPointerDown={() => this._batch = UndoManager.StartBatch("presTransition")} + onPointerDown={() => (this._batch = UndoManager.StartBatch('presTransition'))} onPointerUp={() => this._batch?.end()} onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setTransitionTime(e.target.value); - }} /> - <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}> + }} + /> + <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? '' : 'none'}`}> <div className="slider-text">Fast</div> <div className="slider-text">Medium</div> <div className="slider-text">Slow</div> </div> </div> <div className="ribbon-box"> - Visibility {"&"} Duration + Visibility {'&'} Duration <div className="ribbon-doubleButton"> - {isPresCollection ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Hide before presented"}</div></>}><div className={`ribbon-toggle ${activeItem.presHideBefore ? "active" : ""}`} onClick={() => this.updateHideBefore(activeItem)}>Hide before</div></Tooltip>} - {isPresCollection ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Hide after presented"}</div></>}><div className={`ribbon-toggle ${activeItem.presHideAfter ? "active" : ""}`} onClick={() => this.updateHideAfter(activeItem)}>Hide after</div></Tooltip>} - <Tooltip title={<><div className="dash-tooltip">{"Open in lightbox view"}</div></>}><div className="ribbon-toggle" style={{ backgroundColor: activeItem.openDocument ? Colors.LIGHT_BLUE : "" }} onClick={() => this.updateOpenDoc(activeItem)}>Lightbox</div></Tooltip> + {isPresCollection ? null : ( + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Hide before presented'}</div> + </> + }> + <div className={`ribbon-toggle ${activeItem.presHideBefore ? 'active' : ''}`} onClick={() => this.updateHideBefore(activeItem)}> + Hide before + </div> + </Tooltip> + )} + {isPresCollection ? null : ( + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Hide after presented'}</div> + </> + }> + <div className={`ribbon-toggle ${activeItem.presHideAfter ? 'active' : ''}`} onClick={() => this.updateHideAfter(activeItem)}> + Hide after + </div> + </Tooltip> + )} + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Open in lightbox view'}</div> + </> + }> + <div className="ribbon-toggle" style={{ backgroundColor: activeItem.openDocument ? Colors.LIGHT_BLUE : '' }} onClick={() => this.updateOpenDoc(activeItem)}> + Lightbox + </div> + </Tooltip> </div> - {(type === DocumentType.AUDIO || type === DocumentType.VID) ? (null) : <> - <div className="ribbon-doubleButton" > - <div className="presBox-subheading">Slide Duration</div> - <div className="ribbon-property"> - <input className="presBox-input" - type="number" value={duration} - onKeyDown={e => e.stopPropagation()} - onChange={action((e) => this.setDurationTime(e.target.value))} /> s + {type === DocumentType.AUDIO || type === DocumentType.VID ? null : ( + <> + <div className="ribbon-doubleButton"> + <div className="presBox-subheading">Slide Duration</div> + <div className="ribbon-property"> + <input className="presBox-input" type="number" value={duration} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.setDurationTime(e.target.value))} /> s + </div> + <div className="ribbon-propertyUpDown"> + <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), 1000))}> + <FontAwesomeIcon icon={'caret-up'} /> + </div> + <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), -1000))}> + <FontAwesomeIcon icon={'caret-down'} /> + </div> + </div> + </div> + <input + type="range" + step="0.1" + min="0.1" + max="20" + value={duration} + style={{ display: targetDoc.type === DocumentType.AUDIO ? 'none' : 'block' }} + className={'toolbar-slider'} + id="duration-slider" + onPointerDown={() => { + this._batch = UndoManager.StartBatch('presDuration'); + }} + onPointerUp={() => { + if (this._batch) this._batch.end(); + }} + onChange={(e: React.ChangeEvent<HTMLInputElement>) => { + e.stopPropagation(); + this.setDurationTime(e.target.value); + }} + /> + <div className={'slider-headers'} style={{ display: targetDoc.type === DocumentType.AUDIO ? 'none' : 'grid' }}> + <div className="slider-text">Short</div> + <div className="slider-text">Medium</div> + <div className="slider-text">Long</div> </div> - <div className="ribbon-propertyUpDown"> - <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), 1000))}> - <FontAwesomeIcon icon={"caret-up"} /> + </> + )} + </div> + {isPresCollection ? null : ( + <div className="ribbon-box"> + Effects + <div + className="presBox-dropdown" + onClick={action(e => { + e.stopPropagation(); + this.openEffectDropdown = !this.openEffectDropdown; + })} + style={{ borderBottomLeftRadius: this.openEffectDropdown ? 0 : 5, border: this.openEffectDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}> + {effect.toString()} + <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this.openEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} /> + <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} style={{ display: this.openEffectDropdown ? 'grid' : 'none' }} onPointerDown={e => e.stopPropagation()}> + <div + className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.None || !this.activeItem.presEffect ? 'active' : ''}`} + onPointerDown={e => e.stopPropagation()} + onClick={() => this.updateEffect(PresEffect.None)}> + None </div> - <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), -1000))}> - <FontAwesomeIcon icon={"caret-down"} /> + <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Fade ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Fade)}> + Fade In + </div> + <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Flip ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Flip)}> + Flip + </div> + <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Rotate ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Rotate)}> + Rotate + </div> + <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Bounce ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Bounce)}> + Bounce + </div> + <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Roll ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Roll)}> + Roll </div> </div> </div> - <input type="range" step="0.1" min="0.1" max="20" value={duration} - style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "block" }} - className={"toolbar-slider"} id="duration-slider" - onPointerDown={() => { this._batch = UndoManager.StartBatch("presDuration"); }} - onPointerUp={() => { if (this._batch) this._batch.end(); }} - onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} - /> - <div className={"slider-headers"} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "grid" }}> - <div className="slider-text">Short</div> - <div className="slider-text">Medium</div> - <div className="slider-text">Long</div> + <div className="ribbon-doubleButton" style={{ display: effect === 'None' ? 'none' : 'inline-flex' }}> + <div className="presBox-subheading">Effect direction</div> + <div className="ribbon-property">{this.effectDirection}</div> </div> - </>} - </div> - {isPresCollection ? (null) : <div className="ribbon-box"> - Effects - <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openEffectDropdown = !this.openEffectDropdown; })} style={{ borderBottomLeftRadius: this.openEffectDropdown ? 0 : 5, border: this.openEffectDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}> - {effect} - <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={"angle-down"} /> - <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} style={{ display: this.openEffectDropdown ? "grid" : "none" }} onPointerDown={e => e.stopPropagation()}> - <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.None || !this.activeItem.presEffect ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.None)}>None</div> - <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Fade ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Fade)}>Fade In</div> - <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Flip ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Flip)}>Flip</div> - <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Rotate ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Rotate)}>Rotate</div> - <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Bounce ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Bounce)}>Bounce</div> - <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Roll ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Roll)}>Roll</div> - </div> - </div> - <div className="ribbon-doubleButton" style={{ display: effect === 'None' ? "none" : "inline-flex" }}> - <div className="presBox-subheading" >Effect direction</div> - <div className="ribbon-property"> - {this.effectDirection} + <div className="effectDirection" style={{ display: effect === 'None' ? 'none' : 'grid', width: 40 }}> + <Tooltip title={<div className="dash-tooltip">{'Enter from left'}</div>}> + <div + style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Left ? Colors.LIGHT_BLUE : 'black', cursor: 'pointer' }} + onClick={() => this.updateEffectDirection(PresEffect.Left)}> + <FontAwesomeIcon icon={'angle-right'} /> + </div> + </Tooltip> + <Tooltip title={<div className="dash-tooltip">{'Enter from right'}</div>}> + <div + style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Right ? Colors.LIGHT_BLUE : 'black', cursor: 'pointer' }} + onClick={() => this.updateEffectDirection(PresEffect.Right)}> + <FontAwesomeIcon icon={'angle-left'} /> + </div> + </Tooltip> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Enter from top'}</div> + </> + }> + <div + style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Top ? Colors.LIGHT_BLUE : 'black', cursor: 'pointer' }} + onClick={() => this.updateEffectDirection(PresEffect.Top)}> + <FontAwesomeIcon icon={'angle-down'} /> + </div> + </Tooltip> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Enter from bottom'}</div> + </> + }> + <div + style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Bottom ? Colors.LIGHT_BLUE : 'black', cursor: 'pointer' }} + onClick={() => this.updateEffectDirection(PresEffect.Bottom)}> + <FontAwesomeIcon icon={'angle-up'} /> + </div> + </Tooltip> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Enter from center'}</div> + </> + }> + <div + style={{ + gridColumn: 2, + gridRow: 2, + width: 10, + height: 10, + alignSelf: 'center', + justifySelf: 'center', + border: this.activeItem.presEffectDirection === PresEffect.Center || !this.activeItem.presEffectDirection ? `solid 2px ${Colors.LIGHT_BLUE}` : 'solid 2px black', + borderRadius: '100%', + cursor: 'pointer', + }} + onClick={() => this.updateEffectDirection(PresEffect.Center)}></div> + </Tooltip> </div> </div> - <div className="effectDirection" style={{ display: effect === 'None' ? "none" : "grid", width: 40 }}> - <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Left ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Left)}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip> - <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Right ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Right)}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip> - <Tooltip title={<><div className="dash-tooltip">{"Enter from top"}</div></>}><div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Top ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Top)}><FontAwesomeIcon icon={"angle-down"} /></div></Tooltip> - <Tooltip title={<><div className="dash-tooltip">{"Enter from bottom"}</div></>}><div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Bottom ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Bottom)}><FontAwesomeIcon icon={"angle-up"} /></div></Tooltip> - <Tooltip title={<><div className="dash-tooltip">{"Enter from center"}</div></>}><div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: this.activeItem.presEffectDirection === PresEffect.Center || !this.activeItem.presEffectDirection ? `solid 2px ${Colors.LIGHT_BLUE}` : "solid 2px black", borderRadius: "100%", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Center)}></div></Tooltip> - </div> - </div>} + )} <div className="ribbon-final-box"> <div className="ribbon-final-button-hidden" onClick={() => this.applyTo(this.childDocs)}> Apply to all </div> </div> - </div > + </div> ); } } @@ -1338,11 +1563,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @computed get effectDirection(): string { let effect = ''; switch (this.activeItem.presEffectDirection) { - case 'left': effect = "Enter from left"; break; - case 'right': effect = "Enter from right"; break; - case 'top': effect = "Enter from top"; break; - case 'bottom': effect = "Enter from bottom"; break; - default: effect = "Enter from center"; break; + case 'left': + effect = 'Enter from left'; + break; + case 'right': + effect = 'Enter from right'; + break; + case 'top': + effect = 'Enter from top'; + break; + case 'bottom': + effect = 'Enter from bottom'; + break; + default: + effect = 'Enter from center'; + break; } return effect; } @@ -1355,7 +1590,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this.updateMovement(activeItem.presMovement, true); this.updateEffect(activeItem.presEffect, true); this.updateEffectDirection(activeItem.presEffectDirection, true); - array.forEach((doc) => { + array.forEach(doc => { const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); if (tagDoc && targetDoc) { @@ -1365,63 +1600,86 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { curDoc.presHideAfter = activeItem.presHideAfter; } }); - } + }; @computed get presPinViewOptionsDropdown() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: "auto", width: 16, filter: 'invert(1)' }} />; + const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: 'auto', width: 16, filter: 'invert(1)' }} />; return ( <> - {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : (null)} + {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : null} <div className="ribbon-doubleButton"> - <Tooltip title={<><div className="dash-tooltip">{activeItem.presPinView ? "Turn off pin with view" : "Turn on pin with view"}</div></>}><div className="ribbon-toggle" style={{ width: 20, padding: 0, backgroundColor: activeItem.presPinView ? Colors.LIGHT_BLUE : "" }} - onClick={() => { - activeItem.presPinView = !activeItem.presPinView; - targetDoc.presPinView = activeItem.presPinView; - if (activeItem.presPinView) { - if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { - const scroll = targetDoc._scrollTop; - activeItem.presPinView = true; - activeItem.presPinViewScroll = scroll; - } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) { - activeItem.presStartTime = targetDoc._currentTimecode; - activeItem.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1; - } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) { - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - activeItem.presPinView = true; - activeItem.presPinViewX = x; - activeItem.presPinViewY = y; - activeItem.presPinViewScale = scale; - } else if (targetDoc.type === DocumentType.COMPARISON) { - const width = targetDoc._clipWidth; - activeItem.presPinClipWidth = width; - activeItem.presPinView = true; + <Tooltip + title={ + <> + <div className="dash-tooltip">{activeItem.presPinView ? 'Turn off pin with view' : 'Turn on pin with view'}</div> + </> + }> + <div + className="ribbon-toggle" + style={{ width: 20, padding: 0, backgroundColor: activeItem.presPinView ? Colors.LIGHT_BLUE : '' }} + onClick={() => { + activeItem.presPinView = !activeItem.presPinView; + targetDoc.presPinView = activeItem.presPinView; + if (activeItem.presPinView) { + if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { + const scroll = targetDoc._scrollTop; + activeItem.presPinView = true; + activeItem.presPinViewScroll = scroll; + } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) { + activeItem.presStartTime = targetDoc._currentTimecode; + activeItem.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1; + } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) { + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + activeItem.presPinView = true; + activeItem.presPinViewX = x; + activeItem.presPinViewY = y; + activeItem.presPinViewScale = scale; + } else if (targetDoc.type === DocumentType.COMPARISON) { + const width = targetDoc._clipWidth; + activeItem.presPinClipWidth = width; + activeItem.presPinView = true; + } } - } - }}>{presPinWithViewIcon}</div></Tooltip> - {activeItem.presPinView ? <Tooltip title={<><div className="dash-tooltip">{"Update the pinned view with the view of the selected document"}</div></>}><div className="ribbon-button" - onClick={() => { - if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) { - const scroll = targetDoc._scrollTop; - activeItem.presPinViewScroll = scroll; - } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) { - activeItem.presStartTime = targetDoc._currentTimecode; - activeItem.presStartTime = NumCast(targetDoc._currentTimecode) + 0.1; - } else if (targetDoc.type === DocumentType.COMPARISON) { - const clipWidth = targetDoc._clipWidth; - activeItem.presPinClipWidth = clipWidth; - } else { - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - activeItem.presPinViewX = x; - activeItem.presPinViewY = y; - activeItem.presPinViewScale = scale; - } - }}>Update</div></Tooltip> : (null)} + }}> + {presPinWithViewIcon} + </div> + </Tooltip> + {activeItem.presPinView ? ( + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Update the pinned view with the view of the selected document'}</div> + </> + }> + <div + className="ribbon-button" + onClick={() => { + if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) { + const scroll = targetDoc._scrollTop; + activeItem.presPinViewScroll = scroll; + } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) { + activeItem.presStartTime = targetDoc._currentTimecode; + activeItem.presStartTime = NumCast(targetDoc._currentTimecode) + 0.1; + } else if (targetDoc.type === DocumentType.COMPARISON) { + const clipWidth = targetDoc._clipWidth; + activeItem.presPinClipWidth = clipWidth; + } else { + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + activeItem.presPinViewX = x; + activeItem.presPinViewY = y; + activeItem.presPinViewScale = scale; + } + }}> + Update + </div> + </Tooltip> + ) : null} </div> </> ); @@ -1432,38 +1690,58 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const targetDoc: Doc = this.targetDoc; return ( <> - {this.panable ? <div style={{ display: activeItem.presPinView ? "block" : "none" }}> - <div className="ribbon-doubleButton" style={{ marginRight: 10 }}> - <div className="presBox-subheading">Pan X</div> - <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}> - <input className="presBox-input" - style={{ textAlign: 'left', width: 50 }} - type="number" value={NumCast(activeItem.presPinViewX)} - onKeyDown={e => e.stopPropagation()} - onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewX = Number(val); })} /> + {this.panable ? ( + <div style={{ display: activeItem.presPinView ? 'block' : 'none' }}> + <div className="ribbon-doubleButton" style={{ marginRight: 10 }}> + <div className="presBox-subheading">Pan X</div> + <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}> + <input + className="presBox-input" + style={{ textAlign: 'left', width: 50 }} + type="number" + value={NumCast(activeItem.presPinViewX)} + onKeyDown={e => e.stopPropagation()} + onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { + const val = e.target.value; + activeItem.presPinViewX = Number(val); + })} + /> + </div> </div> - </div> - <div className="ribbon-doubleButton" style={{ marginRight: 10 }}> - <div className="presBox-subheading">Pan Y</div> - <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}> - <input className="presBox-input" - style={{ textAlign: 'left', width: 50 }} - type="number" value={NumCast(activeItem.presPinViewY)} - onKeyDown={e => e.stopPropagation()} - onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewY = Number(val); })} /> + <div className="ribbon-doubleButton" style={{ marginRight: 10 }}> + <div className="presBox-subheading">Pan Y</div> + <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}> + <input + className="presBox-input" + style={{ textAlign: 'left', width: 50 }} + type="number" + value={NumCast(activeItem.presPinViewY)} + onKeyDown={e => e.stopPropagation()} + onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { + const val = e.target.value; + activeItem.presPinViewY = Number(val); + })} + /> + </div> </div> - </div> - <div className="ribbon-doubleButton" style={{ marginRight: 10 }}> - <div className="presBox-subheading">Scale</div> - <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}> - <input className="presBox-input" - style={{ textAlign: 'left', width: 50 }} - type="number" value={NumCast(activeItem.presPinViewScale)} - onKeyDown={e => e.stopPropagation()} - onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewScale = Number(val); })} /> + <div className="ribbon-doubleButton" style={{ marginRight: 10 }}> + <div className="presBox-subheading">Scale</div> + <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}> + <input + className="presBox-input" + style={{ textAlign: 'left', width: 50 }} + type="number" + value={NumCast(activeItem.presPinViewScale)} + onKeyDown={e => e.stopPropagation()} + onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { + const val = e.target.value; + activeItem.presPinViewScale = Number(val); + })} + /> + </div> </div> </div> - </div> : (null)} + ) : null} </> ); } @@ -1473,18 +1751,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const targetDoc: Doc = this.targetDoc; return ( <> - {this.scrollable ? <div style={{ display: activeItem.presPinView ? "block" : "none" }}> - <div className="ribbon-doubleButton" style={{ marginRight: 10 }}> - <div className="presBox-subheading">Scroll</div> - <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}> - <input className="presBox-input" - style={{ textAlign: 'left', width: 50 }} - type="number" value={NumCast(activeItem.presPinViewScroll)} - onKeyDown={e => e.stopPropagation()} - onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewScroll = Number(val); })} /> + {this.scrollable ? ( + <div style={{ display: activeItem.presPinView ? 'block' : 'none' }}> + <div className="ribbon-doubleButton" style={{ marginRight: 10 }}> + <div className="presBox-subheading">Scroll</div> + <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}> + <input + className="presBox-input" + style={{ textAlign: 'left', width: 50 }} + type="number" + value={NumCast(activeItem.presPinViewScroll)} + onKeyDown={e => e.stopPropagation()} + onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { + const val = e.target.value; + activeItem.presPinViewScroll = Number(val); + })} + /> + </div> </div> </div> - </div> : (null)} + ) : null} </> ); } @@ -1494,13 +1780,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const list = this.childDocs.map((doc, i) => { if (i > this.itemIndex) { return ( - <option>{i + 1}. {doc.title}</option> + <option> + {i + 1}. {StrCast(doc.title)} + </option> ); } }); - return ( - list - ); + return list; } @computed get mediaOptionsDropdown() { @@ -1510,25 +1796,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const clipEnd: number = NumCast(activeItem.clipEnd); const duration = Math.round(NumCast(activeItem[`${Doc.LayoutFieldKey(activeItem)}-duration`]) * 10); const mediaStopDocInd: number = NumCast(activeItem.mediaStopDoc); - const mediaStopDocStr: string = mediaStopDocInd ? mediaStopDocInd + ". " + this.childDocs[mediaStopDocInd - 1].title : ""; + const mediaStopDocStr: string = mediaStopDocInd ? mediaStopDocInd + '. ' + this.childDocs[mediaStopDocInd - 1].title : ''; if (activeItem && targetDoc) { return ( <div> <div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> <div> <div className="ribbon-box"> - Start {"&"} End Time - <div className={"slider-headers"}> - <div className="slider-block" > + Start {'&'} End Time + <div className={'slider-headers'}> + <div className="slider-block"> <div className="slider-text" style={{ fontWeight: 500 }}> Start time (s) </div> - <div id={"startTime"} className="slider-number" style={{ backgroundColor: Colors.LIGHT_GRAY }}> - <input className="presBox-input" + <div id={'startTime'} className="slider-number" style={{ backgroundColor: Colors.LIGHT_GRAY }}> + <input + className="presBox-input" style={{ textAlign: 'center', width: 30, height: 15, fontSize: 10 }} - type="number" value={NumCast(activeItem.presStartTime)} + type="number" + value={NumCast(activeItem.presStartTime)} onKeyDown={e => e.stopPropagation()} - onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { activeItem.presStartTime = Number(e.target.value); })} + onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { + activeItem.presStartTime = Number(e.target.value); + })} /> </div> </div> @@ -1544,24 +1834,33 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="slider-text" style={{ fontWeight: 500 }}> End time (s) </div> - <div id={"endTime"} className="slider-number" style={{ backgroundColor: Colors.LIGHT_GRAY }}> - <input className="presBox-input" + <div id={'endTime'} className="slider-number" style={{ backgroundColor: Colors.LIGHT_GRAY }}> + <input + className="presBox-input" onKeyDown={e => e.stopPropagation()} style={{ textAlign: 'center', width: 30, height: 15, fontSize: 10 }} - type="number" value={NumCast(activeItem.presEndTime)} - onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { activeItem.presEndTime = Number(e.target.value); })} + type="number" + value={NumCast(activeItem.presEndTime)} + onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { + activeItem.presEndTime = Number(e.target.value); + })} /> </div> </div> </div> <div className="multiThumb-slider"> - <input type="range" step="0.1" min={clipStart} max={clipEnd} value={NumCast(activeItem.presEndTime)} + <input + type="range" + step="0.1" + min={clipStart} + max={clipEnd} + value={NumCast(activeItem.presEndTime)} style={{ gridColumn: 1, gridRow: 1 }} - className={`toolbar-slider ${"end"}`} + className={`toolbar-slider ${'end'}`} id="toolbar-slider" onPointerDown={() => { - this._batch = UndoManager.StartBatch("presEndTime"); - const endBlock = document.getElementById("endTime"); + this._batch = UndoManager.StartBatch('presEndTime'); + const endBlock = document.getElementById('endTime'); if (endBlock) { endBlock.style.color = Colors.LIGHT_GRAY; endBlock.style.backgroundColor = Colors.MEDIUM_BLUE; @@ -1569,7 +1868,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }} onPointerUp={() => { this._batch?.end(); - const endBlock = document.getElementById("endTime"); + const endBlock = document.getElementById('endTime'); if (endBlock) { endBlock.style.color = Colors.BLACK; endBlock.style.backgroundColor = Colors.LIGHT_GRAY; @@ -1578,14 +1877,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); activeItem.presEndTime = Number(e.target.value); - }} /> - <input type="range" step="0.1" min={clipStart} max={clipEnd} value={NumCast(activeItem.presStartTime)} + }} + /> + <input + type="range" + step="0.1" + min={clipStart} + max={clipEnd} + value={NumCast(activeItem.presStartTime)} style={{ gridColumn: 1, gridRow: 1 }} - className={`toolbar-slider ${"start"}`} + className={`toolbar-slider ${'start'}`} id="toolbar-slider" onPointerDown={() => { - this._batch = UndoManager.StartBatch("presStartTime"); - const startBlock = document.getElementById("startTime"); + this._batch = UndoManager.StartBatch('presStartTime'); + const startBlock = document.getElementById('startTime'); if (startBlock) { startBlock.style.color = Colors.LIGHT_GRAY; startBlock.style.backgroundColor = Colors.MEDIUM_BLUE; @@ -1593,7 +1898,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }} onPointerUp={() => { this._batch?.end(); - const startBlock = document.getElementById("startTime"); + const startBlock = document.getElementById('startTime'); if (startBlock) { startBlock.style.color = Colors.BLACK; startBlock.style.backgroundColor = Colors.LIGHT_GRAY; @@ -1602,9 +1907,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); activeItem.presStartTime = Number(e.target.value); - }} /> + }} + /> </div> - <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}> + <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? '' : 'none'}`}> <div className="slider-text">{clipStart} s</div> <div className="slider-text"></div> <div className="slider-text">{clipEnd} s</div> @@ -1615,38 +1921,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="presBox-subheading">Start playing:</div> <div className="presBox-radioButtons"> <div className="checkbox-container"> - <input className="presBox-checkbox" - type="checkbox" - onChange={() => activeItem.mediaStart = "manual"} - checked={activeItem.mediaStart === "manual"} - /> + <input className="presBox-checkbox" type="checkbox" onChange={() => (activeItem.mediaStart = 'manual')} checked={activeItem.mediaStart === 'manual'} /> <div>On click</div> </div> <div className="checkbox-container"> - <input className="presBox-checkbox" - type="checkbox" - onChange={() => activeItem.mediaStart = "auto"} - checked={activeItem.mediaStart === "auto"} - /> + <input className="presBox-checkbox" type="checkbox" onChange={() => (activeItem.mediaStart = 'auto')} checked={activeItem.mediaStart === 'auto'} /> <div>Automatically</div> </div> </div> <div className="presBox-subheading">Stop playing:</div> <div className="presBox-radioButtons"> <div className="checkbox-container"> - <input className="presBox-checkbox" - type="checkbox" - onChange={() => activeItem.mediaStop = "manual"} - checked={activeItem.mediaStop === "manual"} - /> + <input className="presBox-checkbox" type="checkbox" onChange={() => (activeItem.mediaStop = 'manual')} checked={activeItem.mediaStop === 'manual'} /> <div>At audio end time</div> </div> <div className="checkbox-container"> - <input className="presBox-checkbox" - type="checkbox" - onChange={() => activeItem.mediaStop = "auto"} - checked={activeItem.mediaStop === "auto"} - /> + <input className="presBox-checkbox" type="checkbox" onChange={() => (activeItem.mediaStop = 'auto')} checked={activeItem.mediaStop === 'auto'} /> <div>On slide change</div> </div> {/* <div className="checkbox-container"> @@ -1670,7 +1960,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { </div> </div> </div> - </div > + </div> ); } } @@ -1678,84 +1968,137 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @computed get newDocumentToolbarDropdown() { return ( <div> - <div className={'presBox-toolbar-dropdown'} style={{ display: this.newDocumentTools && this.layoutDoc.presStatus === "edit" ? "inline-flex" : "none" }} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> + <div + className={'presBox-toolbar-dropdown'} + style={{ display: this.newDocumentTools && this.layoutDoc.presStatus === 'edit' ? 'inline-flex' : 'none' }} + onClick={e => e.stopPropagation()} + onPointerUp={e => e.stopPropagation()} + onPointerDown={e => e.stopPropagation()}> <div className="layout-container" style={{ height: 'max-content' }}> - <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'blank'; this.createNewSlide(this.layout); })} /> - <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'title'; this.createNewSlide(this.layout); })}> + <div + className="layout" + style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} + onClick={action(() => { + this.layout = 'blank'; + this.createNewSlide(this.layout); + })} + /> + <div + className="layout" + style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} + onClick={action(() => { + this.layout = 'title'; + this.createNewSlide(this.layout); + })}> <div className="title">Title</div> <div className="subtitle">Subtitle</div> </div> - <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'header'; this.createNewSlide(this.layout); })}> - <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div> + <div + className="layout" + style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} + onClick={action(() => { + this.layout = 'header'; + this.createNewSlide(this.layout); + })}> + <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}> + Section header + </div> </div> - <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'content'; this.createNewSlide(this.layout); })}> - <div className="title" style={{ alignSelf: 'center' }}>Title</div> + <div + className="layout" + style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} + onClick={action(() => { + this.layout = 'content'; + this.createNewSlide(this.layout); + })}> + <div className="title" style={{ alignSelf: 'center' }}> + Title + </div> <div className="content">Text goes here</div> </div> </div> </div> - </div > + </div> ); } @observable openLayouts: boolean = false; @observable addFreeform: boolean = true; - @observable layout: string = ""; - @observable title: string = ""; + @observable layout: string = ''; + @observable title: string = ''; @computed get newDocumentDropdown() { return ( <div> - <div className={"presBox-ribbon"} onClick={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> + <div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> <div className="ribbon-box"> Slide Title: <br></br> - <input className="ribbon-textInput" placeholder="..." type="text" name="fname" - onChange={(e) => { + <input + className="ribbon-textInput" + placeholder="..." + type="text" + name="fname" + onChange={e => { e.stopPropagation(); e.preventDefault(); - runInAction(() => this.title = e.target.value); - }}> - </input> + runInAction(() => (this.title = e.target.value)); + }}></input> </div> <div className="ribbon-box"> Choose type: <div className="ribbon-doubleButton"> - <div title="Text" className={'ribbon-toggle'} style={{ background: this.addFreeform ? "" : Colors.LIGHT_BLUE }} onClick={action(() => this.addFreeform = !this.addFreeform)}>Text</div> - <div title="Freeform" className={'ribbon-toggle'} style={{ background: this.addFreeform ? Colors.LIGHT_BLUE : "" }} onClick={action(() => this.addFreeform = !this.addFreeform)}>Freeform</div> + <div title="Text" className={'ribbon-toggle'} style={{ background: this.addFreeform ? '' : Colors.LIGHT_BLUE }} onClick={action(() => (this.addFreeform = !this.addFreeform))}> + Text + </div> + <div title="Freeform" className={'ribbon-toggle'} style={{ background: this.addFreeform ? Colors.LIGHT_BLUE : '' }} onClick={action(() => (this.addFreeform = !this.addFreeform))}> + Freeform + </div> </div> </div> - <div className="ribbon-box" style={{ display: this.addFreeform ? "grid" : "none" }}> + <div className="ribbon-box" style={{ display: this.addFreeform ? 'grid' : 'none' }}> Preset layouts: <div className="layout-container" style={{ height: this.openLayouts ? 'max-content' : '75px' }}> - <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'blank')} /> - <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'title')}> + <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'blank'))} /> + <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'title'))}> <div className="title">Title</div> <div className="subtitle">Subtitle</div> </div> - <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'header')}> - <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div> + <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'header'))}> + <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}> + Section header + </div> </div> - <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'content')}> - <div className="title" style={{ alignSelf: 'center' }}>Title</div> + <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'content'))}> + <div className="title" style={{ alignSelf: 'center' }}> + Title + </div> <div className="content">Text goes here</div> </div> - <div className="layout" style={{ border: this.layout === 'twoColumns' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'twoColumns')}> - <div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}>Title</div> - <div className="content" style={{ gridColumn: 1, gridRow: 2 }}>Column one text</div> - <div className="content" style={{ gridColumn: 2, gridRow: 2 }}>Column two text</div> + <div className="layout" style={{ border: this.layout === 'twoColumns' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'twoColumns'))}> + <div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}> + Title + </div> + <div className="content" style={{ gridColumn: 1, gridRow: 2 }}> + Column one text + </div> + <div className="content" style={{ gridColumn: 2, gridRow: 2 }}> + Column two text + </div> </div> </div> - <div className="open-layout" onClick={action(() => this.openLayouts = !this.openLayouts)}> - <FontAwesomeIcon style={{ transition: 'all 0.3s', transform: this.openLayouts ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"caret-down"} size={"lg"} /> + <div className="open-layout" onClick={action(() => (this.openLayouts = !this.openLayouts))}> + <FontAwesomeIcon style={{ transition: 'all 0.3s', transform: this.openLayouts ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={'caret-down'} size={'lg'} /> </div> </div> <div className="ribbon-final-box"> - <div className={this.title !== "" && (this.addFreeform && this.layout !== "" || !this.addFreeform) ? "ribbon-final-button-hidden" : "ribbon-final-button"} onClick={() => this.createNewSlide(this.layout, this.title, this.addFreeform)}> + <div + className={this.title !== '' && ((this.addFreeform && this.layout !== '') || !this.addFreeform) ? 'ribbon-final-button-hidden' : 'ribbon-final-button'} + onClick={() => this.createNewSlide(this.layout, this.title, this.addFreeform)}> Create New Slide </div> </div> </div> - </div > + </div> ); } @@ -1763,7 +2106,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { let doc = undefined; if (layout) doc = this.createTemplate(layout); if (freeform && layout) doc = this.createTemplate(layout, title); - if (!freeform && !layout) doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 225, title: title }); + if (!freeform && !layout) doc = Docs.Create.TextDocument('', { _nativeWidth: 400, _width: 225, title: title }); if (doc) { const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); const data = Cast(presCollection?.data, listSpec(Doc)); @@ -1773,10 +2116,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { TabDocView.PinDoc(doc); this.gotoDocument(this.childDocs.length, this.activeItem); } else { - this.props.addDocTab(doc, "add:right"); + this.props.addDocTab(doc, 'add:right'); } } - } + }; createTemplate = (layout: string, input?: string) => { const activeItem: Doc = this.activeItem; @@ -1788,43 +2131,59 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { y = NumCast(targetDoc.y) + NumCast(targetDoc._height) + 20; } let doc = undefined; - const title = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt", }); - const subtitle = Docs.Create.TextDocument("Click to change subtitle", { title: "Slide subtitle", _width: 380, _height: 50, x: 10, y: 118, _fontSize: "16pt" }); - const header = Docs.Create.TextDocument("Click to change header", { title: "Slide header", _width: 380, _height: 65, x: 10, y: 80, _fontSize: "20pt" }); - const contentTitle = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 10, _fontSize: "24pt" }); - const content = Docs.Create.TextDocument("Click to change text", { title: "Slide text", _width: 380, _height: 145, x: 10, y: 70, _fontSize: "14pt" }); - const content1 = Docs.Create.TextDocument("Click to change text", { title: "Column 1", _width: 185, _height: 140, x: 10, y: 80, _fontSize: "14pt" }); - const content2 = Docs.Create.TextDocument("Click to change text", { title: "Column 2", _width: 185, _height: 140, x: 205, y: 80, _fontSize: "14pt" }); + const title = Docs.Create.TextDocument('Click to change title', { title: 'Slide title', _width: 380, _height: 60, x: 10, y: 58, _fontSize: '24pt' }); + const subtitle = Docs.Create.TextDocument('Click to change subtitle', { title: 'Slide subtitle', _width: 380, _height: 50, x: 10, y: 118, _fontSize: '16pt' }); + const header = Docs.Create.TextDocument('Click to change header', { title: 'Slide header', _width: 380, _height: 65, x: 10, y: 80, _fontSize: '20pt' }); + const contentTitle = Docs.Create.TextDocument('Click to change title', { title: 'Slide title', _width: 380, _height: 60, x: 10, y: 10, _fontSize: '24pt' }); + const content = Docs.Create.TextDocument('Click to change text', { title: 'Slide text', _width: 380, _height: 145, x: 10, y: 70, _fontSize: '14pt' }); + const content1 = Docs.Create.TextDocument('Click to change text', { title: 'Column 1', _width: 185, _height: 140, x: 10, y: 80, _fontSize: '14pt' }); + const content2 = Docs.Create.TextDocument('Click to change text', { title: 'Column 2', _width: 185, _height: 140, x: 205, y: 80, _fontSize: '14pt' }); switch (layout) { case 'blank': - doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, x: x, y: y }); + doc = Docs.Create.FreeformDocument([], { title: input ? input : 'Blank slide', _width: 400, _height: 225, x: x, y: y }); break; case 'title': - doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); + doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : 'Title slide', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); break; case 'header': - doc = Docs.Create.FreeformDocument([header], { title: input ? input : "Section header", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); + doc = Docs.Create.FreeformDocument([header], { title: input ? input : 'Section header', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); break; case 'content': - doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : "Title and content", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); + doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : 'Title and content', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); break; case 'twoColumns': - doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); + doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : 'Title and two columns', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); break; default: break; } return doc; - } + }; // Dropdown that appears when the user wants to begin presenting (either minimize or sidebar view) @computed get presentDropdown() { return ( - <div className={`dropdown-play ${this.presentTools ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> - <div className="dropdown-play-button" onClick={undoBatch(action(() => { this.updateMinimize(); this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); }))}> + <div className={`dropdown-play ${this.presentTools ? 'active' : ''}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> + <div + className="dropdown-play-button" + onClick={undoBatch( + action(() => { + this.updateMinimize(); + this.turnOffEdit(true); + this.gotoDocument(this.itemIndex, this.activeItem); + }) + )}> Mini-player </div> - <div className="dropdown-play-button" onClick={undoBatch(action(() => { this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); }))}> + <div + className="dropdown-play-button" + onClick={undoBatch( + action(() => { + this.layoutDoc.presStatus = 'manual'; + this.turnOffEdit(true); + this.gotoDocument(this.itemIndex, this.activeItem); + }) + )}> Sidebar player </div> </div> @@ -1835,7 +2194,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @action nextKeyframe = (tagDoc: Doc, curDoc: Doc): void => { const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]); - const currentFrame = Cast(tagDoc._currentFrame, "number", null); + const currentFrame = Cast(tagDoc._currentFrame, 'number', null); if (currentFrame === undefined) { tagDoc._currentFrame = 0; // CollectionFreeFormDocumentView.setupScroll(tagDoc, 0); @@ -1845,19 +2204,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, tagDoc); tagDoc._currentFrame = Math.max(0, (currentFrame || 0) + 1); tagDoc.lastFrame = Math.max(NumCast(tagDoc._currentFrame), NumCast(tagDoc.lastFrame)); - } + }; @action prevKeyframe = (tagDoc: Doc, actItem: Doc): void => { const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]); - const currentFrame = Cast(tagDoc._currentFrame, "number", null); + const currentFrame = Cast(tagDoc._currentFrame, 'number', null); if (currentFrame === undefined) { tagDoc._currentFrame = 0; // CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0); } CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice()); tagDoc._currentFrame = Math.max(0, (currentFrame || 0) - 1); - } + }; /** * Returns the collection type as a string for headers @@ -1868,15 +2227,33 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { let type: string = ''; if (activeItem) { switch (targetDoc.type) { - case DocumentType.PDF: type = "PDF"; break; - case DocumentType.RTF: type = "Text node"; break; - case DocumentType.COL: type = "Collection"; break; - case DocumentType.AUDIO: type = "Audio"; break; - case DocumentType.VID: type = "Video"; break; - case DocumentType.IMG: type = "Image"; break; - case DocumentType.WEB: type = "Web page"; break; - case DocumentType.MAP: type = "Map"; break; - default: type = "Other node"; break; + case DocumentType.PDF: + type = 'PDF'; + break; + case DocumentType.RTF: + type = 'Text node'; + break; + case DocumentType.COL: + type = 'Collection'; + break; + case DocumentType.AUDIO: + type = 'Audio'; + break; + case DocumentType.VID: + type = 'Video'; + break; + case DocumentType.IMG: + type = 'Image'; + break; + case DocumentType.WEB: + type = 'Web page'; + break; + case DocumentType.MAP: + type = 'Map'; + break; + default: + type = 'Other node'; + break; } } return type; @@ -1885,66 +2262,122 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @observable private openActiveColorPicker: boolean = false; @observable private openViewedColorPicker: boolean = false; - - @computed get progressivizeDropdown() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; if (activeItem && targetDoc) { - const activeFontColor = targetDoc["pres-text-color"] ? StrCast(targetDoc["pres-text-color"]) : "Black"; - const viewedFontColor = targetDoc["pres-text-viewed-color"] ? StrCast(targetDoc["pres-text-viewed-color"]) : "Black"; + const activeFontColor = targetDoc['pres-text-color'] ? StrCast(targetDoc['pres-text-color']) : 'Black'; + const viewedFontColor = targetDoc['pres-text-viewed-color'] ? StrCast(targetDoc['pres-text-viewed-color']) : 'Black'; return ( <div> - <div className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> + <div + className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === 'edit' ? 'active' : ''}`} + onClick={e => e.stopPropagation()} + onPointerUp={e => e.stopPropagation()} + onPointerDown={e => e.stopPropagation()}> <div className="ribbon-box"> {this.stringType} selected - <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}> - <div className="ribbon-toggle" style={{ backgroundColor: activeItem.presProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.progressivizeChild}>Contents</div> - <div className="ribbon-toggle" style={{ opacity: activeItem.presProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.editProgressivize}>Edit</div> + <div + className="ribbon-doubleButton" + style={{ + borderTop: 'solid 1px darkgrey', + display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.RTF ? 'inline-flex' : 'none', + }}> + <div className="ribbon-toggle" style={{ backgroundColor: activeItem.presProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.progressivizeChild}> + Contents + </div> + <div className="ribbon-toggle" style={{ opacity: activeItem.presProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.editProgressivize}> + Edit + </div> </div> - <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? "inline-flex" : "none" }}> + <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? 'inline-flex' : 'none' }}> <div className="presBox-subheading">Active text color</div> - <div className="ribbon-colorBox" style={{ backgroundColor: activeFontColor, height: 15, width: 15 }} onClick={action(() => { this.openActiveColorPicker = !this.openActiveColorPicker; })}> - </div> + <div + className="ribbon-colorBox" + style={{ backgroundColor: activeFontColor, height: 15, width: 15 }} + onClick={action(() => { + this.openActiveColorPicker = !this.openActiveColorPicker; + })}></div> </div> {this.activeColorPicker} - <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? "inline-flex" : "none" }}> + <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? 'inline-flex' : 'none' }}> <div className="presBox-subheading">Viewed font color</div> - <div className="ribbon-colorBox" style={{ backgroundColor: viewedFontColor, height: 15, width: 15 }} onClick={action(() => this.openViewedColorPicker = !this.openViewedColorPicker)}> - </div> + <div className="ribbon-colorBox" style={{ backgroundColor: viewedFontColor, height: 15, width: 15 }} onClick={action(() => (this.openViewedColorPicker = !this.openViewedColorPicker))}></div> </div> {this.viewedColorPicker} - <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}> - <div className="ribbon-toggle" style={{ backgroundColor: activeItem.zoomProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.progressivizeZoom}>Zoom</div> - <div className="ribbon-toggle" style={{ opacity: activeItem.zoomProgressivize ? 1 : 0.4, backgroundColor: activeItem.editZoomProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.editZoomProgressivize}>Edit</div> + <div + className="ribbon-doubleButton" + style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? 'inline-flex' : 'none' }}> + <div className="ribbon-toggle" style={{ backgroundColor: activeItem.zoomProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.progressivizeZoom}> + Zoom + </div> + <div className="ribbon-toggle" style={{ opacity: activeItem.zoomProgressivize ? 1 : 0.4, backgroundColor: activeItem.editZoomProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.editZoomProgressivize}> + Edit + </div> </div> - <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: targetDoc._viewType === "stacking" || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}> - <div className="ribbon-toggle" style={{ backgroundColor: activeItem.scrollProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.progressivizeScroll}>Scroll</div> - <div className="ribbon-toggle" style={{ opacity: activeItem.scrollProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editScrollProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.editScrollProgressivize}>Edit</div> + <div + className="ribbon-doubleButton" + style={{ + borderTop: 'solid 1px darkgrey', + display: targetDoc._viewType === 'stacking' || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? 'inline-flex' : 'none', + }}> + <div className="ribbon-toggle" style={{ backgroundColor: activeItem.scrollProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.progressivizeScroll}> + Scroll + </div> + <div className="ribbon-toggle" style={{ opacity: activeItem.scrollProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editScrollProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.editScrollProgressivize}> + Edit + </div> </div> </div> <div className="ribbon-final-box"> Frames <div className="ribbon-doubleButton"> <div className="ribbon-frameSelector"> - <div key="back" title="back frame" className="backKeyframe" onClick={e => { e.stopPropagation(); this.prevKeyframe(targetDoc, activeItem); }}> - <FontAwesomeIcon icon={"caret-left"} size={"lg"} /> + <div + key="back" + title="back frame" + className="backKeyframe" + onClick={e => { + e.stopPropagation(); + this.prevKeyframe(targetDoc, activeItem); + }}> + <FontAwesomeIcon icon={'caret-left'} size={'lg'} /> </div> - <div key="num" title="toggle view all" className="numKeyframe" style={{ color: targetDoc.keyFrameEditing ? "white" : "black", backgroundColor: targetDoc.keyFrameEditing ? Colors.MEDIUM_BLUE : Colors.LIGHT_BLUE }} - onClick={action(() => targetDoc.keyFrameEditing = !targetDoc.keyFrameEditing)} > + <div + key="num" + title="toggle view all" + className="numKeyframe" + style={{ color: targetDoc.keyFrameEditing ? 'white' : 'black', backgroundColor: targetDoc.keyFrameEditing ? Colors.MEDIUM_BLUE : Colors.LIGHT_BLUE }} + onClick={action(() => (targetDoc.keyFrameEditing = !targetDoc.keyFrameEditing))}> {NumCast(targetDoc._currentFrame)} </div> - <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={e => { e.stopPropagation(); this.nextKeyframe(targetDoc, activeItem); }}> - <FontAwesomeIcon icon={"caret-right"} size={"lg"} /> + <div + key="fwd" + title="forward frame" + className="fwdKeyframe" + onClick={e => { + e.stopPropagation(); + this.nextKeyframe(targetDoc, activeItem); + }}> + <FontAwesomeIcon icon={'caret-right'} size={'lg'} /> </div> </div> - <Tooltip title={<><div className="dash-tooltip">{"Last frame"}</div></>}><div className="ribbon-property">{NumCast(targetDoc.lastFrame)}</div></Tooltip> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Last frame'}</div> + </> + }> + <div className="ribbon-property">{NumCast(targetDoc.lastFrame)}</div> + </Tooltip> </div> <div className="ribbon-frameList"> {this.frameListHeader} {this.frameList} </div> - <div className="ribbon-toggle" style={{ height: 20, backgroundColor: Colors.LIGHT_BLUE }} onClick={() => console.log(" TODO: play frames")}>Play</div> + <div className="ribbon-toggle" style={{ height: 20, backgroundColor: Colors.LIGHT_BLUE }} onClick={() => console.log(' TODO: play frames')}> + Play + </div> </div> </div> </div> @@ -1958,37 +2391,41 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; const val = String(color.hex); - targetDoc["pres-text-color"] = val; + targetDoc['pres-text-color'] = val; return true; - } + }; @undoBatch @action switchPresented = (color: ColorState) => { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; const val = String(color.hex); - targetDoc["pres-text-viewed-color"] = val; + targetDoc['pres-text-viewed-color'] = val; return true; - } + }; @computed get activeColorPicker() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - return !this.openActiveColorPicker ? (null) : <SketchPicker onChange={this.switchActive} - presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', - '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', - '#FFFFFF', '#f1efeb', 'transparent']} - color={StrCast(targetDoc["pres-text-color"])} />; + return !this.openActiveColorPicker ? null : ( + <SketchPicker + onChange={this.switchActive} + presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']} + color={StrCast(targetDoc['pres-text-color'])} + /> + ); } @computed get viewedColorPicker() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - return !this.openViewedColorPicker ? (null) : <SketchPicker onChange={this.switchPresented} - presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', - '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', - '#FFFFFF', '#f1efeb', 'transparent']} - color={StrCast(targetDoc["pres-text-viewed-color"])} />; + return !this.openViewedColorPicker ? null : ( + <SketchPicker + onChange={this.switchPresented} + presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']} + color={StrCast(targetDoc['pres-text-viewed-color'])} + /> + ); } @action @@ -1999,7 +2436,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (srcContext) this.togglePath(srcContext, true); } // Turn off the progressivize editors for each document - this.childDocs.forEach((doc) => { + this.childDocs.forEach(doc => { doc.editSnapZoomProgressivize = false; doc.editZoomProgressivize = false; const targetDoc = Cast(doc.presentationTargetDoc, Doc, null); @@ -2008,7 +2445,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // targetDoc.editScrollProgressivize = false; } }); - } + }; //Toggle whether the user edits or not @action @@ -2016,14 +2453,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; if (!targetDoc.editZoomProgressivize) { - if (!activeItem.zoomProgressivize) activeItem.zoomProgressivize = true; targetDoc.zoomProgressivize = true; + if (!activeItem.zoomProgressivize) activeItem.zoomProgressivize = true; + targetDoc.zoomProgressivize = true; targetDoc.editZoomProgressivize = true; activeItem.editZoomProgressivize = true; } else { targetDoc.editZoomProgressivize = false; activeItem.editZoomProgressivize = false; } - } + }; //Toggle whether the user edits or not @action @@ -2031,12 +2469,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; if (!targetDoc.editScrollProgressivize) { - if (!targetDoc.scrollProgressivize) { targetDoc.scrollProgressivize = true; activeItem.scrollProgressivize = true; } + if (!targetDoc.scrollProgressivize) { + targetDoc.scrollProgressivize = true; + activeItem.scrollProgressivize = true; + } targetDoc.editScrollProgressivize = true; } else { targetDoc.editScrollProgressivize = false; } - } + }; //Progressivize Zoom @action @@ -2052,7 +2493,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { targetDoc._currentFrame = 0; targetDoc.lastFrame = 0; } - } + }; //Progressivize Zoom @action @@ -2068,7 +2509,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { targetDoc._currentFrame = 0; targetDoc.lastFrame = 0; } - } + }; //Progressivize Child Docs @action @@ -2077,12 +2518,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const targetDoc: Doc = this.targetDoc; targetDoc._currentFrame = targetDoc.lastFrame; if (!targetDoc.editProgressivize) { - if (!activeItem.presProgressivize) { activeItem.presProgressivize = true; targetDoc.presProgressivize = true; } + if (!activeItem.presProgressivize) { + activeItem.presProgressivize = true; + targetDoc.presProgressivize = true; + } targetDoc.editProgressivize = true; } else { targetDoc.editProgressivize = false; } - } + }; @action progressivizeChild = (e: React.MouseEvent) => { @@ -2104,40 +2548,48 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { targetDoc._currentFrame = 0; targetDoc.keyFrameEditing = true; } - } + }; @action checkMovementLists = (doc: Doc, xlist: any, ylist: any) => { const x: List<number> = xlist; const y: List<number> = ylist; const tags: JSX.Element[] = []; - let pathPoints = ""; //List of all of the pathpoints that need to be added + let pathPoints = ''; //List of all of the pathpoints that need to be added for (let i = 0; i < x.length - 1; i++) { if (y[i] || x[i]) { - if (i === 0) pathPoints = (x[i] - 11) + "," + (y[i] + 33); - else pathPoints = pathPoints + " " + (x[i] - 11) + "," + (y[i] + 33); - tags.push(<div className="progressivizeMove-frame" style={{ position: 'absolute', top: y[i], left: x[i] }}>{i}</div>); + if (i === 0) pathPoints = x[i] - 11 + ',' + (y[i] + 33); + else pathPoints = pathPoints + ' ' + (x[i] - 11) + ',' + (y[i] + 33); + tags.push( + <div className="progressivizeMove-frame" style={{ position: 'absolute', top: y[i], left: x[i] }}> + {i} + </div> + ); } } - tags.push(<svg style={{ overflow: 'visible', position: 'absolute' }}><polyline - points={pathPoints} - style={{ - position: 'absolute', - opacity: 1, - stroke: "#000000", - strokeWidth: 2, - strokeDasharray: '10 5', - }} - fill="none" - /></svg>); + tags.push( + <svg style={{ overflow: 'visible', position: 'absolute' }}> + <polyline + points={pathPoints} + style={{ + position: 'absolute', + opacity: 1, + stroke: '#000000', + strokeWidth: 2, + strokeDasharray: '10 5', + }} + fill="none" + /> + </svg> + ); return tags; - } + }; @observable toggleDisplayMovement = (doc: Doc) => { if (doc.displayMovement) doc.displayMovement = false; else doc.displayMovement = true; - } + }; @action checkList = (doc: Doc, list: any): number => { @@ -2149,22 +2601,54 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { x[NumCast(doc._currentFrame)] = x[NumCast(doc._currentFrame) - 1]; return x[NumCast(doc._currentFrame)]; } else return 100; - } + }; @computed get progressivizeChildDocs() { const targetDoc: Doc = this.targetDoc; const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); const tags: JSX.Element[] = []; docs.forEach((doc, index) => { - if (doc["x-indexed"] && doc["y-indexed"]) { - tags.push(<div style={{ position: 'absolute', display: doc.displayMovement ? "block" : "none" }}>{this.checkMovementLists(doc, doc["x-indexed"], doc["y-indexed"])}</div>); + if (doc['x-indexed'] && doc['y-indexed']) { + tags.push(<div style={{ position: 'absolute', display: doc.displayMovement ? 'block' : 'none' }}>{this.checkMovementLists(doc, doc['x-indexed'], doc['y-indexed'])}</div>); } tags.push( - <div className="progressivizeButton" key={index} onPointerLeave={() => { if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0; }} onPointerOver={() => { if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5; }} onClick={e => { this.toggleDisplayMovement(doc); e.stopPropagation(); }} style={{ backgroundColor: doc.displayMovement ? Colors.LIGHT_BLUE : "#c8c8c8", top: NumCast(doc.y), left: NumCast(doc.x) }}> - <div className="progressivizeButton-prev"><FontAwesomeIcon icon={"caret-left"} size={"lg"} onClick={e => { e.stopPropagation(); this.prevAppearFrame(doc, index); }} /></div> - <div className="progressivizeButton-frame">{doc.appearFrame}</div> - <div className="progressivizeButton-next"><FontAwesomeIcon icon={"caret-right"} size={"lg"} onClick={e => { e.stopPropagation(); this.nextAppearFrame(doc, index); }} /></div> - </div>); + <div + className="progressivizeButton" + key={index} + onPointerLeave={() => { + if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0; + }} + onPointerOver={() => { + if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5; + }} + onClick={e => { + this.toggleDisplayMovement(doc); + e.stopPropagation(); + }} + style={{ backgroundColor: doc.displayMovement ? Colors.LIGHT_BLUE : '#c8c8c8', top: NumCast(doc.y), left: NumCast(doc.x) }}> + <div className="progressivizeButton-prev"> + <FontAwesomeIcon + icon={'caret-left'} + size={'lg'} + onClick={e => { + e.stopPropagation(); + this.prevAppearFrame(doc, index); + }} + /> + </div> + <div className="progressivizeButton-frame">{NumCast(doc.appearFrame)}</div> + <div className="progressivizeButton-next"> + <FontAwesomeIcon + icon={'caret-right'} + size={'lg'} + onClick={e => { + e.stopPropagation(); + this.nextAppearFrame(doc, index); + }} + /> + </div> + </div> + ); }); return tags; } @@ -2173,25 +2657,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { nextAppearFrame = (doc: Doc, i: number): void => { // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); // const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); - const appearFrame = Cast(doc.appearFrame, "number", null); + const appearFrame = Cast(doc.appearFrame, 'number', null); if (appearFrame === undefined) { doc.appearFrame = 0; } doc.appearFrame = appearFrame + 1; - this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame)); - } + this.updateOpacityList(doc['opacity-indexed'], NumCast(doc.appearFrame)); + }; @action prevAppearFrame = (doc: Doc, i: number): void => { // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); // const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); - const appearFrame = Cast(doc.appearFrame, "number", null); + const appearFrame = Cast(doc.appearFrame, 'number', null); if (appearFrame === undefined) { doc.appearFrame = 0; } doc.appearFrame = Math.max(0, appearFrame - 1); - this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame)); - } + this.updateOpacityList(doc['opacity-indexed'], NumCast(doc.appearFrame)); + }; @action updateOpacityList = (list: any, frame: number) => { @@ -2216,10 +2700,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } list = x; } - } + }; @computed get moreInfoDropdown() { - return (<div></div>); + return <div></div>; } @computed @@ -2235,28 +2719,36 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } else { CurrentUserUtils.propertiesWidth = 250; } - } + }; @computed get toolbar() { - const propIcon = CurrentUserUtils.propertiesWidth > 0 ? "angle-double-right" : "angle-double-left"; - const propTitle = CurrentUserUtils.propertiesWidth > 0 ? "Close Presentation Panel" : "Open Presentation Panel"; + const propIcon = CurrentUserUtils.propertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left'; + const propTitle = CurrentUserUtils.propertiesWidth > 0 ? 'Close Presentation Panel' : 'Open Presentation Panel'; const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; const isMini: boolean = this.toolbarWidth <= 100; - const presKeyEvents: boolean = (this.isPres && this._presKeyEventsActive && this.rootDoc === CurrentUserUtils.ActivePresentation); + const presKeyEvents: boolean = this.isPres && this._presKeyEventsActive && this.rootDoc === CurrentUserUtils.ActivePresentation; const activeColor = Colors.LIGHT_BLUE; const inactiveColor = Colors.WHITE; - return (mode === CollectionViewType.Carousel3D) ? (null) : ( + return mode === CollectionViewType.Carousel3D ? null : ( <div id="toolbarContainer" className={'presBox-toolbar'}> {/* <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}> <FontAwesomeIcon icon={"plus"} /> <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} /> </div></Tooltip> */} - <Tooltip title={<><div className="dash-tooltip">{"View paths"}</div></>}> - <div style={{ opacity: this.childDocs.length > 1 && this.layoutDoc.presCollection ? 1 : 0.3, color: this._pathBoolean ? Colors.MEDIUM_BLUE : 'white', width: isMini ? "100%" : undefined }} className={"toolbar-button"} onClick={this.childDocs.length > 1 && this.layoutDoc.presCollection ? this.viewPaths : undefined}> - <FontAwesomeIcon icon={"exchange-alt"} /> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'View paths'}</div> + </> + }> + <div + style={{ opacity: this.childDocs.length > 1 && this.layoutDoc.presCollection ? 1 : 0.3, color: this._pathBoolean ? Colors.MEDIUM_BLUE : 'white', width: isMini ? '100%' : undefined }} + className={'toolbar-button'} + onClick={this.childDocs.length > 1 && this.layoutDoc.presCollection ? this.viewPaths : undefined}> + <FontAwesomeIcon icon={'exchange-alt'} /> </div> </Tooltip> - {isMini ? (null) : + {isMini ? null : ( <> <div className="toolbar-divider" /> {/* <Tooltip title={<><div className="dash-tooltip">{this._expandBoolean ? "Minimize all" : "Expand all"}</div></>}> @@ -2267,18 +2759,28 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { </div> </Tooltip> <div className="toolbar-divider" /> */} - <Tooltip title={<><div className="dash-tooltip">{presKeyEvents ? "Keys are active" : "Keys are not active - click anywhere on the presentation trail to activate keys"}</div></>}> + <Tooltip + title={ + <> + <div className="dash-tooltip">{presKeyEvents ? 'Keys are active' : 'Keys are not active - click anywhere on the presentation trail to activate keys'}</div> + </> + }> <div className="toolbar-button" style={{ cursor: presKeyEvents ? 'default' : 'pointer', position: 'absolute', right: 30, fontSize: 16 }}> - <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"keyboard"} style={{ color: presKeyEvents ? activeColor : inactiveColor }} /> + <FontAwesomeIcon className={'toolbar-thumbtack'} icon={'keyboard'} style={{ color: presKeyEvents ? activeColor : inactiveColor }} /> </div> </Tooltip> - <Tooltip title={<><div className="dash-tooltip">{propTitle}</div></>}> + <Tooltip + title={ + <> + <div className="dash-tooltip">{propTitle}</div> + </> + }> <div className="toolbar-button" style={{ position: 'absolute', right: 4, fontSize: 16 }} onClick={this.toggleProperties}> - <FontAwesomeIcon className={"toolbar-thumbtack"} icon={propIcon} style={{ color: CurrentUserUtils.propertiesWidth > 0 ? activeColor : inactiveColor }} /> + <FontAwesomeIcon className={'toolbar-thumbtack'} icon={propIcon} style={{ color: CurrentUserUtils.propertiesWidth > 0 ? activeColor : inactiveColor }} /> </div> </Tooltip> </> - } + )} </div> ); } @@ -2292,35 +2794,45 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; const isMini: boolean = this.toolbarWidth <= 100; return ( - <div className="presBox-buttons" style={{ display: !this.rootDoc._chromeHidden ? "none" : undefined }}> - {isMini ? (null) : <select className="presBox-viewPicker" - style={{ display: this.layoutDoc.presStatus === "edit" ? "block" : "none" }} - onPointerDown={e => e.stopPropagation()} - onChange={this.viewChanged} - value={mode}> - <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Stacking}>List</option> - <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Tree}>Tree</option> - {Doc.noviceMode ? (null) : <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel3D}>3D Carousel</option>} - </select>} + <div className="presBox-buttons" style={{ display: !this.rootDoc._chromeHidden ? 'none' : undefined }}> + {isMini ? null : ( + <select className="presBox-viewPicker" style={{ display: this.layoutDoc.presStatus === 'edit' ? 'block' : 'none' }} onPointerDown={e => e.stopPropagation()} onChange={this.viewChanged} value={mode}> + <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Stacking}> + List + </option> + <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Tree}> + Tree + </option> + {Doc.noviceMode ? null : ( + <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel3D}> + 3D Carousel + </option> + )} + </select> + )} <div className="presBox-presentPanel" style={{ opacity: this.childDocs.length ? 1 : 0.3 }}> - <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}> - <div className="presBox-button-left" + <span className={`presBox-button ${this.layoutDoc.presStatus === 'edit' ? 'present' : ''}`}> + <div + className="presBox-button-left" onClick={undoBatch(() => { if (this.childDocs.length) { - this.layoutDoc.presStatus = "manual"; + this.layoutDoc.presStatus = 'manual'; this.gotoDocument(this.itemIndex, this.activeItem); } })}> - <FontAwesomeIcon icon={"play-circle"} /> - <div style={{ display: this.props.PanelWidth() > 200 ? "inline-flex" : "none" }}> Present</div> + <FontAwesomeIcon icon={'play-circle'} /> + <div style={{ display: this.props.PanelWidth() > 200 ? 'inline-flex' : 'none' }}> Present</div> </div> - {(mode === CollectionViewType.Carousel3D || isMini) ? (null) : <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`} - onClick={(action(() => { - if (this.childDocs.length) this.presentTools = !this.presentTools; - }))}> - <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} /> - {this.presentDropdown} - </div>} + {mode === CollectionViewType.Carousel3D || isMini ? null : ( + <div + className={`presBox-button-right ${this.presentTools ? 'active' : ''}`} + onClick={action(() => { + if (this.childDocs.length) this.presentTools = !this.presentTools; + })}> + <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={'angle-down'} /> + {this.presentDropdown} + </div> + )} </span> {this.playButtons} </div> @@ -2332,7 +2844,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { getList = (list: any): List<number> => { const x: List<number> = list; return x; - } + }; @action updateList = (list: any): List<number> => { @@ -2341,7 +2853,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { x.length + 1; x[x.length - 1] = NumCast(targetDoc._scrollY); return x; - } + }; @action newFrame = () => { @@ -2350,7 +2862,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const type: string = StrCast(targetDoc.type); if (!activeItem.frameList) activeItem.frameList = new List<number>(); switch (type) { - case (DocumentType.PDF || DocumentType.RTF || DocumentType.WEB): + case DocumentType.PDF || DocumentType.RTF || DocumentType.WEB: this.updateList(activeItem.frameList); break; case DocumentType.COL: @@ -2358,20 +2870,46 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { default: break; } - } + }; @computed get frameListHeader() { - return (<div className="frameList-header"> - Frames {this.panable ? <i>Panable</i> : this.scrollable ? <i>Scrollable</i> : (null)} - <div className={"frameList-headerButtons"}> - <Tooltip title={<><div className="dash-tooltip">{"Add frame by example"}</div></>}><div className={"headerButton"} onClick={e => { e.stopPropagation(); this.newFrame(); }}> - <FontAwesomeIcon icon={"plus"} onPointerDown={e => e.stopPropagation()} /> - </div></Tooltip> - <Tooltip title={<><div className="dash-tooltip">{"Edit in collection"}</div></>}><div className={"headerButton"} onClick={e => { e.stopPropagation(); console.log('New frame'); }}> - <FontAwesomeIcon icon={"edit"} onPointerDown={e => e.stopPropagation()} /> - </div></Tooltip> + return ( + <div className="frameList-header"> + Frames {this.panable ? <i>Panable</i> : this.scrollable ? <i>Scrollable</i> : null} + <div className={'frameList-headerButtons'}> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Add frame by example'}</div> + </> + }> + <div + className={'headerButton'} + onClick={e => { + e.stopPropagation(); + this.newFrame(); + }}> + <FontAwesomeIcon icon={'plus'} onPointerDown={e => e.stopPropagation()} /> + </div> + </Tooltip> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Edit in collection'}</div> + </> + }> + <div + className={'headerButton'} + onClick={e => { + e.stopPropagation(); + console.log('New frame'); + }}> + <FontAwesomeIcon icon={'edit'} onPointerDown={e => e.stopPropagation()} /> + </div> + </Tooltip> + </div> </div> - </div>); + ); } @computed get frameList() { @@ -2379,66 +2917,118 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const targetDoc: Doc = this.targetDoc; const frameList: List<number> = this.getList(activeItem.frameList); if (frameList) { - const frameItems = frameList.map((value) => - <div className="framList-item"> - - </div> - ); - return ( - - <div className="frameList-container"> - {frameItems} - </div> - ); - } else return (null); - + const frameItems = frameList.map(value => <div className="framList-item"></div>); + return <div className="frameList-container">{frameItems}</div>; + } else return null; } @computed get playButtonFrames() { const targetDoc: Doc = this.targetDoc; return ( <> - {this.targetDoc ? <div className="presPanel-button-frame" style={{ display: targetDoc.lastFrame !== undefined && targetDoc.lastFrame >= 0 ? "inline-flex" : "none" }}> - <div>{targetDoc._currentFrame}</div> - <div className="presPanel-divider" style={{ border: 'solid 0.5px white', height: '60%' }}></div> - <div>{targetDoc.lastFrame}</div> - </div> : null} + {this.targetDoc ? ( + <div className="presPanel-button-frame" style={{ display: targetDoc.lastFrame !== undefined && targetDoc.lastFrame >= 0 ? 'inline-flex' : 'none' }}> + <div>{NumCast(targetDoc._currentFrame)}</div> + <div className="presPanel-divider" style={{ border: 'solid 0.5px white', height: '60%' }}></div> + <div>{NumCast(targetDoc.lastFrame)}</div> + </div> + ) : null} </> ); } @computed get playButtons() { - const presEnd: boolean = !this.layoutDoc.presLoop && (this.itemIndex === this.childDocs.length - 1); - const presStart: boolean = !this.layoutDoc.presLoop && (this.itemIndex === 0); + const presEnd: boolean = !this.layoutDoc.presLoop && this.itemIndex === this.childDocs.length - 1; + const presStart: boolean = !this.layoutDoc.presLoop && this.itemIndex === 0; // Case 1: There are still other frames and should go through all frames before going to next slide - return (<div className="presPanelOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}> - <Tooltip title={<><div className="dash-tooltip">{"Loop"}</div></>}><div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : 'white' }} onClick={() => this.layoutDoc.presLoop = !this.layoutDoc.presLoop}><FontAwesomeIcon icon={"redo-alt"} /></div></Tooltip> - <div className="presPanel-divider"></div> - <div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }} onClick={() => { this.back(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-left"} /></div> - <Tooltip title={<><div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}</div></>}><div className="presPanel-button" onClick={this.startOrPause}><FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? "pause" : "play"} /></div></Tooltip> - <div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }} onClick={() => { this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-right"} /></div> - <div className="presPanel-divider"></div> - <Tooltip title={<><div className="dash-tooltip">{"Click to return to 1st slide"}</div></>}><div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.gotoDocument(0, this.activeItem)}><b>1</b></div></Tooltip> - <div - className="presPanel-button-text" - onClick={() => this.gotoDocument(0, this.activeItem)} - style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}> - Slide {this.itemIndex + 1} / {this.childDocs.length} - {this.playButtonFrames} + return ( + <div className="presPanelOverlay" style={{ display: this.layoutDoc.presStatus !== 'edit' ? 'inline-flex' : 'none' }}> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Loop'}</div> + </> + }> + <div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : 'white' }} onClick={() => (this.layoutDoc.presLoop = !this.layoutDoc.presLoop)}> + <FontAwesomeIcon icon={'redo-alt'} /> + </div> + </Tooltip> + <div className="presPanel-divider"></div> + <div + className="presPanel-button" + style={{ opacity: presStart ? 0.4 : 1 }} + onClick={() => { + this.back(); + if (this._presTimer) { + clearTimeout(this._presTimer); + this.layoutDoc.presStatus = PresStatus.Manual; + } + }}> + <FontAwesomeIcon icon={'arrow-left'} /> + </div> + <Tooltip + title={ + <> + <div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? 'Pause' : 'Autoplay'}</div> + </> + }> + <div className="presPanel-button" onClick={this.startOrPause}> + <FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? 'pause' : 'play'} /> + </div> + </Tooltip> + <div + className="presPanel-button" + style={{ opacity: presEnd ? 0.4 : 1 }} + onClick={() => { + this.next(); + if (this._presTimer) { + clearTimeout(this._presTimer); + this.layoutDoc.presStatus = PresStatus.Manual; + } + }}> + <FontAwesomeIcon icon={'arrow-right'} /> + </div> + <div className="presPanel-divider"></div> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Click to return to 1st slide'}</div> + </> + }> + <div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.gotoDocument(0, this.activeItem)}> + <b>1</b> + </div> + </Tooltip> + <div className="presPanel-button-text" onClick={() => this.gotoDocument(0, this.activeItem)} style={{ display: this.props.PanelWidth() > 250 ? 'inline-flex' : 'none' }}> + Slide {this.itemIndex + 1} / {this.childDocs.length} + {this.playButtonFrames} + </div> + <div className="presPanel-divider"></div> + {this.props.PanelWidth() > 250 ? ( + <div + className="presPanel-button-text" + onClick={undoBatch( + action(() => { + this.layoutDoc.presStatus = 'edit'; + clearTimeout(this._presTimer); + }) + )}> + EXIT + </div> + ) : ( + <div className="presPanel-button" onClick={undoBatch(action(() => (this.layoutDoc.presStatus = 'edit')))}> + <FontAwesomeIcon icon={'times'} /> + </div> + )} </div> - <div className="presPanel-divider"></div> - {this.props.PanelWidth() > 250 ? <div className="presPanel-button-text" onClick={undoBatch(action(() => { this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT</div> - : <div className="presPanel-button" onClick={undoBatch(action(() => this.layoutDoc.presStatus = "edit"))}> - <FontAwesomeIcon icon={"times"} /> - </div>} - </div>); + ); } @action startOrPause = () => { if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startAutoPres(this.itemIndex); else this.pauseAutoPres(); - } + }; @action prevClicked = (e: PointerEvent) => { @@ -2447,7 +3037,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } - } + }; @action nextClicked = (e: PointerEvent) => { @@ -2456,35 +3046,35 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } - } + }; @undoBatch @action exitClicked = (e: PointerEvent) => { this.updateMinimize(); this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); - } + }; @action startMarqueeCreateSlide = () => { PresBox.startMarquee = true; - } + }; AddToMap = (treeViewDoc: Doc, index: number[]): Doc[] => { var indexNum = 0; for (let i = 0; i < index.length; i++) { - indexNum += (index[i] * (10 ** (-i))); + indexNum += index[i] * 10 ** -i; } if (this._treeViewMap.get(treeViewDoc) !== indexNum) { this._treeViewMap.set(treeViewDoc, indexNum); const sorted = this.sort(this._treeViewMap); const curList = DocListCast(this.dataDoc[this.presFieldKey]); - if (sorted.length !== curList.length || sorted.some((doc,ind) => doc !== curList[ind])) { + if (sorted.length !== curList.length || sorted.some((doc, ind) => doc !== curList[ind])) { this.dataDoc[this.presFieldKey] = new List<Doc>(sorted); // this is a flat array of Docs } } return this.childDocs; - } + }; RemFromMap = (treeViewDoc: Doc, index: number[]): Doc[] => { if (!this._unmounting && this.isTree) { @@ -2492,10 +3082,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this.dataDoc[this.presFieldKey] = new List<Doc>(this.sort(this._treeViewMap)); } return this.childDocs; - } + }; // TODO: [AL] implement sort function for an array of numbers (e.g. arr[1,2,4] v arr[1,2,1]) - sort = (treeViewMap: Map<Doc, number>) => [...treeViewMap.entries()].sort((a: [Doc, number], b: [Doc, number]) => a[1] > b[1] ? 1 : a[1] < b[1] ? -1 : 0).map(kv => kv[0]); + sort = (treeViewMap: Map<Doc, number>) => [...treeViewMap.entries()].sort((a: [Doc, number], b: [Doc, number]) => (a[1] > b[1] ? 1 : a[1] < b[1] ? -1 : 0)).map(kv => kv[0]); render() { // calling this method for keyEvents @@ -2503,42 +3093,73 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // needed to ensure that the childDocs are loaded for looking up fields this.childDocs.slice(); const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; - const presKeyEvents: boolean = (this.isPres && this._presKeyEventsActive && this.rootDoc === CurrentUserUtils.ActivePresentation); - const presEnd: boolean = !this.layoutDoc.presLoop && (this.itemIndex === this.childDocs.length - 1); - const presStart: boolean = !this.layoutDoc.presLoop && (this.itemIndex === 0); - return DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.rootDoc) ? + const presKeyEvents: boolean = this.isPres && this._presKeyEventsActive && this.rootDoc === CurrentUserUtils.ActivePresentation; + const presEnd: boolean = !this.layoutDoc.presLoop && this.itemIndex === this.childDocs.length - 1; + const presStart: boolean = !this.layoutDoc.presLoop && this.itemIndex === 0; + return DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.rootDoc) ? ( <div className="miniPres" onClick={e => e.stopPropagation()}> - <div className="presPanelOverlay" style={{ display: "inline-flex", height: 30, background: '#323232', top: 0, zIndex: 3000000, boxShadow: presKeyEvents ? '0 0 0px 3px ' + Colors.MEDIUM_BLUE : undefined }}> - <Tooltip title={<><div className="dash-tooltip">{"Loop"}</div></>}><div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : undefined }} - onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => this.layoutDoc.presLoop = !this.layoutDoc.presLoop, false, false)}><FontAwesomeIcon icon={"redo-alt"} /></div></Tooltip> + <div className="presPanelOverlay" style={{ display: 'inline-flex', height: 30, background: '#323232', top: 0, zIndex: 3000000, boxShadow: presKeyEvents ? '0 0 0px 3px ' + Colors.MEDIUM_BLUE : undefined }}> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Loop'}</div> + </> + }> + <div + className="presPanel-button" + style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : undefined }} + onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => (this.layoutDoc.presLoop = !this.layoutDoc.presLoop), false, false)}> + <FontAwesomeIcon icon={'redo-alt'} /> + </div> + </Tooltip> <div className="presPanel-divider"></div> - <div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }} - onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.prevClicked, false, false)}><FontAwesomeIcon icon={"arrow-left"} /></div> - <Tooltip title={<><div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}</div></>}><div className="presPanel-button" - onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.startOrPause, false, false)}><FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div></Tooltip> - <div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }} - onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.nextClicked, false, false)}><FontAwesomeIcon icon={"arrow-right"} /></div> + <div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.prevClicked, false, false)}> + <FontAwesomeIcon icon={'arrow-left'} /> + </div> + <Tooltip + title={ + <> + <div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? 'Pause' : 'Autoplay'}</div> + </> + }> + <div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.startOrPause, false, false)}> + <FontAwesomeIcon icon={this.layoutDoc.presStatus === 'auto' ? 'pause' : 'play'} /> + </div> + </Tooltip> + <div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.nextClicked, false, false)}> + <FontAwesomeIcon icon={'arrow-right'} /> + </div> <div className="presPanel-divider"></div> - <Tooltip title={<><div className="dash-tooltip">{"Click to return to 1st slide"}</div></>}><div className="presPanel-button" style={{ border: 'solid 1px white' }} - onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => this.gotoDocument(0, this.activeItem), false, false)}><b>1</b></div></Tooltip> + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Click to return to 1st slide'}</div> + </> + }> + <div className="presPanel-button" style={{ border: 'solid 1px white' }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => this.gotoDocument(0, this.activeItem), false, false)}> + <b>1</b> + </div> + </Tooltip> <div className="presPanel-button-text"> Slide {this.itemIndex + 1} / {this.childDocs.length} {this.playButtonFrames} </div> <div className="presPanel-divider" /> - <div className="presPanel-button-text" onPointerDown={e => - setupMoveUpEvents(this, e, returnFalse, returnFalse, this.exitClicked, false, false)}>EXIT</div> + <div className="presPanel-button-text" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.exitClicked, false, false)}> + EXIT + </div> </div> - </div > - : - <div className="presBox-cont" style={{ minWidth: DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.layoutDoc) ? 240 : undefined }} > + </div> + ) : ( + <div className="presBox-cont" style={{ minWidth: DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.layoutDoc) ? 240 : undefined }}> {this.topPanel} {this.toolbar} {this.newDocumentToolbarDropdown} <div className="presBox-listCont"> <div className="Slide" style={{ height: `calc(100% - 30px)` }}> - {mode !== CollectionViewType.Invalid ? - <CollectionView {...this.props} + {mode !== CollectionViewType.Invalid ? ( + <CollectionView + {...this.props} ContainingCollectionDoc={this.props.Document} PanelWidth={this.props.PanelWidth} PanelHeight={this.panelHeight} @@ -2556,25 +3177,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { AddToMap={this.AddToMap} RemFromMap={this.RemFromMap} hierarchyIndex={[]} - /> : (null) - } + /> + ) : null} </div> - { // if the document type is a presentation, then the collection stacking view has a "+ new slide" button at the bottom of the stack - <Tooltip title={<div className="dash-tooltip">{"Click on document to pin to presentaiton or make a marquee selection to pin your desired view"}</div>}> + { + // if the document type is a presentation, then the collection stacking view has a "+ new slide" button at the bottom of the stack + <Tooltip title={<div className="dash-tooltip">{'Click on document to pin to presentaiton or make a marquee selection to pin your desired view'}</div>}> <button className="add-slide-button" onPointerDown={this.startMarqueeCreateSlide}> + NEW SLIDE </button> </Tooltip> } </div> - </div>; + </div> + ); } } -ScriptingGlobals.add(function navigateToDoc(bestTarget:Doc, activeItem:Doc) { +ScriptingGlobals.add(function navigateToDoc(bestTarget: Doc, activeItem: Doc) { const srcContext = Cast(bestTarget.context, Doc, null) ?? Cast(Cast(bestTarget.annotationOn, Doc, null)?.context, Doc, null); - const openInTab = (doc: Doc, finished?: () => void) => {CollectionDockingView.AddSplit(doc, "right"); finished?.(); }; - DocumentManager.Instance.jumpToDocument(bestTarget, true, openInTab, srcContext ? [srcContext]:[], - undefined, undefined, undefined, () => PresBox.navigateToDoc(bestTarget, activeItem, true), undefined, true, NumCast(activeItem.presZoom)); -});
\ No newline at end of file + const openInTab = (doc: Doc, finished?: () => void) => { + CollectionDockingView.AddSplit(doc, 'right'); + finished?.(); + }; + DocumentManager.Instance.jumpToDocument(bestTarget, true, openInTab, srcContext ? [srcContext] : [], undefined, undefined, undefined, () => PresBox.navigateToDoc(bestTarget, activeItem, true), undefined, true, NumCast(activeItem.presZoom)); +}); |
