aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/PresBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/PresBox.tsx')
-rw-r--r--src/client/views/nodes/PresBox.tsx138
1 files changed, 95 insertions, 43 deletions
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 06d8e688b..6c4cbba12 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -2,11 +2,10 @@ import React = require("react");
import { library } from '@fortawesome/fontawesome-svg-core';
import { faArrowLeft, faArrowRight, faEdit, faMinus, faPlay, faPlus, faStop, faTimes } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, IReactionDisposer, reaction } from "mobx";
+import { action, computed, IReactionDisposer, reaction, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
-import { listSpec } from "../../../new_fields/Schema";
-import { ComputedField } from "../../../new_fields/ScriptField";
+import { listSpec, makeInterface } from "../../../new_fields/Schema";
import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
import { Docs } from "../../documents/Documents";
@@ -17,7 +16,13 @@ import { CollectionView, CollectionViewType } from "../collections/CollectionVie
import { ContextMenu } from "../ContextMenu";
import { FieldView, FieldViewProps } from './FieldView';
import "./PresBox.scss";
-import { presSchema } from "../presentationview/PresElementBox";
+import { CollectionCarouselView } from "../collections/CollectionCarouselView";
+import { returnFalse } from "../../../Utils";
+import { ContextMenuProps } from "../ContextMenuItem";
+import { CollectionTimeView } from "../collections/CollectionTimeView";
+import { documentSchema } from "../../../new_fields/documentSchemas";
+import { InkingControl } from "../InkingControl";
+import { InkTool } from "../../../new_fields/InkField";
library.add(faArrowLeft);
library.add(faArrowRight);
@@ -31,24 +36,41 @@ library.add(faEdit);
@observer
export class PresBox extends React.Component<FieldViewProps> {
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); }
+ _childReaction: IReactionDisposer | undefined;
+ _slideshowReaction: IReactionDisposer | undefined;
+ @observable _isChildActive = false;
+
componentDidMount() {
const userDoc = CurrentUserUtils.UserDocument;
- let presTemp = Cast(userDoc.presentationTemplate, Doc);
- if (presTemp instanceof Promise) {
- presTemp.then(presTemp => this.props.Document.childLayout = presTemp);
- }
- else if (presTemp === undefined) {
- presTemp = userDoc.presentationTemplate = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent", _xMargin: 5, isTemplateDoc: true, isTemplateForField: "data" });
- }
- else {
- this.props.Document.childLayout = presTemp;
- }
+ this._slideshowReaction = reaction(() => this.props.Document._slideshow,
+ (slideshow) => {
+ if (!slideshow) {
+ let presTemp = Cast(userDoc.presentationTemplate, Doc);
+ if (presTemp instanceof Promise) {
+ presTemp.then(presTemp => this.props.Document.childLayout = presTemp);
+ }
+ else if (presTemp === undefined) {
+ presTemp = userDoc.presentationTemplate = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent", _xMargin: 5, isTemplateDoc: true, isTemplateForField: "data" });
+ }
+ else {
+ this.props.Document.childLayout = presTemp;
+ }
+ } else {
+ this.props.Document.childLayout = undefined;
+ }
+ }, { fireImmediately: true });
+ this._childReaction = reaction(() => this.childDocs.slice(), (children) => children.forEach((child, i) => child.presentationIndex = i), { fireImmediately: true });
+ }
+ componentWillUnmount() {
+ this._childReaction?.();
+ this._slideshowReaction?.();
}
@computed get childDocs() { return DocListCast(this.props.Document[this.props.fieldKey]); }
next = async () => {
- const current = NumCast(this.props.Document.selectedDoc);
+ runInAction(() => Doc.UserDoc().curPresentation = this.props.Document);
+ const current = NumCast(this.props.Document._itemIndex);
//asking to get document at current index
const docAtCurrentNext = await this.getDocAtIndex(current + 1);
if (docAtCurrentNext !== undefined) {
@@ -65,7 +87,8 @@ export class PresBox extends React.Component<FieldViewProps> {
}
}
back = async () => {
- const current = NumCast(this.props.Document.selectedDoc);
+ action(() => Doc.UserDoc().curPresentation = this.props.Document);
+ const current = NumCast(this.props.Document._itemIndex);
//requesting for the doc at current index
const docAtCurrent = await this.getDocAtIndex(current);
if (docAtCurrent !== undefined) {
@@ -104,12 +127,17 @@ export class PresBox extends React.Component<FieldViewProps> {
}
}
+ whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive));
+ active = (outsideReaction?: boolean) => ((InkingControl.Instance.selectedTool === InkTool.None && !this.props.Document.isBackground) &&
+ (this.props.Document.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
+
/**
* This is the method that checks for the actions that need to be performed
* after the document has been presented, which involves 3 button options:
* Hide Until Presented, Hide After Presented, Fade After Presented
*/
showAfterPresented = (index: number) => {
+ action(() => Doc.UserDoc().curPresentation = this.props.Document);
this.childDocs.forEach((doc, ind) => {
//the order of cases is aligned based on priority
if (doc.hideTillShownButton && ind <= index) {
@@ -130,6 +158,7 @@ export class PresBox extends React.Component<FieldViewProps> {
* Hide Until Presented, Hide After Presented, Fade After Presented
*/
hideIfNotPresented = (index: number) => {
+ action(() => Doc.UserDoc().curPresentation = this.props.Document);
this.childDocs.forEach((key, ind) => {
//the order of cases is aligned based on priority
@@ -151,6 +180,7 @@ export class PresBox extends React.Component<FieldViewProps> {
* te option open, navigates to that element.
*/
navigateToElement = async (curDoc: Doc, fromDocIndex: number) => {
+ action(() => Doc.UserDoc().curPresentation = this.props.Document);
const fromDoc = this.childDocs[fromDocIndex].presentationTargetDoc as Doc;
let docToJump = curDoc;
let willZoom = false;
@@ -177,15 +207,17 @@ export class PresBox extends React.Component<FieldViewProps> {
});
//docToJump stayed same meaning, it was not in the group or was the last element in the group
+ const aliasOf = await Cast(docToJump.aliasOf, Doc);
+ const srcContext = aliasOf && await Cast(aliasOf.sourceContext, Doc);
if (docToJump === curDoc) {
//checking if curDoc has navigation open
- const target = await curDoc.presentationTargetDoc as Doc;
- if (curDoc.navButton) {
- DocumentManager.Instance.jumpToDocument(target, false);
- } else if (curDoc.showButton) {
+ const target = await Cast(curDoc.presentationTargetDoc, Doc);
+ if (curDoc.navButton && target) {
+ DocumentManager.Instance.jumpToDocument(target, false, undefined, srcContext);
+ } else if (curDoc.showButton && target) {
const curScale = DocumentManager.Instance.getScaleOfDocView(fromDoc);
//awaiting jump so that new scale can be found, since jumping is async
- await DocumentManager.Instance.jumpToDocument(target, true);
+ await DocumentManager.Instance.jumpToDocument(target, true, undefined, srcContext);
curDoc.viewScale = DocumentManager.Instance.getScaleOfDocView(target);
//saving the scale user was on before zooming in
@@ -199,7 +231,8 @@ export class PresBox extends React.Component<FieldViewProps> {
const curScale = DocumentManager.Instance.getScaleOfDocView(fromDoc);
//awaiting jump so that new scale can be found, since jumping is async
- await DocumentManager.Instance.jumpToDocument(await docToJump.presentationTargetDoc as Doc, willZoom);
+ const presTargetDoc = await docToJump.presentationTargetDoc as Doc;
+ await DocumentManager.Instance.jumpToDocument(presTargetDoc, willZoom, undefined, srcContext);
const newScale = DocumentManager.Instance.getScaleOfDocView(await curDoc.presentationTargetDoc as Doc);
curDoc.viewScale = newScale;
//saving the scale that user was on
@@ -215,7 +248,7 @@ export class PresBox extends React.Component<FieldViewProps> {
getDocAtIndex = async (index: number) => {
const list = FieldValue(Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)));
if (list && index >= 0 && index < list.length) {
- this.props.Document.selectedDoc = index;
+ this.props.Document._itemIndex = index;
//awaiting async call to finish to get Doc instance
return list[index];
}
@@ -238,12 +271,12 @@ export class PresBox extends React.Component<FieldViewProps> {
//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.
- @action
public gotoDocument = async (index: number, fromDoc: number) => {
+ action(() => Doc.UserDoc().curPresentation = this.props.Document);
Doc.UnBrushAllDocs();
const list = FieldValue(Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)));
if (list && index >= 0 && index < list.length) {
- this.props.Document.selectedDoc = index;
+ this.props.Document._itemIndex = index;
if (!this.props.Document.presStatus) {
this.props.Document.presStatus = true;
@@ -260,14 +293,14 @@ export class PresBox extends React.Component<FieldViewProps> {
}
//The function that starts or resets presentaton functionally, depending on status flag.
- @action
startOrResetPres = () => {
+ action(() => Doc.UserDoc().curPresentation = this.props.Document);
if (this.props.Document.presStatus) {
this.resetPresentation();
} else {
this.props.Document.presStatus = true;
this.startPresentation(0);
- this.gotoDocument(0, NumCast(this.props.Document.selectedDoc));
+ this.gotoDocument(0, NumCast(this.props.Document._itemIndex));
}
}
@@ -280,13 +313,13 @@ export class PresBox extends React.Component<FieldViewProps> {
//The function that resets the presentation by removing every action done by it. It also
//stops the presentaton.
- @action
resetPresentation = () => {
+ action(() => Doc.UserDoc().curPresentation = this.props.Document);
this.childDocs.forEach((doc: Doc) => {
doc.opacity = 1;
doc.viewScale = 1;
});
- this.props.Document.selectedDoc = 0;
+ this.props.Document._itemIndex = 0;
this.props.Document.presStatus = false;
if (this.childDocs.length !== 0) {
DocumentManager.Instance.zoomIntoScale(this.childDocs[0], 1);
@@ -296,6 +329,7 @@ export class PresBox extends React.Component<FieldViewProps> {
//The function that starts the presentation, also checking if actions should be applied
//directly at start.
startPresentation = (startIndex: number) => {
+ action(() => Doc.UserDoc().curPresentation = this.props.Document);
this.childDocs.map(doc => {
if (doc.hideTillShownButton && this.childDocs.indexOf(doc) > startIndex) {
doc.opacity = 0;
@@ -323,14 +357,17 @@ export class PresBox extends React.Component<FieldViewProps> {
}));
specificContextMenu = (e: React.MouseEvent): void => {
- ContextMenu.Instance.addItem({ description: "Make Current Presentation", event: action(() => Doc.UserDoc().curPresentation = this.props.Document), icon: "asterisk" });
+ const funcs: ContextMenuProps[] = [];
+ funcs.push({ description: "Show as Slideshow", event: action(() => this.props.Document._slideshow = "slideshow"), icon: "asterisk" });
+ funcs.push({ description: "Show as Timeline", event: action(() => this.props.Document._slideshow = "timeline"), icon: "asterisk" });
+ funcs.push({ description: "Show as List", event: action(() => this.props.Document._slideshow = undefined), icon: "asterisk" });
+ ContextMenu.Instance.addItem({ description: "Presentation Funcs...", subitems: funcs, icon: "asterisk" });
}
/**
* Initially every document starts with a viewScale 1, which means
* that they will be displayed in a canvas with scale 1.
*/
- @action
initializeScaleViews = (docList: Doc[], viewtype: number) => {
this.props.Document._chromeStatus = "disabled";
const hgt = (viewtype === CollectionViewType.Tree) ? 50 : 46;
@@ -346,19 +383,37 @@ export class PresBox extends React.Component<FieldViewProps> {
});
}
-
selectElement = (doc: Doc) => {
const index = DocListCast(this.props.Document[this.props.fieldKey]).indexOf(doc);
- index !== -1 && this.gotoDocument(index, NumCast(this.props.Document.selectedDoc));
+ index !== -1 && this.gotoDocument(index, NumCast(this.props.Document._itemIndex));
}
getTransform = () => {
return this.props.ScreenToLocalTransform().translate(0, -50);// listBox padding-left and pres-box-cont minHeight
}
+ panelHeight = () => {
+ return this.props.PanelHeight() - 20;
+ }
render() {
this.initializeScaleViews(this.childDocs, NumCast(this.props.Document._viewType));
- return (
- <div className="presBox-cont" onContextMenu={this.specificContextMenu}>
+ return (this.props.Document._slideshow ?
+ <div className="presBox-cont" onContextMenu={this.specificContextMenu} style={{ pointerEvents: this.active() ? "all" : "none" }} >
+ {this.props.Document.inOverlay ? (null) :
+ <div className="presBox-listCont" >
+ {this.props.Document._slideshow === "slideshow" ?
+ <CollectionCarouselView {...this.props} PanelHeight={this.panelHeight} chromeCollapsed={true} annotationsKey={""} CollectionView={undefined}
+ moveDocument={returnFalse}
+ addDocument={this.addDocument} removeDocument={returnFalse} focus={this.selectElement} ScreenToLocalTransform={this.getTransform} />
+ :
+ <CollectionTimeView {...this.props} PanelHeight={this.panelHeight} chromeCollapsed={true} annotationsKey={""} CollectionView={undefined}
+ moveDocument={returnFalse}
+ addDocument={this.addDocument} removeDocument={returnFalse} focus={this.selectElement} ScreenToLocalTransform={this.getTransform} />
+ }
+ </div>}
+ <button className="presBox-backward" title="Back" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></button>
+ <button className="presBox-forward" title="Next" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></button>
+ </div>
+ : <div className="presBox-cont" onContextMenu={this.specificContextMenu}>
<div className="presBox-buttons">
<button className="presBox-button" title="Back" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></button>
<button className="presBox-button" title={"Reset Presentation" + this.props.Document.presStatus ? "" : " From Start"} onClick={this.startOrResetPres}>
@@ -366,13 +421,10 @@ export class PresBox extends React.Component<FieldViewProps> {
</button>
<button className="presBox-button" title="Next" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></button>
<button className="presBox-button" title={this.props.Document.inOverlay ? "Expand" : "Minimize"} onClick={this.toggleMinimize}><FontAwesomeIcon icon={"eye"} /></button>
- </div>
- {this.props.Document.inOverlay ? (null) :
- <div className="presBox-listCont" >
- <CollectionView {...this.props} addDocument={this.addDocument} focus={this.selectElement} ScreenToLocalTransform={this.getTransform} />
- </div>
- }
- </div>
- );
+ {this.props.Document.inOverlay ? (null) :
+ <div className="presBox-listCont">
+ <CollectionView {...this.props} whenActiveChanged={this.whenActiveChanged} PanelHeight={this.panelHeight} addDocument={this.addDocument} focus={this.selectElement} ScreenToLocalTransform={this.getTransform} />
+ </div>}
+ </div></div>);
}
} \ No newline at end of file