diff options
-rw-r--r-- | src/client/documents/DocumentTypes.ts | 2 | ||||
-rw-r--r-- | src/client/documents/Documents.ts | 5 | ||||
-rw-r--r-- | src/client/views/MainView.tsx | 1 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 31 | ||||
-rw-r--r-- | src/client/views/nodes/PresBox.tsx | 165 | ||||
-rw-r--r-- | src/client/views/presentationview/PresentationElement.tsx | 19 | ||||
-rw-r--r-- | src/client/views/presentationview/PresentationList.tsx | 9 | ||||
-rw-r--r-- | src/client/views/presentationview/PresentationModeMenu.scss | 30 | ||||
-rw-r--r-- | src/client/views/presentationview/PresentationModeMenu.tsx | 101 | ||||
-rw-r--r-- | src/new_fields/Doc.ts | 22 |
10 files changed, 105 insertions, 280 deletions
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 381981e1b..8ec6e9642 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -19,5 +19,5 @@ export enum DocumentType { YOUTUBE = "youtube", DRAGBOX = "dragbox", PRES = "presentation", - LINKFOLLOW = "linkfollow", + LINKFOLLOW = "linkfollow" }
\ No newline at end of file diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index d1ec2ac39..01c36182f 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -46,8 +46,6 @@ import { ComputedField } from "../../new_fields/ScriptField"; import { ProxyField } from "../../new_fields/Proxy"; import { DocumentType } from "./DocumentTypes"; import { LinkFollowBox } from "../views/linking/LinkFollowBox"; -//import { PresBox } from "../views/nodes/PresBox"; -//import { PresField } from "../../new_fields/PresField"; var requestImageSize = require('../util/request-image-size'); var path = require('path'); @@ -176,7 +174,7 @@ export namespace Docs { }], [DocumentType.LINKFOLLOW, { layout: { view: LinkFollowBox } - }] + }], ]); // All document prototypes are initialized with at least these values @@ -459,7 +457,6 @@ export namespace Docs { export function LinkFollowBoxDocument(options?: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.LINKFOLLOW), undefined, { ...(options || {}) }); } - export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) { return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, viewType: CollectionViewType.Docking, dockingConfig: config }, id); } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index dadff21a7..35d527c91 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -634,7 +634,6 @@ export class MainView extends React.Component { <SharingManager /> <DocumentDecorations /> {this.mainContent} - {PresBox.miniPresentation} <PreviewCursor /> <ContextMenu /> {this.nodesMenu()} diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 3c3cc0d91..d035cbe18 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -1,37 +1,34 @@ -import { computed, trace } from "mobx"; +import { computed } from "mobx"; import { observer } from "mobx-react"; +import { Doc } from "../../../new_fields/Doc"; +import { ScriptField } from "../../../new_fields/ScriptField"; +import { Cast } from "../../../new_fields/Types"; +import { OmitKeys, Without } from "../../../Utils"; +import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox"; +import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; import { CollectionPDFView } from "../collections/CollectionPDFView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionVideoView } from "../collections/CollectionVideoView"; import { CollectionView } from "../collections/CollectionView"; +import { LinkFollowBox } from "../linking/LinkFollowBox"; +import { YoutubeBox } from "./../../apis/youtube/YoutubeBox"; import { AudioBox } from "./AudioBox"; +import { ButtonBox } from "./ButtonBox"; import { DocumentViewProps } from "./DocumentView"; import "./DocumentView.scss"; -import { FormattedTextBox } from "./FormattedTextBox"; -import { ImageBox } from "./ImageBox"; import { DragBox } from "./DragBox"; -import { ButtonBox } from "./ButtonBox"; -import { PresBox } from "./PresBox"; -import { LinkFollowBox } from "../linking/LinkFollowBox"; +import { FieldView, FieldViewProps } from "./FieldView"; +import { FormattedTextBox } from "./FormattedTextBox"; import { IconBox } from "./IconBox"; +import { ImageBox } from "./ImageBox"; import { KeyValueBox } from "./KeyValueBox"; import { PDFBox } from "./PDFBox"; +import { PresBox } from "./PresBox"; import { VideoBox } from "./VideoBox"; -import { FieldView } from "./FieldView"; import { WebBox } from "./WebBox"; -import { YoutubeBox } from "./../../apis/youtube/YoutubeBox"; -import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox"; import React = require("react"); -import { FieldViewProps } from "./FieldView"; -import { Without, OmitKeys } from "../../../Utils"; -import { Cast, StrCast, NumCast } from "../../../new_fields/Types"; -import { List } from "../../../new_fields/List"; -import { Doc } from "../../../new_fields/Doc"; -import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox"; -import { ScriptField } from "../../../new_fields/ScriptField"; -import { fromPromise } from "mobx-utils"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? type BindingProps = Without<FieldViewProps, 'fieldKey'>; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index d246da87a..e2dac4fd3 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -2,20 +2,19 @@ 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, observable, runInAction, computed } from "mobx"; +import { action, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast } from "../../../new_fields/Doc"; +import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc"; import { listSpec } from "../../../new_fields/Schema"; import { BoolCast, Cast, FieldValue, NumCast } from "../../../new_fields/Types"; +import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; import { DocumentManager } from "../../util/DocumentManager"; import { undoBatch } from "../../util/UndoManager"; +import { CollectionDockingView } from "../collections/CollectionDockingView"; import { ContextMenu } from "../ContextMenu"; -import PresentationElement from "../presentationview/PresentationElement"; import PresentationViewList from "../presentationview/PresentationList"; import "../presentationview/PresentationView.scss"; import { FieldView, FieldViewProps } from './FieldView'; -import PresModeMenu from "../presentationview/PresentationModeMenu"; -import { CollectionDockingView } from "../collections/CollectionDockingView"; library.add(faArrowLeft); library.add(faArrowRight); @@ -31,31 +30,13 @@ export class PresBox extends React.Component<FieldViewProps> { public static LayoutString(fieldKey?: string) { return FieldView.LayoutString(PresBox, fieldKey); } public static Instance: PresBox; - //mapping from docs to their rendered component - @observable _presElementsMappings: Map<Doc, PresentationElement> = new Map(); //variable that holds all the docs in the presentation @observable _childrenDocs: Doc[] = []; - @observable _opacity = 1; - @observable _persistOpacity = true; - @observable _labelOpacity = 0; // whether presentation view has been minimized @observable _presMode = false; @observable public static CurrentPresentation: PresBox; - @computed static get miniPresentation() { - let next = () => PresBox.CurrentPresentation.next(); - let back = () => PresBox.CurrentPresentation.back(); - let startOrResetPres = () => PresBox.CurrentPresentation.startOrResetPres(); - let closePresMode = action(() => { - PresBox.CurrentPresentation._presMode = false; - CollectionDockingView.AddRightSplit(PresBox.CurrentPresentation.props.Document, undefined); - }); - return !PresBox.CurrentPresentation || !PresBox.CurrentPresentation._presMode ? (null) : - <PresModeMenu next={next} back={back} presStatus={BoolCast(PresBox.CurrentPresentation.props.Document.presStatus)} - startOrResetPres={startOrResetPres} closePresMode={closePresMode} />; - } - //initilize class variables constructor(props: FieldViewProps) { super(props); @@ -71,7 +52,7 @@ export class PresBox extends React.Component<FieldViewProps> { let nextSelected = current + 1; for (; nextSelected < presDocs.length - 1; nextSelected++) { - if (!this._presElementsMappings.get(presDocs[nextSelected + 1])!.props.document.groupButton) { + if (!presDocs[nextSelected + 1].groupButton) { break; } } @@ -89,18 +70,16 @@ export class PresBox extends React.Component<FieldViewProps> { let prevSelected = current; let zoomOut: boolean = false; - //checking if this presentation id is mapped to a group, if so chosing the first element in group - let presDocs = DocListCast(this.props.Document.data); + let presDocs = await DocListCastAsync(this.props.Document[this.props.fieldKey]); let currentsArray: Doc[] = []; - for (; prevSelected > 0 && presDocs[prevSelected].groupButton; prevSelected--) { + for (; presDocs && prevSelected > 0 && presDocs[prevSelected].groupButton; prevSelected--) { currentsArray.push(presDocs[prevSelected]); } prevSelected = Math.max(0, prevSelected - 1); //checking if any of the group members had used zooming in currentsArray.forEach((doc: Doc) => { - //let presElem: PresentationElement | undefined = this.presElementsMappings.get(doc); - if (this._presElementsMappings.get(doc)!.props.document.showButton) { + if (doc.showButton) { zoomOut = true; return; } @@ -109,7 +88,7 @@ export class PresBox extends React.Component<FieldViewProps> { // if a group set that flag to zero or a single element //If so making sure to zoom out, which goes back to state before zooming action if (current > 0) { - if (zoomOut || this._presElementsMappings.get(docAtCurrent)!.showButton) { + if (zoomOut || docAtCurrent.showButton) { let prevScale = NumCast(this._childrenDocs[prevSelected].viewScale, null); let curScale = DocumentManager.Instance.getScaleOfDocView(this._childrenDocs[current]); if (prevScale !== undefined && prevScale !== curScale) { @@ -127,20 +106,20 @@ export class PresBox extends React.Component<FieldViewProps> { * Hide Until Presented, Hide After Presented, Fade After Presented */ showAfterPresented = (index: number) => { - this._presElementsMappings.forEach((presElem, doc) => { + this._childrenDocs.forEach((doc, ind) => { //the order of cases is aligned based on priority - if (presElem.props.document.hideTillShownButton) { - if (this._childrenDocs.indexOf(doc) <= index) { + if (doc.hideTillShownButton) { + if (ind <= index) { doc.opacity = 1; } } - if (presElem.props.document.hideAfterButton) { - if (this._childrenDocs.indexOf(doc) < index) { + if (doc.hideAfterButton) { + if (ind < index) { doc.opacity = 0; } } - if (presElem.props.document.fadeButton) { - if (this._childrenDocs.indexOf(doc) < index) { + if (doc.fadeButton) { + if (ind < index) { doc.opacity = 0.5; } } @@ -153,21 +132,21 @@ export class PresBox extends React.Component<FieldViewProps> { * Hide Until Presented, Hide After Presented, Fade After Presented */ hideIfNotPresented = (index: number) => { - this._presElementsMappings.forEach((presElem, key) => { + this._childrenDocs.forEach((key, ind) => { //the order of cases is aligned based on priority - if (presElem.props.document.hideAfterButton) { - if (this._childrenDocs.indexOf(key) >= index) { + if (key.hideAfterButton) { + if (ind >= index) { key.opacity = 1; } } - if (presElem.props.document.fadeButton) { - if (this._childrenDocs.indexOf(key) >= index) { + if (key.fadeButton) { + if (ind >= index) { key.opacity = 1; } } - if (presElem.props.document.hideTillShownButton) { - if (this._childrenDocs.indexOf(key) > index) { + if (key.hideTillShownButton) { + if (ind > index) { key.opacity = 0; } } @@ -187,18 +166,18 @@ export class PresBox extends React.Component<FieldViewProps> { let nextSelected = presDocs.indexOf(curDoc); let currentDocGroups: Doc[] = []; for (; nextSelected < presDocs.length - 1; nextSelected++) { - if (!this._presElementsMappings.get(presDocs[nextSelected + 1])!.props.document.groupButton) { + if (!presDocs[nextSelected + 1].groupButton) { break; } currentDocGroups.push(presDocs[nextSelected]); } currentDocGroups.forEach((doc: Doc, index: number) => { - if (this._presElementsMappings.get(doc)!.navButton) { + if (doc.navButton) { docToJump = doc; willZoom = false; } - if (this._presElementsMappings.get(doc)!.showButton) { + if (doc.showButton) { docToJump = doc; willZoom = true; } @@ -207,9 +186,9 @@ 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 if (docToJump === curDoc) { //checking if curDoc has navigation open - if (this._presElementsMappings.get(curDoc)!.navButton) { + if (curDoc.navButton) { DocumentManager.Instance.jumpToDocument(curDoc, false); - } else if (this._presElementsMappings.get(curDoc)!.showButton) { + } else if (curDoc.showButton) { let curScale = DocumentManager.Instance.getScaleOfDocView(this._childrenDocs[fromDoc]); //awaiting jump so that new scale can be found, since jumping is async await DocumentManager.Instance.jumpToDocument(curDoc, true); @@ -250,15 +229,13 @@ export class PresBox extends React.Component<FieldViewProps> { } /** - * The function that removes a doc from a presentation. It also makes sure to - * do necessary updates to backUps and mappings stored locally. + * The function that removes a doc from a presentation. */ @action public RemoveDoc = async (index: number) => { const value = FieldValue(Cast(this.props.Document.data, listSpec(Doc))); // don't replace with DocListCast -- we need to modify the document's actual stored list if (value) { - //removing the Presentation Element from the document and update mappings - this._presElementsMappings.delete(await value.splice(index, 1)[0]); + value.splice(index, 1); } } @@ -302,14 +279,6 @@ export class PresBox extends React.Component<FieldViewProps> { this._childrenDocs = docList; } - //The function that is called to render the play or pause button depending on - //if presentation is running or not. - renderPlayPauseButton = () => { - return <button title={"Reset Presentation" + this.props.Document.presStatus ? "" : " From Start"} className="presentation-button" onClick={this.startOrResetPres}> - <FontAwesomeIcon icon={this.props.Document.presStatus ? "stop" : "play"} /> - </button>; - } - //The function that starts or resets presentaton functionally, depending on status flag. @action startOrResetPres = () => { @@ -340,18 +309,18 @@ 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) => { - this._presElementsMappings.forEach((component, doc) => { - if (component.props.document.hideTillShownButton) { + this._childrenDocs.map(doc => { + if (doc.hideTillShownButton) { if (this._childrenDocs.indexOf(doc) > startIndex) { doc.opacity = 0; } } - if (component.props.document.hideAfterButton) { + if (doc.hideAfterButton) { if (this._childrenDocs.indexOf(doc) < startIndex) { doc.opacity = 0; } } - if (component.props.document.fadeButton) { + if (doc.fadeButton) { if (this._childrenDocs.indexOf(doc) < startIndex) { doc.opacity = 0.5; } @@ -359,13 +328,18 @@ export class PresBox extends React.Component<FieldViewProps> { }); } - addPressElem = (keyDoc: Doc, elem: PresentationElement) => { - this._presElementsMappings.set(keyDoc, elem); - } - - minimize = undoBatch(action(() => { - this._presMode = true; - this.props.addDocTab && this.props.addDocTab(this.props.Document, this.props.DataDoc, "close"); + toggleMinimize = undoBatch(action((e: React.PointerEvent) => { + if (this.props.Document.minimizedView) { + this.props.Document.minimizedView = false; + Doc.RemoveDocFromList((CurrentUserUtils.UserDocument.overlays as Doc), "data", this.props.Document); + CollectionDockingView.AddRightSplit(this.props.Document, this.props.DataDoc); + } else { + this.props.Document.minimizedView = true; + this.props.Document.x = e.clientX + 25; + this.props.Document.y = e.clientY - 25; + this.props.addDocTab && this.props.addDocTab(this.props.Document, this.props.DataDoc, "close"); + Doc.AddDocToList((CurrentUserUtils.UserDocument.overlays as Doc), "data", this.props.Document); + } })); specificContextMenu = (e: React.MouseEvent): void => { @@ -374,37 +348,24 @@ export class PresBox extends React.Component<FieldViewProps> { render() { return ( - <div className="presentationView-cont" onPointerEnter={action(() => !this._persistOpacity && (this._opacity = 1))} onContextMenu={this.specificContextMenu} - onPointerLeave={action(() => !this._persistOpacity && (this._opacity = 0.4))} - style={{ width: "100%", opacity: this._opacity, }}> - <div className="presentation-buttons"> - <button title="Back" className="presentation-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></button> - {this.renderPlayPauseButton()} - <button title="Next" className="presentation-button" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></button> - <button title="Minimize" className="presentation-button" onClick={this.minimize}><FontAwesomeIcon icon={"eye"} /></button> + <div className="presentationView-cont" onContextMenu={this.specificContextMenu} style={{ width: "100%", minWidth: "200px", height: "100%", minHeight: "50px" }}> + <div className="presentation-buttons" style={{ width: "100%" }}> + <button className="presentation-button" title="Back" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></button> + <button className="presentation-button" title={"Reset Presentation" + this.props.Document.presStatus ? "" : " From Start"} onClick={this.startOrResetPres}> + <FontAwesomeIcon icon={this.props.Document.presStatus ? "stop" : "play"} /> + </button> + <button className="presentation-button" title="Next" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></button> + <button className="presentation-button" title={this.props.Document.minimizedView ? "Expand" : "Minimize"} onClick={this.toggleMinimize}><FontAwesomeIcon icon={"eye"} /></button> </div> - <input - type="checkbox" - onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { - this._persistOpacity = e.target.checked; - this._opacity = this._persistOpacity ? 1 : 0.4; - })} - checked={this._persistOpacity} - style={{ position: "absolute", bottom: 5, left: 5 }} - onPointerEnter={action(() => this._labelOpacity = 1)} - onPointerLeave={action(() => this._labelOpacity = 0)} - /> - <p style={{ position: "absolute", bottom: 1, left: 22, opacity: this._labelOpacity, transition: "0.7s opacity ease" }}>opacity {this._persistOpacity ? "persistent" : "on focus"}</p> - <PresentationViewList - mainDocument={this.props.Document} - deleteDocument={this.RemoveDoc} - gotoDocument={this.gotoDocument} - PresElementsMappings={this._presElementsMappings} - setChildrenDocs={this.setChildrenDocs} - presStatus={BoolCast(this.props.Document.presStatus)} - removeDocByRef={this.removeDocByRef} - clearElemMap={() => this._presElementsMappings.clear()} - /> + {this.props.Document.minimizedView ? (null) : + <PresentationViewList + mainDocument={this.props.Document} + deleteDocument={this.RemoveDoc} + gotoDocument={this.gotoDocument} + setChildrenDocs={this.setChildrenDocs} + presStatus={BoolCast(this.props.Document.presStatus)} + removeDocByRef={this.removeDocByRef} + />} </div> ); } diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index 126d62c52..6e8c28d34 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -1,6 +1,6 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faFile as fileRegular } from '@fortawesome/free-regular-svg-icons'; -import { faArrowRight, faArrowUp, faFile as fileSolid, faFileDownload, faLocationArrow, faSearch } from '@fortawesome/free-solid-svg-icons'; +import { faArrowDown, faArrowUp, faFile as fileSolid, faFileDownload, faLocationArrow, faSearch } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed } from "mobx"; import { observer } from "mobx-react"; @@ -22,7 +22,7 @@ library.add(fileSolid); library.add(faLocationArrow); library.add(fileRegular as any); library.add(faSearch); -library.add(faArrowRight); +library.add(faArrowDown); interface PresentationElementProps { mainDocument: Doc; @@ -33,7 +33,6 @@ interface PresentationElementProps { allListElements: Doc[]; presStatus: boolean; removeDocByRef(doc: Doc): boolean; - PresElementsMappings: Map<Doc, PresentationElement>; } /** @@ -59,14 +58,14 @@ export default class PresentationElement extends React.Component<PresentationEle @computed get fadeButton() { return BoolCast(this.props.document.fadeButton); } @computed get hideAfterButton() { return BoolCast(this.props.document.hideAfterButton); } @computed get groupButton() { return BoolCast(this.props.document.groupButton); } - @computed get openRightButton() { return BoolCast(this.props.document.openRightButton); } + @computed get expandInlineButton() { return BoolCast(this.props.document.expandInlineButton); } set showButton(val: boolean) { this.props.document.showButton = val; } set navButton(val: boolean) { this.props.document.navButton = val; } set hideTillShownButton(val: boolean) { this.props.document.hideTillShownButton = val; } set fadeButton(val: boolean) { this.props.document.fadeButton = val; } set hideAfterButton(val: boolean) { this.props.document.hideAfterButton = val; } set groupButton(val: boolean) { this.props.document.groupButton = val; } - set openRightButton(val: boolean) { this.props.document.openRightButton = val; } + set expandInlineButton(val: boolean) { this.props.document.expandInlineButton = val; } //Lifecycle function that makes sure that button BackUp is received when mounted. async componentDidMount() { @@ -190,14 +189,12 @@ export default class PresentationElement extends React.Component<PresentationEle } /** - * Function that opens up the option to open a element on right when navigated, - * instead of openening it as tab as default. + * Function that expands the target inline */ @action - onRightTabClick = (e: React.MouseEvent) => { + onExpandTabClick = (e: React.MouseEvent) => { e.stopPropagation(); - - this.openRightButton = !this.openRightButton; + this.embedInline = !this.embedInline } /** @@ -416,7 +413,7 @@ export default class PresentationElement extends React.Component<PresentationEle <button title="Fade Document After Presented" className={this.fadeButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button> <button title="Hide Document After Presented" className={this.hideAfterButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button> <button title="Group With Up" className={this.groupButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onGroupClick}> <FontAwesomeIcon icon={"arrow-up"} /> </button> - <button title="Open Right" className={this.openRightButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onRightTabClick}><FontAwesomeIcon icon={"arrow-right"} /></button> + <button title="Expand Inline" className={this.expandInlineButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onExpandTabClick}><FontAwesomeIcon icon={"arrow-down"} /></button> <br /> {this.renderEmbeddedInline()} diff --git a/src/client/views/presentationview/PresentationList.tsx b/src/client/views/presentationview/PresentationList.tsx index da48a856a..483461e5a 100644 --- a/src/client/views/presentationview/PresentationList.tsx +++ b/src/client/views/presentationview/PresentationList.tsx @@ -12,11 +12,9 @@ interface PresListProps { mainDocument: Doc; deleteDocument(index: number): void; gotoDocument(index: number, fromDoc: number): Promise<void>; - PresElementsMappings: Map<Doc, PresentationElement>; setChildrenDocs: (docList: Doc[]) => void; presStatus: boolean; removeDocByRef(doc: Doc): boolean; - clearElemMap(): void; } @@ -45,16 +43,10 @@ export default class PresentationViewList extends React.Component<PresListProps> const children = DocListCast(this.props.mainDocument.data); this.initializeScaleViews(children); this.props.setChildrenDocs(children); - this.props.clearElemMap(); return ( <div className="presentationView-listCont" > {children.map((doc: Doc, index: number) => <PresentationElement - ref={(e) => { - if (e && e !== null) { - this.props.PresElementsMappings.set(doc, e); - } - }} key={doc[Id]} mainDocument={this.props.mainDocument} document={doc} @@ -64,7 +56,6 @@ export default class PresentationViewList extends React.Component<PresListProps> allListElements={children} presStatus={this.props.presStatus} removeDocByRef={this.props.removeDocByRef} - PresElementsMappings={this.props.PresElementsMappings} /> )} </div> diff --git a/src/client/views/presentationview/PresentationModeMenu.scss b/src/client/views/presentationview/PresentationModeMenu.scss deleted file mode 100644 index 336f43d20..000000000 --- a/src/client/views/presentationview/PresentationModeMenu.scss +++ /dev/null @@ -1,30 +0,0 @@ -.presMenu-cont { - position: fixed; - z-index: 10000; - height: 35px; - background: #323232; - box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25); - border-radius: 0px 6px 6px 6px; - overflow: hidden; - display: flex; - - .presMenu-button { - background-color: transparent; - width: 35px; - height: 35px; - } - - .presMenu-button:hover { - background-color: #121212; - } - - .presMenu-dragger { - height: 100%; - transition: width .2s; - background-image: url("https://logodix.com/logo/1020374.png"); - background-size: 90% 100%; - background-repeat: no-repeat; - background-position: left center; - } - -}
\ No newline at end of file diff --git a/src/client/views/presentationview/PresentationModeMenu.tsx b/src/client/views/presentationview/PresentationModeMenu.tsx deleted file mode 100644 index e4123a1fe..000000000 --- a/src/client/views/presentationview/PresentationModeMenu.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import React = require("react"); -import { observable, action, runInAction } from "mobx"; -import "./PresentationModeMenu.scss"; -import { observer } from "mobx-react"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; - - -export interface PresModeMenuProps { - next: () => void; - back: () => void; - presStatus: boolean; - startOrResetPres: () => void; - closePresMode: () => void; -} - -/** - * This class is responsible for modeling of the Presentation Mode Menu. The menu allows - * user to navigate through presentation elements, and start/stop the presentation. - */ -@observer -export default class PresModeMenu extends React.Component<PresModeMenuProps> { - - @observable private _top: number = 20; - @observable private _left: number = window.innerWidth - 160; - @observable private _opacity: number = 1; - @observable private _transition: string = "opacity 0.5s"; - @observable private _transitionDelay: string = ""; - private _offsetY: number = 0; - private _offsetX: number = 0; - - - private _mainCont: React.RefObject<HTMLDivElement> = React.createRef(); - - /** - * The function that changes the coordinates of the menu, depending on the - * movement of the mouse when it's being dragged. - */ - @action - dragging = (e: PointerEvent) => { - this._left = e.pageX - this._offsetX; - this._top = e.pageY - this._offsetY; - - e.stopPropagation(); - e.preventDefault(); - } - - /** - * The function that removes the event listeners that are responsible for - * dragging of the menu. - */ - dragEnd = (e: PointerEvent) => { - document.removeEventListener("pointermove", this.dragging); - document.removeEventListener("pointerup", this.dragEnd); - e.stopPropagation(); - e.preventDefault(); - } - - /** - * The function that starts the dragging of the presentation mode menu. When - * the lines on further right are clicked on. - */ - dragStart = (e: React.PointerEvent) => { - document.removeEventListener("pointermove", this.dragging); - document.addEventListener("pointermove", this.dragging); - document.removeEventListener("pointerup", this.dragEnd); - document.addEventListener("pointerup", this.dragEnd); - - this._offsetX = this._mainCont.current!.getBoundingClientRect().width - e.nativeEvent.offsetX; - this._offsetY = e.nativeEvent.offsetY; - - e.stopPropagation(); - e.preventDefault(); - } - - /** - * The function that is responsible for rendering the play or pause button, depending on the - * status of the presentation. - */ - renderPlayPauseButton = () => { - if (this.props.presStatus) { - return <button title="Reset Presentation" className="presMenu-button" onClick={this.props.startOrResetPres}><FontAwesomeIcon icon="stop" /></button>; - } else { - return <button title="Start Presentation From Start" className="presMenu-button" onClick={this.props.startOrResetPres}><FontAwesomeIcon icon="play" /></button>; - } - } - - render() { - return ( - <div className="presMenu-cont" ref={this._mainCont} - style={{ left: this._left, top: this._top, opacity: this._opacity, transition: this._transition, transitionDelay: this._transitionDelay }}> - <button title="Back" className="presMenu-button" onClick={this.props.back}><FontAwesomeIcon icon={"arrow-left"} /></button> - {this.renderPlayPauseButton()} - <button title="Next" className="presMenu-button" onClick={this.props.next}><FontAwesomeIcon icon={"arrow-right"} /></button> - <button className="presMenu-button" title="Close Presentation Menu" onClick={this.props.closePresMode}> - <FontAwesomeIcon icon="times" size="lg" /> - </button> - <div className="presMenu-dragger" onPointerDown={this.dragStart} style={{ width: "20px" }} /> - </div > - ); - } -}
\ No newline at end of file diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 79b73aba8..4a03fed08 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -337,11 +337,25 @@ export namespace Doc { export function IndexOf(toFind: Doc, list: Doc[]) { return list.findIndex(doc => doc === toFind || Doc.AreProtosEqual(doc, toFind)); } - export function AddDocToList(target: Doc, key: string, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean, reversed?: boolean) { - if (target[key] === undefined) { - Doc.GetProto(target)[key] = new List<Doc>(); + export function RemoveDocFromList(listDoc: Doc, key: string, doc: Doc) { + if (listDoc[key] === undefined) { + Doc.GetProto(listDoc)[key] = new List<Doc>(); } - let list = Cast(target[key], listSpec(Doc)); + let list = Cast(listDoc[key], listSpec(Doc)); + if (list) { + let ind = list.indexOf(doc); + if (ind !== -1) { + list.splice(ind, 1); + return true; + } + } + return false; + } + export function AddDocToList(listDoc: Doc, key: string, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean, reversed?: boolean) { + if (listDoc[key] === undefined) { + Doc.GetProto(listDoc)[key] = new List<Doc>(); + } + let list = Cast(listDoc[key], listSpec(Doc)); if (list) { if (allowDuplicates !== true) { let pind = list.reduce((l, d, i) => d instanceof Doc && d[Id] === doc[Id] ? i : l, -1); |