diff options
| author | Sophie Zhang <sophie_zhang@brown.edu> | 2024-01-25 11:35:26 -0500 |
|---|---|---|
| committer | Sophie Zhang <sophie_zhang@brown.edu> | 2024-01-25 11:35:26 -0500 |
| commit | f3dab2a56db5e4a6a3dca58185d94e1ff7d1dc32 (patch) | |
| tree | a7bc895266b53bb620dbd2dd71bad2e83b555446 /src/client/views/nodes/trails | |
| parent | b5c5410b4af5d2c68d2107d3f064f6e3ec4ac3f2 (diff) | |
| parent | 136f3d9f349d54e8bdd73b6380ea47c19e5edebf (diff) | |
Merge branch 'master' into sophie-ai-images
Diffstat (limited to 'src/client/views/nodes/trails')
| -rw-r--r-- | src/client/views/nodes/trails/PresBox.scss | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/trails/PresBox.tsx | 295 | ||||
| -rw-r--r-- | src/client/views/nodes/trails/PresElementBox.tsx | 395 |
3 files changed, 310 insertions, 382 deletions
diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss index 1b76a39ad..1537ad0b8 100644 --- a/src/client/views/nodes/trails/PresBox.scss +++ b/src/client/views/nodes/trails/PresBox.scss @@ -1,4 +1,4 @@ -@import '../../global/globalCssVariables'; +@import '../../global/globalCssVariables.module.scss'; .presBox-cont { cursor: auto; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index f1b501506..b2059b185 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -1,10 +1,10 @@ -import React = require('react'); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; -import { action, computed, IReactionDisposer, observable, ObservableSet, reaction, runInAction } from 'mobx'; +import { Tooltip } from '@mui/material'; +import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast, FieldResult, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; -import { Animation } from '../../../../fields/DocSymbols'; +import { Animation, DocData } from '../../../../fields/DocSymbols'; import { Copy, Id } from '../../../../fields/FieldSymbols'; import { InkField } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; @@ -24,27 +24,19 @@ import { SerializationHelper } from '../../../util/SerializationHelper'; import { SettingsManager } from '../../../util/SettingsManager'; import { undoBatch, UndoManager } from '../../../util/UndoManager'; import { CollectionDockingView } from '../../collections/CollectionDockingView'; -import { CollectionFreeFormView, computeTimelineLayout, MarqueeViewBounds } from '../../collections/collectionFreeForm'; +import { CollectionFreeFormView, MarqueeViewBounds } from '../../collections/collectionFreeForm'; import { CollectionStackedTimeline } from '../../collections/CollectionStackedTimeline'; import { CollectionView } from '../../collections/CollectionView'; -import { TabDocView } from '../../collections/TabDocView'; import { TreeView } from '../../collections/TreeView'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { Colors } from '../../global/globalEnums'; import { LightboxView } from '../../LightboxView'; -import { DocFocusOptions, DocumentView, OpenWhere, OpenWhereMod } from '../DocumentView'; -import { FieldView, FieldViewProps } from '../FieldView'; +import { DocumentView, OpenWhere, OpenWhereMod } from '../DocumentView'; +import { FocusViewOptions, FieldView, FieldViewProps } from '../FieldView'; import { ScriptingBox } from '../ScriptingBox'; import './PresBox.scss'; import ReactLoading from 'react-loading'; import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums'; -import { IconButton, Type } from 'browndash-components'; -import { AiOutlineSend } from 'react-icons/ai'; -import { DictationManager } from '../../../util/DictationManager'; -import { BiMicrophone, BiX } from 'react-icons/bi'; -import TextareaAutosize from 'react-textarea-autosize'; -import { gptTrailSlideCustomization } from '../../../apis/gpt/customization'; - export interface pinDataTypes { scrollable?: boolean; dataviz?: number[]; @@ -79,10 +71,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } static navigateToDocScript: ScriptField; - constructor(props: any) { + constructor(props: FieldViewProps) { super(props); + makeObservable(this); if (!PresBox.navigateToDocScript) { - PresBox.navigateToDocScript = ScriptField.MakeFunction('navigateToDoc(self.presentation_targetDoc, self)')!; + PresBox.navigateToDocScript = ScriptField.MakeFunction('navigateToDoc(this.presentation_targetDoc, self)')!; } } @@ -91,12 +84,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { _batch: UndoManager.Batch | undefined = undefined; // undo batch for dragging sliders which generate multiple scene edit events as the cursor moves _keyTimer: NodeJS.Timeout | undefined; // timer for turning off transition flag when key frame change has completed. Need to clear this if you do a second navigation before first finishes, or else first timer can go off during second naviation. _unmounting = false; // flag that view is unmounting used to block RemFromMap from deleting things + _presTimer: NodeJS.Timeout | undefined; @observable public static Instance: PresBox; @observable _isChildActive = false; @observable _moveOnFromAudio: boolean = true; - @observable _presTimer!: NodeJS.Timeout; @observable _eleArray: HTMLElement[] = []; @observable _dragArray: HTMLElement[] = []; @@ -151,16 +144,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { return StrCast(this.layoutDoc.presFieldKey, 'data'); } @computed get childDocs() { - return DocListCast(this.rootDoc[this.presFieldKey]); + return DocListCast(this.Document[this.presFieldKey]); } @computed get tagDocs() { return this.childDocs.map(doc => Cast(doc.presentation_targetDoc, Doc, null)); } @computed get itemIndex() { - return NumCast(this.rootDoc._itemIndex); + return NumCast(this.Document._itemIndex); } @computed get activeItem() { - return DocCast(this.childDocs[NumCast(this.rootDoc._itemIndex)]); + return DocCast(this.childDocs[NumCast(this.Document._itemIndex)]); } @computed get targetDoc() { return Cast(this.activeItem?.presentation_targetDoc, Doc, null); @@ -178,21 +171,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { return false; } @computed get selectedDocumentView() { - if (SelectionManager.Views().length) return SelectionManager.Views()[0]; - if (this.selectedArray.size) return DocumentManager.Instance.getDocumentView(this.rootDoc); + if (SelectionManager.Views.length) return SelectionManager.Views[0]; + if (this.selectedArray.size) return DocumentManager.Instance.getDocumentView(this.Document); } @computed get isPres() { - return this.selectedDoc === this.rootDoc; + return this.selectedDoc === this.Document; } @computed get selectedDoc() { - return this.selectedDocumentView?.rootDoc; + return this.selectedDocumentView?.Document; } isActiveItemTarget = (layoutDoc: Doc) => this.activeItem?.presentation_targetDoc === layoutDoc; clearSelectedArray = () => this.selectedArray.clear(); addToSelectedArray = action((doc: Doc) => this.selectedArray.add(doc)); removeFromSelectedArray = action((doc: Doc) => this.selectedArray.delete(doc)); - @action componentWillUnmount() { this._unmounting = true; if (this._presTimer) clearTimeout(this._presTimer); @@ -207,7 +199,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { () => this.selectedDoc, selected => { document.removeEventListener('keydown', PresBox.keyEventsWrapper, true); - (this._presKeyEvents = selected === this.rootDoc) && document.addEventListener('keydown', PresBox.keyEventsWrapper, true); + (this._presKeyEvents = selected === this.Document) && document.addEventListener('keydown', PresBox.keyEventsWrapper, true); }, { fireImmediately: true } ); @@ -223,39 +215,27 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }, { fireImmediately: true } ); - this.props.setContentView?.(this); + this._props.setContentViewBox?.(this); this._unmounting = false; - if (this.props.renderDepth > 0) { - runInAction(() => { - this.rootDoc._forceRenderEngine = computeTimelineLayout.name; - this.layoutDoc._gridGap = 0; - this.layoutDoc._yMargin = 0; - }); - } this.turnOffEdit(true); this._disposers.selection = reaction( - () => SelectionManager.Views().slice(), - views => (!PresBox.Instance || views.some(view => view.props.Document === this.rootDoc)) && this.updateCurrentPresentation(), + () => SelectionManager.Views.slice(), + views => (!PresBox.Instance || views.some(view => view.Document === this.Document)) && this.updateCurrentPresentation(), { fireImmediately: true } ); this._disposers.editing = reaction( () => this.layoutDoc.presentation_status === PresStatus.Edit, - editing => { - if (editing) { - this.childDocs.forEach(doc => { - if (doc.presentation_indexed !== undefined) { - this.progressivizedItems(doc)?.forEach(indexedDoc => (indexedDoc.opacity = undefined)); - doc.presentation_indexed = Math.min(this.progressivizedItems(doc)?.length ?? 0, 1); - } - }); - } - } + editing => editing && + this.childDocs.filter(doc => doc.presentation_indexed !== undefined).forEach(doc => { + this.progressivizedItems(doc)?.forEach(indexedDoc => (indexedDoc.opacity = undefined)); + doc.presentation_indexed = Math.min(this.progressivizedItems(doc)?.length ?? 0, 1); + }) // prettier-ignore ); } @action updateCurrentPresentation = (pres?: Doc) => { - Doc.ActivePresentation = pres ?? this.rootDoc; + Doc.ActivePresentation = pres ?? this.Document; PresBox.Instance = this; }; @@ -384,19 +364,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }; // go to documents chain - runSubroutines = (childrenToRun: Doc[], normallyNextSlide: Doc) => { - console.log(childrenToRun, normallyNextSlide, 'runSUBFUNC'); - if (childrenToRun === undefined) { - console.log('children undefined'); - return; - } - if (childrenToRun[0] === normallyNextSlide) { - return; + runSubroutines = (childrenToRun: Opt<Doc[]>, normallyNextSlide: Doc) => { + if (childrenToRun && childrenToRun[0] !== normallyNextSlide) { + childrenToRun.forEach(child => DocumentManager.Instance.showDocument(child, {})); } - - childrenToRun.forEach(child => { - DocumentManager.Instance.showDocument(child, {}); - }); }; // Called when the user activates 'next' - to move to the next part of the pres. trail @@ -419,13 +390,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { listItemDoc.presentation_effect = this.activeItem.presBulletEffect; listItemDoc.presentation_transition = 500; targetView?.setAnimEffect(listItemDoc, 500); - if (targetView?.docView && this.activeItem.presBulletExpand) { - targetView.docView._animateScalingTo = 1.2; - targetView.docView._animateScaleTime = 400; - Doc.AddUnHighlightWatcher(() => { - targetView.docView!._animateScaleTime = undefined; - targetView!.docView!._animateScalingTo = 0; - }); + if (targetView && this.activeItem.presBulletExpand) { + targetView.setAnimateScaling(1.2, 400); + Doc.AddUnHighlightWatcher(() => targetView?.setAnimateScaling(0, undefined)); } listItemDoc.opacity = undefined; this.activeItem.presentation_indexed = presIndexed + 1; @@ -437,7 +404,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (progressiveReveal(false)) return true; if (this.childDocs[this.itemIndex + 1] !== undefined) { // Case 1: No more frames in current doc and next slide is defined, therefore move to next slide - const slides = DocListCast(this.rootDoc[StrCast(this.presFieldKey, 'data')]); + const slides = DocListCast(this.Document[StrCast(this.presFieldKey, 'data')]); const curLast = this.selectedArray.size ? Math.max(...Array.from(this.selectedArray).map(d => slides.indexOf(DocCast(d)))) : this.itemIndex; // before moving onto next slide, run the subroutines :) @@ -472,7 +439,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // Case 2: There are no other frames so it should go to the previous slide prevSelected = Math.max(0, prevSelected - 1); this.nextSlide(prevSelected); - this.rootDoc._itemIndex = prevSelected; + this.Document._itemIndex = prevSelected; } else if (this.childDocs[this.itemIndex - 1] === undefined && this.layoutDoc.presLoop) { // Case 3: Pres loop is on so it should go to the last slide this.nextSlide(this.childDocs.length - 1); @@ -486,7 +453,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { public gotoDocument = action((index: number, from?: Doc, group?: boolean, finished?: () => void) => { Doc.UnBrushAllDocs(); if (index >= 0 && index < this.childDocs.length) { - this.rootDoc._itemIndex = index; + this.Document._itemIndex = index; if (from?.mediaStopTriggerList && this.layoutDoc.presentation_status !== PresStatus.Edit) { DocListCast(from.mediaStopTriggerList).forEach(this.stopTempMedia); } @@ -526,7 +493,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { playAnnotation = (anno: AudioField) => {}; @action static restoreTargetDocView(bestTargetView: Opt<DocumentView>, activeItem: Doc, transTime: number, pinDocLayout: boolean = BoolCast(activeItem.config_pinLayout), pinDataTypes?: pinDataTypes, targetDoc?: Doc) { - const bestTarget = bestTargetView?.rootDoc ?? (targetDoc?.layout_unrendered ? DocCast(targetDoc?.annotationOn) : targetDoc); + const bestTarget = bestTargetView?.Document ?? (targetDoc?.layout_unrendered ? DocCast(targetDoc?.annotationOn) : targetDoc); if (!bestTarget) return; let changed = false; if (pinDocLayout) { @@ -554,10 +521,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const acontext = activeItem.config_activeFrame !== undefined ? DocCast(DocCast(activeItem.presentation_targetDoc).embedContainer) : DocCast(activeItem.presentation_targetDoc); const context = DocCast(acontext)?.annotationOn ? DocCast(DocCast(acontext).annotationOn) : acontext; if (context) { - const ffview = DocumentManager.Instance.getFirstDocumentView(context)?.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView; + const ffview = DocumentManager.Instance.getFirstDocumentView(context)?.CollectionFreeFormView; if (ffview?.childDocs) { PresBox.Instance._keyTimer = CollectionFreeFormView.gotoKeyframe(PresBox.Instance._keyTimer, ffview.childDocs, transTime); - ffview.rootDoc._currentFrame = NumCast(activeFrame); + ffview.layoutDoc._currentFrame = NumCast(activeFrame); } } } @@ -567,9 +534,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const setData = bestTargetView?.ComponentView?.setData; if (setData) setData(activeItem.config_data); else { - const current = Doc.GetProto(bestTarget)[fkey]; - Doc.GetProto(bestTarget)[fkey + '_' + Date.now()] = current instanceof ObjectField ? current[Copy]() : current; - Doc.GetProto(bestTarget)[fkey] = activeItem.config_data instanceof ObjectField ? activeItem.config_data[Copy]() : activeItem.config_data; + const bestTargetData = bestTarget[DocData]; + const current = bestTargetData[fkey]; + bestTargetData[fkey + '_' + Date.now()] = current instanceof ObjectField ? current[Copy]() : current; + bestTargetData[fkey] = activeItem.config_data instanceof ObjectField ? activeItem.config_data[Copy]() : activeItem.config_data; } bestTarget[fkey + '_usePath'] = activeItem.config_usePath; setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10); @@ -627,11 +595,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } if (pinDataTypes?.inkable || (!pinDataTypes && (activeItem.config_fillColor !== undefined || activeItem.color !== undefined))) { if (bestTarget.fillColor !== activeItem.config_fillColor) { - Doc.GetProto(bestTarget).fillColor = StrCast(activeItem.config_fillColor, StrCast(bestTarget.fillColor)); + bestTarget[DocData].fillColor = StrCast(activeItem.config_fillColor, StrCast(bestTarget.fillColor)); changed = true; } if (bestTarget.color !== activeItem.config_color) { - Doc.GetProto(bestTarget).color = StrCast(activeItem.config_color, StrCast(bestTarget.color)); + bestTarget[DocData].color = StrCast(activeItem.config_color, StrCast(bestTarget.color)); changed = true; } if (bestTarget.width !== activeItem.width) { @@ -672,11 +640,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (bestTarget._layout_scrollTop !== activeItem.config_scrollTop) { bestTarget._layout_scrollTop = activeItem.config_scrollTop; changed = true; - const contentBounds = Cast(activeItem.config_viewBounds, listSpec('number')); - if (contentBounds) { - const dv = DocumentManager.Instance.getDocumentView(bestTarget)?.ComponentView; - dv?.brushView?.({ panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] }, transTime); - } } } if (pinDataTypes?.dataannos || (!pinDataTypes && activeItem.config_annotations !== undefined)) { @@ -693,7 +656,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { return doc; }); const newList = new List<Doc>([...oldItems, ...hiddenItems, ...newItems]); - Doc.GetProto(bestTarget)[fkey + '_annotations'] = newList; + bestTarget[DocData][fkey + '_annotations'] = newList; } if (pinDataTypes?.poslayoutview || (!pinDataTypes && activeItem.config_pinLayoutData !== undefined)) { changed = true; @@ -714,14 +677,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { data.fill && (doc._fillColor = data.fill); doc._width = data.w; doc._height = data.h; - data.data && (Doc.GetProto(doc).data = field); - data.text && (Doc.GetProto(doc).text = tfield); - Doc.AddDocToList(Doc.GetProto(bestTarget), layoutField, doc); + data.data && (doc[DocData].data = field); + data.text && (doc[DocData].text = tfield); + Doc.AddDocToList(bestTarget[DocData], layoutField, doc); } }); setTimeout(() => Array.from(transitioned).forEach(action(doc => (doc._dataTransition = undefined))), transTime + 10); } - if ((pinDataTypes?.pannable || (!pinDataTypes && (activeItem.config_viewBounds !== undefined || activeItem.config_panX !== undefined || activeItem.config_viewScale !== undefined))) && !bestTarget._isGroup) { + if ((pinDataTypes?.pannable || (!pinDataTypes && (activeItem.config_viewBounds !== undefined || activeItem.config_panX !== undefined || activeItem.config_viewScale !== undefined))) && !bestTarget.isGroup) { const contentBounds = Cast(activeItem.config_viewBounds, listSpec('number')); if (contentBounds) { const viewport = { panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] }; @@ -730,9 +693,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const dv = DocumentManager.Instance.getDocumentView(bestTarget); if (dv) { changed = true; - const computedScale = NumCast(activeItem.config_zoom, 1) * Math.min(dv.props.PanelWidth() / viewport.width, dv.props.PanelHeight() / viewport.height); + const computedScale = NumCast(activeItem.config_zoom, 1) * Math.min(dv._props.PanelWidth() / viewport.width, dv._props.PanelHeight() / viewport.height); activeItem.presentation_movement === PresMovement.Zoom && (bestTarget._freeform_scale = computedScale); - dv.ComponentView?.brushView?.(viewport, transTime); + dv.ComponentView?.brushView?.(viewport, transTime, 2500); } } else { if (bestTarget._freeform_panX !== activeItem.config_panX || bestTarget._freeform_panY !== activeItem.config_panY || bestTarget._freeform_scale !== activeItem.config_viewScale) { @@ -782,7 +745,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } if (pinProps.pinData.dataannos) { const fkey = Doc.LayoutFieldKey(targetDoc); - pinDoc.config_annotations = new List<Doc>(DocListCast(Doc.GetProto(targetDoc)[fkey + '_annotations']).filter(doc => !doc.layout_unrendered)); + pinDoc.config_annotations = new List<Doc>(DocListCast(targetDoc[DocData][fkey + '_annotations']).filter(doc => !doc.layout_unrendered)); } if (pinProps.pinData.inkable) { pinDoc.config_fillColor = targetDoc.fillColor; @@ -877,8 +840,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const dragViewCache = Array.from(this._dragArray); const eleViewCache = Array.from(this._eleArray); const resetSelection = action(() => { - if (!this.props.isSelected()) { - const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc); + if (!this._props.isSelected()) { + const presDocView = DocumentManager.Instance.getDocumentView(this.Document); if (presDocView) SelectionManager.SelectView(presDocView, false); this.clearSelectedArray(); selViewCache.forEach(doc => this.addToSelectedArray(doc)); @@ -890,6 +853,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { PresBox.NavigateToTarget(targetDoc, activeItem, resetSelection); }; + public static PanelName = 'PRESBOX'; + static NavigateToTarget(targetDoc: Doc, activeItem: Doc, finished?: () => void) { if (activeItem.presentation_movement === PresMovement.None && targetDoc.type === DocumentType.SCRIPTING) { (DocumentManager.Instance.getFirstDocumentView(targetDoc)?.ComponentView as ScriptingBox)?.onRun?.(); @@ -897,14 +862,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } const effect = activeItem.presentation_effect && activeItem.presentation_effect !== PresEffect.None ? activeItem.presentation_effect : undefined; const presTime = NumCast(activeItem.presentation_transition, effect ? 750 : 500); - const options: DocFocusOptions = { + const options: FocusViewOptions = { willPan: activeItem.presentation_movement !== PresMovement.None, willZoomCentered: activeItem.presentation_movement === PresMovement.Zoom || activeItem.presentation_movement === PresMovement.Jump || activeItem.presentation_movement === PresMovement.Center, zoomScale: activeItem.presentation_movement === PresMovement.Center ? 0 : NumCast(activeItem.config_zoom, 1), zoomTime: activeItem.presentation_movement === PresMovement.Jump ? 0 : Math.min(Math.max(effect ? 750 : 500, (effect ? 0.2 : 1) * presTime), presTime), effect: activeItem, noSelect: true, - openLocation: OpenWhere.addLeft, + openLocation: targetDoc.type === DocumentType.PRES ? ((OpenWhere.replace + ':' + PresBox.PanelName) as OpenWhere) : OpenWhere.addLeft, anchorDoc: activeItem, easeFunc: StrCast(activeItem.presEaseFunc, 'ease') as any, zoomTextSelections: BoolCast(activeItem.presentation_zoomText), @@ -914,7 +879,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (activeItem.presentation_openInLightbox) { const context = DocCast(targetDoc.annotationOn) ?? targetDoc; if (!DocumentManager.Instance.getLightboxDocumentView(context)) { - LightboxView.SetLightboxDoc(context); + LightboxView.Instance.SetLightboxDoc(context); } } if (targetDoc) { @@ -923,7 +888,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { DocumentManager.Instance.AddViewRenderedCb(LightboxView.LightboxDoc, dv => { // if target or the doc it annotates is not in the lightbox, then close the lightbox if (!DocumentManager.Instance.getLightboxDocumentView(DocCast(targetDoc.annotationOn) ?? targetDoc)) { - LightboxView.SetLightboxDoc(undefined); + LightboxView.Instance.SetLightboxDoc(undefined); } DocumentManager.Instance.showDocument(targetDoc, options, finished); }); @@ -1017,8 +982,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { break; } }); - LightboxView.SetLightboxDoc(undefined); - Doc.RemFromMyOverlay(this.rootDoc); + LightboxView.Instance.SetLightboxDoc(undefined); + Doc.RemFromMyOverlay(this.Document); return PresStatus.Edit; }; }; @@ -1057,7 +1022,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // The function allows for expanding the view of pres on toggle @action toggleExpandMode = () => { runInAction(() => (this._expandBoolean = !this._expandBoolean)); - this.rootDoc.expandBoolean = this._expandBoolean; + this.Document.expandBoolean = this._expandBoolean; this.childDocs.forEach(doc => { doc.presentation_expandInlineButton = this._expandBoolean; }); @@ -1107,16 +1072,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { */ @action enterMinimize = () => { - this.updateCurrentPresentation(this.rootDoc); + this.updateCurrentPresentation(this.Document); clearTimeout(this._presTimer); - const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - this.props.removeDocument?.(this.layoutDoc); - return PresBox.OpenPresMinimized(this.rootDoc, [pt[0] + (this.props.PanelWidth() - 250), pt[1] + 10]); + const pt = this.ScreenToLocalBoxXf().inverse().transformPoint(0, 0); + this._props.removeDocument?.(this.layoutDoc); + return PresBox.OpenPresMinimized(this.Document, [pt[0] + (this._props.PanelWidth() - 250), pt[1] + 10]); }; exitMinimize = () => { if (Doc.IsInMyOverlay(this.layoutDoc)) { - Doc.RemFromMyOverlay(this.rootDoc); - CollectionDockingView.AddSplit(this.rootDoc, OpenWhereMod.right); + Doc.RemFromMyOverlay(this.Document); + CollectionDockingView.AddSplit(this.Document, OpenWhereMod.right); } return PresStatus.Edit; }; @@ -1142,8 +1107,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const type_collection = e.target.selectedOptions[0].value as CollectionViewType; this.layoutDoc.presFieldKey = this.fieldKey + (type_collection === 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(type_collection) && (this.rootDoc._pivotField = undefined); - this.rootDoc._type_collection = type_collection; + [CollectionViewType.Tree || CollectionViewType.Stacking].includes(type_collection) && (this.Document._pivotField = undefined); + this.Document._type_collection = type_collection; if (this.isTreeOrStack) { this.layoutDoc._gridGap = 0; } @@ -1179,7 +1144,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { return StrCast(activeItem.presentation_movement); }); - 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) => { @@ -1190,11 +1155,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { audio.config_clipStart = NumCast(doc._timecodeToShow /* audioStart */, NumCast(doc._timecodeToShow /* videoStart */)); audio.config_clipEnd = NumCast(doc._timecodeToHide /* audioEnd */, NumCast(doc._timecodeToHide /* videoEnd */)); audio.presentation_duration = audio.config_clipStart - audio.config_clipEnd; - TabDocView.PinDoc(audio, { audioRange: true }); + this._props.pinToPres(audio, { audioRange: true }); setTimeout(() => this.removeDocument(doc), 0); return false; } - } else { + } else if (doc.type !== DocumentType.PRES) { if (!doc.presentation_targetDoc) doc.title = doc.title + ' - Slide'; doc.presentation_targetDoc = doc.createdFrom; // dropped document will be a new embedding of an embedded document somewhere else. doc.presentation_movement = PresMovement.Zoom; @@ -1203,10 +1168,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }); return true; }; + childLayoutTemplate = () => Docs.Create.PresElementBoxDocument(); - 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 - panelHeight = () => this.props.PanelHeight() - 40; + removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.Document, this.fieldKey, doc); + getTransform = () => this.ScreenToLocalBoxXf().translate(-5, -65); // listBox padding-left and pres-box-cont minHeight + panelHeight = () => this._props.PanelHeight() - 40; /** * For sorting the array so that the order is maintained when it is dropped. */ @@ -1244,11 +1210,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @action selectPres = () => { - const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc); + const presDocView = DocumentManager.Instance.getDocumentView(this.Document); presDocView && SelectionManager.SelectView(presDocView, false); }; - focusElement = (doc: Doc, options: DocFocusOptions) => { + focusElement = (doc: Doc, options: FocusViewOptions) => { this.selectElement(doc); return undefined; }; @@ -1260,7 +1226,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (noNav) { const index = this.childDocs.indexOf(doc); if (index >= 0 && index < this.childDocs.length) { - this.rootDoc._itemIndex = index; + this.Document._itemIndex = index; } } else { this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem); @@ -1359,8 +1325,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { 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.addToSelectedArray(this.childDocs[this.rootDoc._itemIndex]); + this.Document._itemIndex = NumCast(this.Document._itemIndex) + 1; + this.addToSelectedArray(this.childDocs[this.Document._itemIndex]); } else { this.next(); if (this._presTimer) { @@ -1376,8 +1342,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { case 'ArrowLeft': if (e.shiftKey && this.itemIndex !== 0) { // TODO: update to work properly - this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) - 1; - this.addToSelectedArray(this.childDocs[this.rootDoc._itemIndex]); + this.Document._itemIndex = NumCast(this.Document._itemIndex) - 1; + this.addToSelectedArray(this.childDocs[this.Document._itemIndex]); } else { this.back(); if (this._presTimer) { @@ -1440,7 +1406,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } else if (doc.config_pinView && presCollection === tagDoc && dv) { // Case B: Document is presPinView and is presCollection const scale = 1 / NumCast(doc.config_viewScale); - const viewBounds = NumListCast(doc.config_viewBounds, [0, 0, dv.props.PanelWidth(), dv.props.PanelHeight()]); + const viewBounds = NumListCast(doc.config_viewBounds, [0, 0, dv._props.PanelWidth(), dv._props.PanelHeight()]); const height = (viewBounds[3] - viewBounds[1]) * scale; const width = (viewBounds[2] - viewBounds[0]) * scale; const indWidth = width / 10; @@ -1560,46 +1526,39 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { updateMovement = action((movement: PresMovement, all?: boolean) => (all ? this.childDocs : this.selectedArray).forEach(doc => (doc.presentation_movement = movement))); @undoBatch - @action updateHideBefore = (activeItem: Doc) => { activeItem.presentation_hideBefore = !activeItem.presentation_hideBefore; this.selectedArray.forEach(doc => (doc.presentation_hideBefore = activeItem.presentation_hideBefore)); }; @undoBatch - @action updateHide = (activeItem: Doc) => { activeItem.presentation_hide = !activeItem.presentation_hide; this.selectedArray.forEach(doc => (doc.presentation_hide = activeItem.presentation_hide)); }; @undoBatch - @action updateHideAfter = (activeItem: Doc) => { activeItem.presentation_hideAfter = !activeItem.presentation_hideAfter; this.selectedArray.forEach(doc => (doc.presentation_hideAfter = activeItem.presentation_hideAfter)); }; @undoBatch - @action updateOpenDoc = (activeItem: Doc) => { activeItem.presentation_openInLightbox = !activeItem.presentation_openInLightbox; this.selectedArray.forEach(doc => (doc.presentation_openInLightbox = activeItem.presentation_openInLightbox)); }; @undoBatch - @action updateEaseFunc = (activeItem: Doc) => { activeItem.presEaseFunc = activeItem.presEaseFunc === 'linear' ? 'ease' : 'linear'; this.selectedArray.forEach(doc => (doc.presEaseFunc = activeItem.presEaseFunc)); }; @undoBatch - @action updateEffectDirection = (effect: PresEffectDirection, all?: boolean) => (all ? this.childDocs : this.selectedArray).forEach(doc => (doc.presentation_effectDirection = effect)); @undoBatch - @action updateEffect = (effect: PresEffect, bullet: boolean, all?: boolean) => (all ? this.childDocs : this.selectedArray).forEach(doc => (bullet ? (doc.presBulletEffect = effect) : (doc.presentation_effect = effect))); static _sliderBatch: any; @@ -1632,7 +1591,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }; @undoBatch - @action applyTo = (array: Doc[]) => { this.updateMovement(this.activeItem.presentation_movement as PresMovement, true); this.updateEffect(this.activeItem.presentation_effect as PresEffect, false, true); @@ -1762,8 +1720,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { let dataField = Doc.LayoutFieldKey(tagDoc); if (Cast(tagDoc[dataField], listSpec(Doc), null)?.filter(d => d instanceof Doc) === undefined) dataField = dataField + '_annotations'; - if (DocCast(activeItem.presentation_targetDoc).annotationOn) activeItem.data = ComputedField.MakeFunction(`self.presentation_targetDoc.annotationOn["${dataField}"]`); - else activeItem.data = ComputedField.MakeFunction(`self.presentation_targetDoc["${dataField}"]`); + if (DocCast(activeItem.presentation_targetDoc).annotationOn) activeItem.data = ComputedField.MakeFunction(`this.presentation_targetDoc.annotationOn?.["${dataField}"]`); + else activeItem.data = ComputedField.MakeFunction(`this.presentation_targetDoc?.["${dataField}"]`); }} checked={Cast(activeItem.presentation_indexed, 'number', null) !== undefined ? true : false} /> @@ -1809,12 +1767,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { className={'presBox-dropdownOptions'} style={{ display: this._openBulletEffectDropdown ? 'grid' : 'none', color: SettingsManager.userColor, background: SettingsManager.userBackgroundColor }} onPointerDown={e => e.stopPropagation()}> - {bulletEffect(PresEffect.None)} - {bulletEffect(PresEffect.Fade)} - {bulletEffect(PresEffect.Flip)} - {bulletEffect(PresEffect.Rotate)} - {bulletEffect(PresEffect.Bounce)} - {bulletEffect(PresEffect.Roll)} + {Object.values(PresEffect) + .filter(v => isNaN(Number(v))) + .map(effect => bulletEffect(effect))} </div> </div> </div> @@ -1978,12 +1933,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { display: this._openEffectDropdown ? 'grid' : 'none', }} onPointerDown={e => e.stopPropagation()}> - {preseEffect(PresEffect.None)} - {preseEffect(PresEffect.Fade)} - {preseEffect(PresEffect.Flip)} - {preseEffect(PresEffect.Rotate)} - {preseEffect(PresEffect.Bounce)} - {preseEffect(PresEffect.Roll)} + {Object.values(PresEffect) + .filter(v => isNaN(Number(v))) + .map(effect => preseEffect(effect))} </div> </div> <div className="ribbon-doubleButton" style={{ display: effect === PresEffectDirection.None ? 'none' : 'inline-flex' }}> @@ -2343,13 +2295,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { const tab = tabMap && Array.from(tabMap).find(tab => tab.DashDoc.type === DocumentType.COL)?.DashDoc; const presCollection = DocumentManager.GetContextPath(this.activeItem).reverse().lastElement().presentation_targetDoc ?? tab; const data = Cast(presCollection?.data, listSpec(Doc)); - const config_data = Cast(this.rootDoc.data, listSpec(Doc)); + const config_data = Cast(this.Document.data, listSpec(Doc)); if (data && config_data) { data.push(doc); - TabDocView.PinDoc(doc, {}); + this._props.pinToPres(doc, {}); this.gotoDocument(this.childDocs.length, this.activeItem); } else { - this.props.addDocTab(doc, OpenWhere.addRight); + this._props.addDocTab(doc, OpenWhere.addRight); } } }; @@ -2410,20 +2362,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @computed get toolbarWidth(): number { - return this.props.PanelWidth(); + return this._props.PanelWidth(); } @action - toggleProperties = () => (SettingsManager.propertiesWidth = SettingsManager.propertiesWidth > 0 ? 0 : 250); + toggleProperties = () => (SettingsManager.Instance.propertiesWidth = SettingsManager.Instance.propertiesWidth > 0 ? 0 : 250); @computed get toolbar() { - const propIcon = SettingsManager.propertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left'; - const propTitle = SettingsManager.propertiesWidth > 0 ? 'Close Presentation Panel' : 'Open Presentation Panel'; - const mode = StrCast(this.rootDoc._type_collection) as CollectionViewType; + const propIcon = SettingsManager.Instance.propertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left'; + const propTitle = SettingsManager.Instance.propertiesWidth > 0 ? 'Close Presentation Panel' : 'Open Presentation Panel'; + const mode = StrCast(this.Document._type_collection) as CollectionViewType; const isMini: boolean = this.toolbarWidth <= 100; const activeColor = SettingsManager.userVariantColor; const inactiveColor = lightOrDark(SettingsManager.userBackgroundColor) === Colors.WHITE ? Colors.WHITE : SettingsManager.userBackgroundColor; - return mode === CollectionViewType.Carousel3D || Doc.IsInMyOverlay(this.rootDoc) ? null : ( + return mode === CollectionViewType.Carousel3D || Doc.IsInMyOverlay(this.Document) ? 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"} /> @@ -2447,7 +2399,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { </Tooltip> <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: SettingsManager.propertiesWidth > 0 ? activeColor : inactiveColor }} /> + <FontAwesomeIcon className={'toolbar-thumbtack'} icon={propIcon} style={{ color: SettingsManager.Instance.propertiesWidth > 0 ? activeColor : inactiveColor }} /> </div> </Tooltip> </> @@ -2462,12 +2414,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { * presentPanel: The button to start the presentation / open minimized view of the presentation */ @computed get topPanel() { - const mode = StrCast(this.rootDoc._type_collection) as CollectionViewType; + const mode = StrCast(this.Document._type_collection) as CollectionViewType; const isMini: boolean = this.toolbarWidth <= 100; return ( - <div - className={`presBox-buttons${Doc.IsInMyOverlay(this.rootDoc) ? ' inOverlay' : ''}`} - style={{ background: Doc.ActivePresentation === this.rootDoc ? Colors.LIGHT_BLUE : undefined, display: !this.rootDoc._chromeHidden ? 'none' : undefined }}> + <div className={`presBox-buttons${Doc.IsInMyOverlay(this.Document) ? ' inOverlay' : ''}`} style={{ background: Doc.ActivePresentation === this.Document ? Colors.LIGHT_BLUE : undefined }}> {isMini ? null : ( <select className="presBox-viewPicker" style={{ display: this.layoutDoc.presentation_status === 'edit' ? 'block' : 'none' }} onPointerDown={e => e.stopPropagation()} onChange={this.viewChanged} value={mode}> <option onPointerDown={StopEvent} value={CollectionViewType.Stacking}> @@ -2495,7 +2445,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } })}> <FontAwesomeIcon icon={'play-circle'} /> - <div style={{ display: this.props.PanelWidth() > 200 ? 'inline-flex' : 'none' }}> Present</div> + <div style={{ display: this._props.PanelWidth() > 200 ? 'inline-flex' : 'none' }}> Present</div> </div> {mode === CollectionViewType.Carousel3D || isMini ? null : ( <div @@ -2520,7 +2470,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this.itemIndex === this.childDocs.length - 1 && (this.activeItem.presentation_indexed === undefined || NumCast(this.activeItem.presentation_indexed) === (this.progressivizedItems(this.activeItem)?.length ?? 0)); const presStart: boolean = !this.layoutDoc.presLoop && this.itemIndex === 0; - const inOverlay = Doc.IsInMyOverlay(this.rootDoc); + const inOverlay = Doc.IsInMyOverlay(this.Document); // 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.presentation_status !== 'edit' ? 'inline-flex' : 'none' }}> @@ -2605,12 +2555,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <b>1</b> </div> </Tooltip> - <div className="presPanel-button-text" onClick={() => this.gotoDocument(0, this.activeItem)} style={{ display: inOverlay || this.props.PanelWidth() > 250 ? 'inline-flex' : 'none' }}> + <div className="presPanel-button-text" onClick={() => this.gotoDocument(0, this.activeItem)} style={{ display: inOverlay || this._props.PanelWidth() > 250 ? 'inline-flex' : 'none' }}> {inOverlay ? '' : 'Slide'} {this.itemIndex + 1} {this.activeItem?.presentation_indexed !== undefined ? `(${this.activeItem.presentation_indexed}/${this.progressivizedItems(this.activeItem)?.length})` : ''} / {this.childDocs.length} </div> <div className="presPanel-divider"></div> - {this.props.PanelWidth() > 250 ? ( + {this._props.PanelWidth() > 250 ? ( <div className="presPanel-button-text" onClick={undoBatch( @@ -2656,7 +2606,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }; @undoBatch - @action exitClicked = () => { this.layoutDoc.presentation_status = this._exitTrail?.() ?? this.exitMinimize(); clearTimeout(this._presTimer); @@ -2678,6 +2627,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } }; + SlideIndex = (slideDoc: Doc) => DocListCast(this.dataDoc[this.presFieldKey]).indexOf(slideDoc); + RemFromMap = (treeViewDoc: Doc, index: number[]) => { if (!treeViewDoc.presentation_targetDoc) return this.childDocs; // if treeViewDoc is not a pres elements, then it's a sub-bullet of a progressivized slide which isn't added to the linearized list of pres elements since it's not really a pres element. if (!this._unmounting && this.isTree) { @@ -2691,17 +2642,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { render() { // needed to ensure that the childDocs are loaded for looking up fields this.childDocs.slice(); - const mode = StrCast(this.rootDoc._type_collection) as CollectionViewType; + const mode = StrCast(this.Document._type_collection) as CollectionViewType; const presEnd = !this.layoutDoc.presLoop && this.itemIndex === this.childDocs.length - 1 && (this.activeItem.presentation_indexed === undefined || NumCast(this.activeItem.presentation_indexed) === (this.progressivizedItems(this.activeItem)?.length ?? 0)); const presStart = !this.layoutDoc.presLoop && this.itemIndex === 0; - return this.props.addDocTab === returnFalse ? ( // bcz: hack!! - addDocTab === returnFalse only when this is being rendered by the OverlayView which means the doc is a mini player + return this._props.addDocTab === returnFalse ? ( // bcz: hack!! - addDocTab === returnFalse only when this is being rendered by the OverlayView which means the doc is a mini player <div className="miniPres" onClick={e => e.stopPropagation()} onPointerEnter={action(e => (this._forceKeyEvents = true))}> <div className="presPanelOverlay" - style={{ display: 'inline-flex', height: 30, background: Doc.ActivePresentation === this.rootDoc ? 'green' : '#323232', top: 0, zIndex: 3000000, boxShadow: this._presKeyEvents ? '0 0 0px 3px ' + Colors.MEDIUM_BLUE : undefined }}> + style={{ display: 'inline-flex', height: 30, background: Doc.ActivePresentation === this.Document ? 'green' : '#323232', top: 0, zIndex: 3000000, boxShadow: this._presKeyEvents ? '0 0 0px 3px ' + Colors.MEDIUM_BLUE : undefined }}> <Tooltip title={<div className="dash-tooltip">{'Loop'}</div>}> <div className="presPanel-button" @@ -2739,7 +2690,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { </div> </div> ) : ( - <div className="presBox-cont" style={{ minWidth: Doc.IsInMyOverlay(this.rootDoc) ? PresBox.minimizedWidth : undefined }}> + <div className="presBox-cont" style={{ minWidth: Doc.IsInMyOverlay(this.Document) ? PresBox.minimizedWidth : undefined }}> {this.topPanel} {this.toolbar} {this.newDocumentToolbarDropdown} @@ -2747,19 +2698,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="Slide"> {mode !== CollectionViewType.Invalid ? ( <CollectionView - {...this.props} - PanelWidth={this.props.PanelWidth} + {...this._props} + PanelWidth={this._props.PanelWidth} PanelHeight={this.panelHeight} childIgnoreNativeSize={true} moveDocument={returnFalse} ignoreUnrendered={true} childDragAction="move" - setContentView={emptyFunction} + setContentViewBox={emptyFunction} //childLayoutFitWidth={returnTrue} childOpacity={returnOne} childClickScript={PresBox.navigateToDocScript} childLayoutTemplate={this.childLayoutTemplate} - childXPadding={Doc.IsComicStyle(this.rootDoc) ? 20 : undefined} + childXPadding={Doc.IsComicStyle(this.Document) ? 20 : undefined} filterAddDocument={this.addDocumentFilter} removeDocument={returnFalse} dontRegisterView={true} @@ -2767,7 +2718,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { ScreenToLocalTransform={this.getTransform} AddToMap={this.AddToMap} RemFromMap={this.RemFromMap} - hierarchyIndex={emptyPath} + hierarchyIndex={emptyPath as any as number[]} /> ) : null} </div> diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 37f449001..ed2f25fb6 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -1,9 +1,9 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; -import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; +import { Tooltip } from '@mui/material'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; -import { Height, Width } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types'; @@ -15,17 +15,16 @@ import { DragManager } from '../../../util/DragManager'; import { SettingsManager } from '../../../util/SettingsManager'; import { Transform } from '../../../util/Transform'; import { undoable, undoBatch } from '../../../util/UndoManager'; +import { TreeView } from '../../collections/TreeView'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { EditableView } from '../../EditableView'; import { Colors } from '../../global/globalEnums'; -import { DocumentView, DocumentViewProps } from '../../nodes/DocumentView'; +import { DocumentView } from '../../nodes/DocumentView'; import { FieldView, FieldViewProps } from '../../nodes/FieldView'; import { StyleProp } from '../../StyleProvider'; import { PresBox } from './PresBox'; import './PresElementBox.scss'; import { PresMovement } from './PresEnums'; -import React = require('react'); -import { TreeView } from '../../collections/TreeView'; /** * This class models the view a document added to presentation will have in the presentation. * It involves some functionality for its buttons and options. @@ -35,37 +34,58 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); } - _heightDisposer: IReactionDisposer | undefined; + private _itemRef: React.RefObject<HTMLDivElement> = React.createRef(); + private _dragRef: React.RefObject<HTMLDivElement> = React.createRef(); + private _titleRef: React.RefObject<EditableView> = React.createRef(); + private _heightDisposer: IReactionDisposer | undefined; + readonly expandViewHeight = 100; + readonly collapsedHeight = 35; - @observable _dragging = false; - // Idea: this boolean will determine whether to automatically show the video when this preselement is selected. - // @observable static showVideo: boolean = false; - @computed get indexInPres() { - return DocListCast(this.presBox?.[StrCast(this.presBox.presFieldKey, 'data')]).indexOf(this.rootDoc); - } // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements) - @computed get expandViewHeight() { - return 100; - } - @computed get collapsedHeight() { - return 35; - } // the collapsed height changes depending on the state of the presBox. We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up - @computed get selectedArray() { - return this.presBoxView?.selectedArray; + constructor(props: FieldViewProps) { + super(props); + makeObservable(this); } + + @observable _dragging = false; + + // the presentation view that renders this slide @computed get presBoxView() { - return this.props.DocumentView?.()?.props.docViewPath().lastElement()?.ComponentView as PresBox; + return this.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as PresBox; } + + // the presentation view document that renders this slide @computed get presBox() { - return this.props.DocumentView?.().props.docViewPath().lastElement()?.rootDoc; + return this.presBoxView?.Document; + } + + // Since this node is being rendered with a template, this method retrieves + // the actual slide being rendered from the auto-generated rendering template + @computed get slideDoc() { + return this._props.TemplateDataDocument ?? this.Document; } + + // this is the document in the workspaces that is targeted by the slide @computed get targetDoc() { - return Cast(this.rootDoc.presentation_targetDoc, Doc, null) || this.rootDoc; + return Cast(this.slideDoc.presentation_targetDoc, Doc, null) || this.slideDoc; + } + + // computes index of this presentation slide in the presBox list + @computed get indexInPres() { + return this.presBoxView?.SlideIndex(this.slideDoc); + } + + @computed get selectedArray() { + return this.presBoxView?.selectedArray; + } + + @computed get videoRecordingIsInOverlay() { + return Doc.MyOverlayDocs.some(doc => doc.slides === this.slideDoc); } componentDidMount() { this.layoutDoc.layout_hideLinkButton = true; this._heightDisposer = reaction( - () => ({ expand: this.rootDoc.presentation_expandInlineButton, height: this.collapsedHeight }), + () => ({ expand: this.slideDoc.presentation_expandInlineButton, height: this.collapsedHeight }), ({ expand, height }) => (this.layoutDoc._height = height + (expand ? this.expandViewHeight : 0)), { fireImmediately: true } ); @@ -74,55 +94,41 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { this._heightDisposer?.(); } - /** - * Returns a local transformed coordinate array for given coordinates. - */ - ScreenToLocalListTransform = (xCord: number, yCord: number) => [xCord, yCord]; - - @action - presExpandDocumentClick = () => (this.rootDoc.presentation_expandInlineButton = !this.rootDoc.presentation_expandInlineButton); - - embedHeight = (): number => this.collapsedHeight + this.expandViewHeight; - // embedWidth = () => this.props.PanelWidth(); - // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight); - embedWidth = (): number => this.props.PanelWidth() / 2; - styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string): any => { - if (property === StyleProp.Opacity) return 1; - return this.props.styleProvider?.(doc, props, property); + presExpandDocumentClick = () => (this.slideDoc.presentation_expandInlineButton = !this.slideDoc.presentation_expandInlineButton); + embedHeight = () => this.collapsedHeight + this.expandViewHeight; + embedWidth = () => this._props.PanelWidth() / 2; + styleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => { + return property === StyleProp.Opacity ? 1 : this._props.styleProvider?.(doc, props, property); }; /** * The function that is responsible for rendering a preview or not for this * presentation element. */ @computed get renderEmbeddedInline() { - return !this.rootDoc.presentation_expandInlineButton || !this.targetDoc ? null : ( + return !this.slideDoc.presentation_expandInlineButton || !this.targetDoc ? null : ( <div className="presItem-embedded" style={{ height: this.embedHeight(), width: '50%' }}> <DocumentView - Document={PresBox.targetRenderedDoc(this.rootDoc)} - DataDoc={undefined} //this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]} + Document={PresBox.targetRenderedDoc(this.slideDoc)} PanelWidth={this.embedWidth} PanelHeight={this.embedHeight} - isContentActive={this.props.isContentActive} + isContentActive={this._props.isContentActive} styleProvider={this.styleProvider} hideLinkButton={true} ScreenToLocalTransform={Transform.Identity} - renderDepth={this.props.renderDepth + 1} - docViewPath={returnEmptyDoclist} - childFilters={this.props.childFilters} - childFiltersByRanges={this.props.childFiltersByRanges} - searchFilterDocs={this.props.searchFilterDocs} - rootSelected={returnTrue} + renderDepth={this._props.renderDepth + 1} + containerViewPath={returnEmptyDoclist} + childFilters={this._props.childFilters} + childFiltersByRanges={this._props.childFiltersByRanges} + searchFilterDocs={this._props.searchFilterDocs} addDocument={returnFalse} removeDocument={returnFalse} fitContentsToBox={returnTrue} - moveDocument={this.props.moveDocument!} + moveDocument={this._props.moveDocument!} focus={emptyFunction} whenChildContentsActiveChanged={returnFalse} addDocTab={returnFalse} pinToPres={returnFalse} - bringToFront={returnFalse} /> - {/* <div className="presItem-embeddedMask" /> */} </div> ); } @@ -159,26 +165,22 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { @computed get transition() { let transitionInS: number; - if (this.rootDoc.presentation_transition) transitionInS = NumCast(this.rootDoc.presentation_transition) / 1000; + if (this.slideDoc.presentation_transition) transitionInS = NumCast(this.slideDoc.presentation_transition) / 1000; else transitionInS = 0.5; - return this.rootDoc.presentation_movement === PresMovement.Jump || this.rootDoc.presentation_movement === PresMovement.None ? null : 'M: ' + transitionInS + 's'; + return this.slideDoc.presentation_movement === PresMovement.Jump || this.slideDoc.presentation_movement === PresMovement.None ? null : 'M: ' + transitionInS + 's'; } - private _itemRef: React.RefObject<HTMLDivElement> = React.createRef(); - private _dragRef: React.RefObject<HTMLDivElement> = React.createRef(); - private _titleRef: React.RefObject<EditableView> = React.createRef(); - @action headerDown = (e: React.PointerEvent<HTMLDivElement>) => { const element = e.target as any; e.stopPropagation(); e.preventDefault(); if (element && !(e.ctrlKey || e.metaKey || e.button === 2)) { - this.presBoxView?.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, true, false); + this.presBoxView?.regularSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, true, false); setupMoveUpEvents(this, e, this.startDrag, emptyFunction, e => { e.stopPropagation(); e.preventDefault(); - this.presBoxView?.modifierSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, e.shiftKey || e.ctrlKey || e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey); + this.presBoxView?.modifierSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, e.shiftKey || e.ctrlKey || e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey); this.presBoxView?.activeItem && this.showRecording(this.presBoxView?.activeItem); }); } @@ -189,12 +191,12 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { */ startDrag = (e: PointerEvent) => { const miniView: boolean = this.toolbarWidth <= 100; - const activeItem = this.rootDoc; + const activeItem = this.slideDoc; const dragArray = this.presBoxView?._dragArray ?? []; const dragData = new DragManager.DocumentDragData(this.presBoxView?.sortArray() ?? []); - if (!dragData.draggedDocuments.length) dragData.draggedDocuments.push(this.rootDoc); - dragData.treeViewDoc = this.presBox?._type_collection === CollectionViewType.Tree ? this.presBox : undefined; // this.props.DocumentView?.()?.props.treeViewDoc; - dragData.moveDocument = this.props.moveDocument; + if (!dragData.draggedDocuments.length) dragData.draggedDocuments.push(this.slideDoc); + dragData.treeViewDoc = this.presBox?._type_collection === CollectionViewType.Tree ? this.presBox : undefined; // this.DocumentView?.()?._props.treeViewDoc; + dragData.moveDocument = this._props.moveDocument; const dragItem: HTMLElement[] = []; const classesToRestore = new Map<HTMLElement, string>(); if (dragArray.length === 1) { @@ -238,7 +240,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { }; onPointerMove = (e: PointerEvent) => { - const slide = this._itemRef.current!; + const slide = this._itemRef.current; const dragIsPresItem = DragManager.docsBeingDragged.some(d => d.presentation_targetDoc); if (slide && dragIsPresItem) { const rect = slide.getBoundingClientRect(); @@ -257,35 +259,42 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { }; onPointerLeave = (e: any) => { - this._itemRef.current!.style.borderTop = '0px'; - this._itemRef.current!.style.borderBottom = '0px'; + const slide = this._itemRef.current; + if (slide) { + slide.style.borderTop = '0px'; + slide.style.borderBottom = '0px'; + } document.removeEventListener('pointermove', this.onPointerMove); }; @action toggleProperties = () => { - if (SettingsManager.propertiesWidth < 5) { - action(() => (SettingsManager.propertiesWidth = 250)); + if (SettingsManager.Instance.propertiesWidth < 5) { + SettingsManager.Instance.propertiesWidth = 250; } }; - removePresentationItem = undoable((e: React.MouseEvent) => { - e.stopPropagation(); - if (this.presBox && this.indexInPres < (this.presBoxView?.itemIndex || 0)) { - runInAction(() => (this.presBox!.itemIndex = (this.presBoxView?.itemIndex || 0) - 1)); - } - this.props.removeDocument?.(this.rootDoc); - this.presBoxView?.removeFromSelectedArray(this.rootDoc); - this.removeAllRecordingInOverlay(); - }, 'Remove doc from pres trail'); - - // set the value/title of the individual pres element - @undoBatch - @action - onSetValue = (value: string) => { - this.rootDoc.title = !value.trim().length ? '-untitled-' : value; - return true; - }; + removePresentationItem = undoable( + action((e: React.MouseEvent) => { + e.stopPropagation(); + if (this.presBox && this.indexInPres < (this.presBoxView?.itemIndex || 0)) { + this.presBox.itemIndex = (this.presBoxView?.itemIndex || 0) - 1; + } + this._props.removeDocument?.(this.slideDoc); + this.presBoxView?.removeFromSelectedArray(this.slideDoc); + this.removeAllRecordingInOverlay(); + }), + 'Remove doc from pres trail' + ); + + // set title of the individual pres slide + onSetValue = undoable( + action((value: string) => { + this.slideDoc.title = !value.trim().length ? '-untitled-' : value; + return true; + }), + 'set title of pres element' + ); /** * Method called for updating the view of the currently selected document @@ -294,7 +303,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { * @param activeItem */ @undoBatch - @action updateCapturedContainerLayout = (presTargetDoc: Doc, activeItem: Doc) => { const targetDoc = DocCast(presTargetDoc.annotationOn) ?? presTargetDoc; activeItem.config_x = NumCast(targetDoc.x); @@ -306,130 +314,99 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { // activeItem.config_pinLayout = true; }; - //wait i dont think i have to do anything here since by default it'll revert to the previously saved if I don't save - //so basically, don't have an onClick for this, just let it do nada for now - @undoBatch - @action - revertToPreviouslySaved = (presTargetDoc: Doc, activeItem: Doc) => { - const target = DocCast(activeItem.annotationOn) ?? activeItem; - PresBox.reversePin(activeItem, target); - }; - /** * Method called for updating the view of the currently selected document * * @param presTargetDoc * @param activeItem */ - @undoBatch - @action - updateCapturedViewContents = (presTargetDoc: Doc, activeItem: Doc) => { - const target = DocCast(presTargetDoc.annotationOn) ?? presTargetDoc; - PresBox.pinDocView(activeItem, { pinData: PresBox.pinDataTypes(target) }, target); - }; - - @computed get recordingIsInOverlay() { - return DocListCast(Doc.MyOverlayDocs.data).some(doc => doc.slides === this.rootDoc); - } + updateCapturedViewContents = undoable( + action((presTargetDoc: Doc, activeItem: Doc) => { + const target = DocCast(presTargetDoc.annotationOn) ?? presTargetDoc; + PresBox.pinDocView(activeItem, { pinData: PresBox.pinDataTypes(target) }, target); + }), + 'updated captured view contents' + ); // a previously recorded video will have timecode defined - static videoIsRecorded = (activeItem: Opt<Doc>) => { - const casted = Cast(activeItem?.recording, Doc, null); - return casted && 'layout_currentTimecode' in casted; - }; + static videoIsRecorded = (activeItem: Opt<Doc>) => 'layout_currentTimecode' in (DocCast(activeItem?.recording) ?? {}); - removeAllRecordingInOverlay = () => { - DocListCast(Doc.MyOverlayDocs.data) - .filter(doc => doc.slides === this.rootDoc) - .forEach(Doc.RemFromMyOverlay); - }; + removeAllRecordingInOverlay = () => Doc.MyOverlayDocs.filter(doc => doc.slides === this.slideDoc).forEach(Doc.RemFromMyOverlay); + /// remove all videos that have been recorded from overlay (leave videso that are being recorded to avoid losing data) static removeEveryExistingRecordingInOverlay = () => { - // Remove every recording that already exists in overlay view - DocListCast(Doc.MyOverlayDocs.data).forEach(doc => { - if (doc.slides !== null) { - // if it's a recording video, don't remove from overlay (user can lose data) - if (PresElementBox.videoIsRecorded(DocCast(doc.slides))) { - Doc.RemFromMyOverlay(doc); - } - } - }); - }; - - @undoBatch - @action - hideRecording = (e: React.MouseEvent, iconClick: boolean = false) => { - e.stopPropagation(); - this.removeAllRecordingInOverlay(); - // if (iconClick) PresElementBox.showVideo = false; - }; - - @undoBatch - @action - showRecording = (activeItem: Doc, iconClick: boolean = false) => { - // remove the overlays on switch *IF* not opened from the specific icon - if (!iconClick) PresElementBox.removeEveryExistingRecordingInOverlay(); - - if (activeItem.recording) { - Doc.AddToMyOverlay(DocCast(activeItem.recording)); - } + Doc.MyOverlayDocs.filter(doc => doc.slides !== null && PresElementBox.videoIsRecorded(DocCast(doc.slides))) // + .forEach(Doc.RemFromMyOverlay); }; - @undoBatch - @action - startRecording = (e: React.MouseEvent, activeItem: Doc) => { - e.stopPropagation(); - if (PresElementBox.videoIsRecorded(activeItem)) { - // if we already have an existing recording - this.showRecording(activeItem, true); - // // if we already have an existing recording - // Doc.AddToMyOverlay(Cast(activeItem.recording, Doc, null)); - } else { - // Remove every recording that already exists in overlay view - // this is a design decision to clear to focus in on the recoding mode - PresElementBox.removeEveryExistingRecordingInOverlay(); - - // if we dont have any recording - const recording = Docs.Create.WebCamDocument('', { - _width: 384, - _height: 216, - layout_hideDocumentButtonBar: true, - layout_hideDecorationTitle: true, - layout_hideOpenButton: true, - // hideDeleteButton: true, - cloneFieldFilter: new List<string>(['isSystem']), - }); - - // attach the recording to the slide, and attach the slide to the recording - recording.slides = activeItem; - activeItem.recording = recording; - - // make recording box appear in the bottom right corner of the screen - recording.overlayX = window.innerWidth - recording[Width]() - 20; - recording.overlayY = window.innerHeight - recording[Height]() - 20; - Doc.AddToMyOverlay(recording); - } - }; + hideRecording = undoable( + action((e: React.MouseEvent, iconClick: boolean = false) => { + e.stopPropagation(); + this.removeAllRecordingInOverlay(); + }), + 'hide video recording' + ); + + showRecording = undoable( + action((activeItem: Doc, iconClick: boolean = false) => { + // remove the overlays on switch *IF* not opened from the specific icon + if (!iconClick) PresElementBox.removeEveryExistingRecordingInOverlay(); + + activeItem.recording && Doc.AddToMyOverlay(DocCast(activeItem.recording)); + }), + 'show video recording' + ); + + startRecording = undoable( + action((e: React.MouseEvent, activeItem: Doc) => { + e.stopPropagation(); + if (PresElementBox.videoIsRecorded(activeItem)) { + // if we already have an existing recording + this.showRecording(activeItem, true); + // // if we already have an existing recording + // Doc.AddToMyOverlay(Cast(activeItem.recording, Doc, null)); + } else { + // we dont have any recording + // Remove every recording that already exists in overlay view + // this is a design decision to clear to focus in on the recoding mode + PresElementBox.removeEveryExistingRecordingInOverlay(); + + // create and add a recording to the slide + // make recording box appear in the bottom right corner of the screen + Doc.AddToMyOverlay( + (activeItem.recording = Docs.Create.WebCamDocument('', { + _width: 384, + _height: 216, + overlayX: window.innerWidth - 384 - 20, + overlayY: window.innerHeight - 216 - 20, + layout_hideDocumentButtonBar: true, + layout_hideDecorationTitle: true, + layout_hideOpenButton: true, + cloneFieldFilter: new List<string>(['isSystem']), + slides: activeItem, // attach the slide to the recording + })) + ); + } + }), + 'start video recording' + ); @undoBatch - @action lfg = (e: React.MouseEvent) => { e.stopPropagation(); // TODO: fix this bug - const { toggleChildrenRun } = this.rootDoc; - TreeView.ToggleChildrenRun.get(this.rootDoc)?.(); + const { toggleChildrenRun } = this.slideDoc; + TreeView.ToggleChildrenRun.get(this.slideDoc)?.(); - // call this.rootDoc.recurChildren() to get all the children + // call this.slideDoc.recurChildren() to get all the children // if (iconClick) PresElementBox.showVideo = false; }; @computed get toolbarWidth(): number { const presBoxDocView = DocumentManager.Instance.getDocumentView(this.presBox); - let width: number = NumCast(this.presBox?._width); - if (presBoxDocView) width = presBoxDocView.props.PanelWidth(); - if (width === 0) width = 300; - return width; + const width = NumCast(this.presBox?._width); + return presBoxDocView ? presBoxDocView._props.PanelWidth() : width ? width : 300; } // GPT @@ -439,8 +416,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { const presBoxColor = StrCast(presBox?._backgroundColor); const presColorBool = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false; const targetDoc = this.targetDoc; - const activeItem = this.rootDoc; - const hasChildren = BoolCast(this.rootDoc?.hasChildren); + const activeItem = this.slideDoc; + const hasChildren = BoolCast(this.slideDoc?.hasChildren); const items: JSX.Element[] = []; @@ -465,9 +442,9 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { </Tooltip> ); items.push( - <Tooltip key="slash" title={<div className="dash-tooltip">{this.recordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}</div>}> - <div className="slideButton" onClick={e => (this.recordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}> - <FontAwesomeIcon icon={`video${this.recordingIsInOverlay ? '-slash' : ''}`} onPointerDown={e => e.stopPropagation()} /> + <Tooltip key="slash" title={<div className="dash-tooltip">{this.videoRecordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}</div>}> + <div className="slideButton" onClick={e => (this.videoRecordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}> + <FontAwesomeIcon icon={`video${this.videoRecordingIsInOverlay ? '-slash' : ''}`} onPointerDown={e => e.stopPropagation()} /> </div> </Tooltip> ); @@ -480,8 +457,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { {!activeItem.presentation_groupWithUp ? 'Not grouped with previous slide (click to group)' : activeItem.presentation_groupWithUp === 1 - ? 'Run simultaneously with previous slide (click again to run after)' - : 'Run after previous slide (click to ungroup from previous)'} + ? 'Run simultaneously with previous slide (click again to run after)' + : 'Run after previous slide (click to ungroup from previous)'} </div> }> <div @@ -503,14 +480,14 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { ); } items.push( - <Tooltip key="eye" title={<div className="dash-tooltip">{this.rootDoc.presentation_expandInlineButton ? 'Minimize' : 'Expand'}</div>}> + <Tooltip key="eye" title={<div className="dash-tooltip">{this.slideDoc.presentation_expandInlineButton ? 'Minimize' : 'Expand'}</div>}> <div className="slideButton" onClick={e => { e.stopPropagation(); this.presExpandDocumentClick(); }}> - <FontAwesomeIcon icon={this.rootDoc.presentation_expandInlineButton ? 'eye-slash' : 'eye'} onPointerDown={e => e.stopPropagation()} /> + <FontAwesomeIcon icon={this.slideDoc.presentation_expandInlineButton ? 'eye-slash' : 'eye'} onPointerDown={e => e.stopPropagation()} /> </div> </Tooltip> ); @@ -554,30 +531,30 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { } @computed get mainItem() { - const isSelected: boolean = this.selectedArray?.has(this.rootDoc) ? true : false; + const isSelected: boolean = this.selectedArray?.has(this.slideDoc) ? true : false; const isCurrent: boolean = this.presBox?._itemIndex === this.indexInPres; const miniView: boolean = this.toolbarWidth <= 110; const presBox = this.presBox; //presBox const presBoxColor: string = StrCast(presBox?._backgroundColor); const presColorBool: boolean = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false; - const activeItem: Doc = this.rootDoc; + const activeItem: Doc = this.slideDoc; return ( <div - className={`presItem-container`} - key={this.props.Document[Id] + this.indexInPres} + className="presItem-container" + key={this.slideDoc[Id] + this.indexInPres} ref={this._itemRef} style={{ backgroundColor: presColorBool ? (isSelected ? 'rgba(250,250,250,0.3)' : 'transparent') : isSelected ? Colors.LIGHT_BLUE : 'transparent', opacity: this._dragging ? 0.3 : 1, - paddingLeft: NumCast(this.layoutDoc._xPadding, this.props.xPadding), - paddingRight: NumCast(this.layoutDoc._xPadding, this.props.xPadding), - paddingTop: NumCast(this.layoutDoc._yPadding, this.props.yPadding), - paddingBottom: NumCast(this.layoutDoc._yPadding, this.props.yPadding), + paddingLeft: NumCast(this.layoutDoc._xPadding, this._props.xPadding), + paddingRight: NumCast(this.layoutDoc._xPadding, this._props.xPadding), + paddingTop: NumCast(this.layoutDoc._yPadding, this._props.yPadding), + paddingBottom: NumCast(this.layoutDoc._yPadding, this._props.yPadding), }} onDoubleClick={action(e => { this.toggleProperties(); - this.presBoxView?.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false); + this.presBoxView?.regularSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, false); })} onPointerOver={this.onPointerOver} onPointerLeave={this.onPointerLeave} @@ -589,10 +566,10 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { ) : ( <div ref={this._dragRef} - className={`presItem-slide ${isCurrent ? 'active' : ''}${this.rootDoc.runProcess ? ' testingv2' : ''}`} + className={`presItem-slide ${isCurrent ? 'active' : ''}${this.slideDoc.runProcess ? ' testingv2' : ''}`} style={{ display: 'infline-block', - backgroundColor: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor), + backgroundColor: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor), //layout_boxShadow: presBoxColor && presBoxColor !== 'white' && presBoxColor !== 'transparent' ? (isCurrent ? '0 0 0px 1.5px' + presBoxColor : undefined) : undefined, border: presBoxColor && presBoxColor !== 'white' && presBoxColor !== 'transparent' ? (isCurrent ? presBoxColor + ' solid 2.5px' : undefined) : undefined, }}> @@ -601,7 +578,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { style={{ display: 'inline-flex', pointerEvents: isSelected ? undefined : 'none', - width: `calc(100% ${this.rootDoc.presentation_expandInlineButton ? '- 50%' : ''} - ${this.presButtons.length * 22}px`, + width: `calc(100% ${this.slideDoc.presentation_expandInlineButton ? '- 50%' : ''} - ${this.presButtons.length * 22}px`, cursor: isSelected ? 'text' : 'grab', }}> <div @@ -629,6 +606,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { } render() { - return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? null : this.mainItem; + return !(this.slideDoc instanceof Doc) || this.targetDoc instanceof Promise ? null : this.mainItem; } } |
