aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/PresentationView.tsx
diff options
context:
space:
mode:
authorTyler Schicke <tyler_schicke@brown.edu>2019-05-07 16:29:02 -0400
committerTyler Schicke <tyler_schicke@brown.edu>2019-05-07 16:29:02 -0400
commit14c776b6d30e0bc0d5b3712f28e4b9f1170eae3b (patch)
tree5255d8cce8a72a5b09cc1ad58661e2176295467a /src/client/views/PresentationView.tsx
parente19fdbba4cf672aee5bfb59b91b6162431d146d3 (diff)
parent26141a697ae52a7edf3cc6845ce2153111f8860e (diff)
Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web into new_search
Diffstat (limited to 'src/client/views/PresentationView.tsx')
-rw-r--r--src/client/views/PresentationView.tsx191
1 files changed, 191 insertions, 0 deletions
diff --git a/src/client/views/PresentationView.tsx b/src/client/views/PresentationView.tsx
new file mode 100644
index 000000000..4853eb151
--- /dev/null
+++ b/src/client/views/PresentationView.tsx
@@ -0,0 +1,191 @@
+import { observer } from "mobx-react";
+import React = require("react")
+import { observable, action, runInAction, reaction } from "mobx";
+import "./PresentationView.scss"
+import "./Main.tsx";
+import { DocumentManager } from "../util/DocumentManager";
+import { Utils } from "../../Utils";
+import { Doc } from "../../new_fields/Doc";
+import { listSpec } from "../../new_fields/Schema";
+import { Cast, NumCast, FieldValue, PromiseValue } from "../../new_fields/Types";
+import { Id } from "../../new_fields/RefField";
+import { List } from "../../new_fields/List";
+import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
+
+export interface PresViewProps {
+ //Document: Doc;
+}
+
+
+@observer
+/**
+ * Component that takes in a document prop and a boolean whether it's collapsed or not.
+ */
+class PresentationViewItem extends React.Component<PresViewProps> {
+
+ @observable Document: Doc;
+ constructor(props: PresViewProps) {
+ super(props);
+ this.Document = FieldValue(Cast(FieldValue(Cast(CurrentUserUtils.UserDocument.activeWorkspace, Doc))!.presentationView, Doc))!;
+ }
+ //look at CollectionFreeformView.focusDocument(d)
+ @action
+ openDoc = (doc: Doc) => {
+ let docView = DocumentManager.Instance.getDocumentView(doc);
+ if (docView) {
+ docView.props.focus(docView.props.Document);
+ }
+ }
+
+ /**
+ * Removes a document from the presentation view
+ **/
+ @action
+ public RemoveDoc(doc: Doc) {
+ const value = Cast(this.Document.data, listSpec(Doc), []);
+ let index = -1;
+ for (let i = 0; i < value.length; i++) {
+ if (value[i][Id] === doc[Id]) {
+ index = i;
+ break;
+ }
+ }
+ if (index !== -1) {
+ value.splice(index, 1);
+ }
+ }
+
+ /**
+ * Renders a single child document. It will just append a list element.
+ * @param document The document to render.
+ */
+ renderChild(document: Doc) {
+ let title = document.title;
+
+ //to get currently selected presentation doc
+ let selected = NumCast(this.Document.selectedDoc, 0);
+
+ // finally, if it's a normal document, then render it as such.
+ const children = Cast(this.Document.data, listSpec(Doc));
+ const styles: any = {};
+ if (children && children[selected] === document) {
+ //this doc is selected
+ styles.background = "gray";
+ }
+ return (
+ <li className="presentationView-item" style={styles} key={Utils.GenerateGuid()}>
+ <div className="presentationView-header" onClick={() => this.openDoc(document)}>{title}</div>
+ <div className="presentation-icon" onClick={() => this.RemoveDoc(document)}>X</div>
+ </li>
+ );
+
+ }
+
+ render() {
+ const children = Cast(this.Document.data, listSpec(Doc), []);
+
+ return (
+ <div>
+ {children.map(value => this.renderChild(value))}
+ </div>
+ );
+ }
+}
+
+
+@observer
+export class PresentationView extends React.Component<PresViewProps> {
+ public static Instance: PresentationView;
+
+ //observable means render is re-called every time variable is changed
+ @observable
+ collapsed: boolean = false;
+ closePresentation = action(() => this.Document!.width = 0);
+ next = () => {
+ const current = NumCast(this.Document!.selectedDoc);
+ const allDocs = FieldValue(Cast(this.Document!.data, listSpec(Doc)));
+ if (allDocs && current < allDocs.length + 1) {
+ //can move forwards
+ this.Document!.selectedDoc = current + 1;
+ const doc = allDocs[current + 1];
+ let docView = DocumentManager.Instance.getDocumentView(doc);
+ if (docView) {
+ docView.props.focus(docView.props.Document);
+ }
+ }
+
+ }
+ back = () => {
+ const current = NumCast(this.Document!.selectedDoc);
+ const allDocs = FieldValue(Cast(this.Document!.data, listSpec(Doc)));
+ if (allDocs && current - 1 >= 0) {
+ //can move forwards
+ this.Document!.selectedDoc = current - 1;
+ const doc = allDocs[current - 1];
+ let docView = DocumentManager.Instance.getDocumentView(doc);
+ if (docView) {
+ docView.props.focus(docView.props.Document);
+ }
+ }
+ }
+
+ private ref = React.createRef<HTMLDivElement>();
+
+ @observable Document?: Doc;
+ //initilize class variables
+ constructor(props: PresViewProps) {
+ super(props);
+ let self = this;
+ reaction(() =>
+ CurrentUserUtils.UserDocument.activeWorkspace,
+ (activeW) => {
+ if (activeW && activeW instanceof Doc) {
+ PromiseValue(Cast(activeW.presentationView, Doc)).
+ then(pv => runInAction(() =>
+ self.Document = pv ? pv : (activeW.presentationView = new Doc())))
+ }
+ },
+ { fireImmediately: true });
+ PresentationView.Instance = this;
+ }
+
+ /**
+ * Adds a document to the presentation view
+ **/
+ @action
+ public PinDoc(doc: Doc) {
+ //add this new doc to props.Document
+ const data = Cast(this.Document!.data, listSpec(Doc));
+ if (data) {
+ data.push(doc);
+ } else {
+ this.Document!.data = new List([doc]);
+ }
+
+ this.Document!.width = 300;
+ }
+
+ render() {
+ if (!this.Document)
+ return (null);
+ let titleStr = this.Document.Title;
+ let width = NumCast(this.Document.width);
+
+ //TODO: next and back should be icons
+ return (
+ <div className="presentationView-cont" style={{ width: width, overflow: "hidden" }}>
+ <div className="presentationView-heading">
+ <div className="presentationView-title">{titleStr}</div>
+ <div className='presentation-icon' onClick={this.closePresentation}>X</div></div>
+ <div>
+ <div className="presentation-back" onClick={this.back}>back</div>
+ <div className="presentation-next" onClick={this.next}>next</div>
+
+ </div>
+ <ul>
+ <PresentationViewItem />
+ </ul>
+ </div>
+ );
+ }
+} \ No newline at end of file