aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/MainView.tsx2
-rw-r--r--src/client/views/PresentationView.tsx165
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/presentationview/PresentationElement.tsx115
-rw-r--r--src/client/views/presentationview/PresentationView.scss (renamed from src/client/views/PresentationView.scss)5
-rw-r--r--src/client/views/presentationview/PresentationView.tsx203
6 files changed, 325 insertions, 167 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index a093ffdec..c98e6e8fb 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -14,7 +14,7 @@ import { Docs } from '../documents/Documents';
import { SetupDrag, DragManager } from '../util/DragManager';
import { Transform } from '../util/Transform';
import { UndoManager } from '../util/UndoManager';
-import { PresentationView } from './PresentationView';
+import { PresentationView } from './presentationview/PresentationView';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { ContextMenu } from './ContextMenu';
import { DocumentDecorations } from './DocumentDecorations';
diff --git a/src/client/views/PresentationView.tsx b/src/client/views/PresentationView.tsx
deleted file mode 100644
index b6e0f0889..000000000
--- a/src/client/views/PresentationView.tsx
+++ /dev/null
@@ -1,165 +0,0 @@
-import { observer } from "mobx-react";
-import React = require("react");
-import { observable, action, runInAction, reaction } from "mobx";
-import "./PresentationView.scss";
-import { DocumentManager } from "../util/DocumentManager";
-import { Utils } from "../../Utils";
-import { Doc, DocListCast, DocListCastAsync } from "../../new_fields/Doc";
-import { listSpec } from "../../new_fields/Schema";
-import { Cast, NumCast, FieldValue, PromiseValue, StrCast, BoolCast } from "../../new_fields/Types";
-import { Id } from "../../new_fields/FieldSymbols";
-import { List } from "../../new_fields/List";
-import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
-
-export interface PresViewProps {
- Document: Doc;
-}
-
-interface PresListProps extends PresViewProps {
- deleteDocument(index: number): void;
- gotoDocument(index: number): void;
-}
-
-
-@observer
-/**
- * Component that takes in a document prop and a boolean whether it's collapsed or not.
- */
-class PresentationViewList extends React.Component<PresListProps> {
-
-
- /**
- * Renders a single child document. It will just append a list element.
- * @param document The document to render.
- */
- renderChild = (document: Doc, index: number) => {
- let title = document.title;
-
- //to get currently selected presentation doc
- let selected = NumCast(this.props.Document.selectedDoc, 0);
-
- let className = "presentationView-item";
- if (selected === index) {
- //this doc is selected
- className += " presentationView-selected";
- }
- let onEnter = (e: React.PointerEvent) => { document.libraryBrush = true; }
- let onLeave = (e: React.PointerEvent) => { document.libraryBrush = false; }
- return (
- <div className={className} key={document[Id] + index}
- onPointerEnter={onEnter} onPointerLeave={onLeave}
- style={{
- outlineColor: "maroon",
- outlineStyle: "dashed",
- outlineWidth: BoolCast(document.libraryBrush, false) || BoolCast(document.protoBrush, false) ? `1px` : "0px",
- }}
- onClick={e => { this.props.gotoDocument(index); e.stopPropagation(); }}>
- <strong className="presentationView-name">
- {`${index + 1}. ${title}`}
- </strong>
- <button className="presentation-icon" onClick={e => { this.props.deleteDocument(index); e.stopPropagation(); }}>X</button>
- <br></br>
- <button className="presentation-interaction">A</button>
- <button className="presentation-interaction">B</button>
- <button className="presentation-interaction">C</button>
- <button className="presentation-interaction">D</button>
-
- </div>
- );
-
- }
-
- render() {
- const children = DocListCast(this.props.Document.data);
-
- return (
- <div className="presentationView-listCont">
- {children.map(this.renderChild)}
- </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.props.Document.width = 0);
- next = () => {
- const current = NumCast(this.props.Document.selectedDoc);
- this.gotoDocument(current + 1);
-
- }
- back = () => {
- const current = NumCast(this.props.Document.selectedDoc);
- this.gotoDocument(current - 1);
- }
-
- @action
- public RemoveDoc = (index: number) => {
- const value = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
- if (value) {
- value.splice(index, 1);
- }
- }
-
- public gotoDocument = async (index: number) => {
- const list = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
- if (!list) {
- return;
- }
- if (index < 0 || index >= list.length) {
- return;
- }
-
- this.props.Document.selectedDoc = index;
- const doc = await list[index];
- DocumentManager.Instance.jumpToDocument(doc);
- }
-
- //initilize class variables
- constructor(props: PresViewProps) {
- super(props);
- 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.props.Document.data, listSpec(Doc));
- if (data) {
- data.push(doc);
- } else {
- this.props.Document.data = new List([doc]);
- }
-
- this.props.Document.width = 300;
- }
-
- render() {
- let titleStr = StrCast(this.props.Document.title);
- let width = NumCast(this.props.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>
- <button className='presentation-icon' onClick={this.closePresentation}>X</button>
- </div>
- <div className="presentation-buttons">
- <button className="presentation-button" onClick={this.back}>back</button>
- <button className="presentation-button" onClick={this.next}>next</button>
- </div>
- <PresentationViewList Document={this.props.Document} deleteDocument={this.RemoveDoc} gotoDocument={this.gotoDocument} />
- </div>
- );
- }
-} \ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7750b9173..984cac9b9 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -23,7 +23,7 @@ import { CollectionVideoView } from "../collections/CollectionVideoView";
import { CollectionView } from "../collections/CollectionView";
import { ContextMenu } from "../ContextMenu";
import { DocComponent } from "../DocComponent";
-import { PresentationView } from "../PresentationView";
+import { PresentationView } from "../presentationview/PresentationView";
import { Template } from "./../Templates";
import { DocumentContentsView } from "./DocumentContentsView";
import "./DocumentView.scss";
diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx
new file mode 100644
index 000000000..02d97ee4d
--- /dev/null
+++ b/src/client/views/presentationview/PresentationElement.tsx
@@ -0,0 +1,115 @@
+import { observer } from "mobx-react";
+import React = require("react");
+import { Doc } from "../../../new_fields/Doc";
+import { NumCast, BoolCast } from "../../../new_fields/Types";
+import { Id } from "../../../new_fields/FieldSymbols";
+import { observable, action } from "mobx";
+import "./PresentationView.scss";
+
+
+
+interface PresentationElementProps {
+ mainDocument: Doc;
+ document: Doc;
+ index: number;
+ deleteDocument(index: number): void;
+ gotoDocument(index: number): void;
+ groupedMembers: [Doc[]];
+ allListElements: Doc[];
+
+}
+
+@observer
+export default class PresentationElement extends React.Component<PresentationElementProps> {
+
+ @observable selectedButtons: boolean[] = new Array(6);
+
+
+ @action
+ onGroupClick = (document: Doc, index: number, buttonStatus: boolean[] | boolean) => {
+ let p = this.props;
+ if (Array.isArray(buttonStatus)) {
+ if (buttonStatus[5]) {
+ buttonStatus[5] = false;
+ console.log("Reached!");
+ if (index >= 1) {
+ if (p.groupedMembers[index].length >= 0) {
+ p.groupedMembers[index].forEach((doc: Doc) => p.groupedMembers[index - 1] = p.groupedMembers[index - 1].slice(p.groupedMembers[index - 1].indexOf(doc), 1));
+ }
+ }
+ } else {
+ buttonStatus[5] = true;
+ if (index >= 1) {
+ if (p.groupedMembers[index].length >= 0) {
+ p.groupedMembers[index].forEach((doc: Doc) => p.groupedMembers[index - 1].push(doc));
+ }
+ p.groupedMembers[index - 1].push(document);
+ //this.onGroupClick()
+ }
+ }
+ } else {
+ if (!buttonStatus) {
+ if (p.groupedMembers[index].length >= 0) {
+ p.groupedMembers[index].forEach((doc: Doc) => p.groupedMembers[index - 1] = p.groupedMembers[index - 1].slice(p.groupedMembers[index - 1].indexOf(doc), 1));
+ }
+ } else {
+ if (p.groupedMembers[index].length >= 0) {
+ p.groupedMembers[index].forEach((doc: Doc) => { if (!p.groupedMembers[index - 1].includes(doc)) { p.groupedMembers[index - 1].push(doc); } });
+ }
+ if (!p.groupedMembers[index - 1].includes(document)) {
+ p.groupedMembers[index - 1].push(document);
+ }
+ }
+ }
+ if (index >= 2) {
+ this.onGroupClick(p.allListElements[index - 1], index - 1, p.groupedMembers[index - 2].length !== 0);
+ }
+
+ p.groupedMembers.forEach((docArray: Doc[], index: number) => console.log("Index: ", index, " size: ", docArray.length));
+ console.log("Group Size: ", p.groupedMembers[index - 1].length);
+ }
+
+
+
+ render() {
+ let p = this.props;
+ let title = p.document.title;
+
+ //to get currently selected presentation doc
+ let selected = NumCast(p.mainDocument.selectedDoc, 0);
+
+ let className = "presentationView-item";
+ if (selected === p.index) {
+ //this doc is selected
+ className += " presentationView-selected";
+ }
+ let onEnter = (e: React.PointerEvent) => { p.document.libraryBrush = true; }
+ let onLeave = (e: React.PointerEvent) => { p.document.libraryBrush = false; }
+ return (
+ <div className={className} key={p.document[Id] + p.index}
+ onPointerEnter={onEnter} onPointerLeave={onLeave}
+ style={{
+ outlineColor: "maroon",
+ outlineStyle: "dashed",
+ outlineWidth: BoolCast(p.document.libraryBrush, false) || BoolCast(p.document.protoBrush, false) ? `1px` : "0px",
+ }}
+ onClick={e => { p.gotoDocument(p.index); e.stopPropagation(); }}>
+ <strong className="presentationView-name">
+ {`${p.index + 1}. ${title}`}
+ </strong>
+ <button className="presentation-icon" onClick={e => { this.props.deleteDocument(p.index); e.stopPropagation(); }}>X</button>
+ <br></br>
+ <button className={this.selectedButtons[0] ? "presentation-interaction-selected" : "presentation-interaction"}>A</button>
+ <button className={this.selectedButtons[1] ? "presentation-interaction-selected" : "presentation-interaction"}>B</button>
+ <button className={this.selectedButtons[2] ? "presentation-interaction-selected" : "presentation-interaction"}>C</button>
+ <button className={this.selectedButtons[3] ? "presentation-interaction-selected" : "presentation-interaction"}>D</button>
+ <button className={this.selectedButtons[4] ? "presentation-interaction-selected" : "presentation-interaction"}>E</button>
+ <button className={this.selectedButtons[5] ? "presentation-interaction-selected" : "presentation-interaction"} onClick={(e) => {
+ e.stopPropagation();
+ this.onGroupClick(p.document, p.index, this.selectedButtons);
+ }}>F</button>
+
+ </div>
+ );
+ }
+} \ No newline at end of file
diff --git a/src/client/views/PresentationView.scss b/src/client/views/presentationview/PresentationView.scss
index 97ce80a02..07c3e69fd 100644
--- a/src/client/views/PresentationView.scss
+++ b/src/client/views/presentationview/PresentationView.scss
@@ -57,6 +57,11 @@
float: left;
}
+.presentation-interaction-selected {
+ background: #505050;
+ float: left;
+}
+
.presentationView-name {
font-size: 15px;
display: inline-block;
diff --git a/src/client/views/presentationview/PresentationView.tsx b/src/client/views/presentationview/PresentationView.tsx
new file mode 100644
index 000000000..5a7d38e28
--- /dev/null
+++ b/src/client/views/presentationview/PresentationView.tsx
@@ -0,0 +1,203 @@
+import { observer } from "mobx-react";
+import React = require("react");
+import { observable, action, runInAction, reaction } from "mobx";
+import "./PresentationView.scss";
+import { DocumentManager } from "../../util/DocumentManager";
+import { Utils } from "../../../Utils";
+import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
+import { listSpec } from "../../../new_fields/Schema";
+import { Cast, NumCast, FieldValue, PromiseValue, StrCast, BoolCast } from "../../../new_fields/Types";
+import { Id } from "../../../new_fields/FieldSymbols";
+import { List } from "../../../new_fields/List";
+import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
+import PresentationElement from "./PresentationElement";
+
+export interface PresViewProps {
+ Document: Doc;
+}
+
+interface PresListProps extends PresViewProps {
+ deleteDocument(index: number): void;
+ gotoDocument(index: number): void;
+ groupedMembers: [Doc[]];
+
+}
+
+
+@observer
+/**
+ * Component that takes in a document prop and a boolean whether it's collapsed or not.
+ */
+class PresentationViewList extends React.Component<PresListProps> {
+
+
+ // onGroupClick = (document: Doc, index: number, buttonStatus: boolean[]) => {
+ // if (buttonStatus[5]) {
+ // buttonStatus[5] = false;
+ // if (index >= 1) {
+ // if (this.groupedMembers[index].length >= 0) {
+ // this.groupedMembers[index].forEach((doc: Doc) => this.groupedMembers[index - 1].slice(this.groupedMembers[index - 1].indexOf(doc), 1));
+ // }
+ // }
+ // } else {
+ // buttonStatus[5] = true;
+ // console.log("reached!! ", buttonStatus[5]);
+ // if (index >= 1) {
+ // if (this.groupedMembers[index].length >= 0) {
+ // this.groupedMembers[index].forEach((doc: Doc) => this.groupedMembers[index - 1].push(doc));
+ // }
+ // this.groupedMembers[index - 1].push(document);
+ // }
+ // }
+ // }
+ @action
+ initializeGroupArrays = (docList: Doc[]) => {
+ docList.forEach((doc: Doc, index: number) => {
+ if (this.props.groupedMembers.length < index + 1) {
+ this.props.groupedMembers[index] = new Array();
+ }
+ });
+ }
+
+ // /**
+ // * Renders a single child document. It will just append a list element.
+ // * @param document The document to render.
+ // */
+ // renderChild = (document: Doc, index: number) => {
+ // let title = document.title;
+
+ // //to get currently selected presentation doc
+ // let selected = NumCast(this.props.Document.selectedDoc, 0);
+
+ // let className = "presentationView-item";
+ // if (selected === index) {
+ // //this doc is selected
+ // className += " presentationView-selected";
+ // }
+ // let selectedButtons: boolean[] = new Array(6);
+ // let onEnter = (e: React.PointerEvent) => { document.libraryBrush = true; }
+ // let onLeave = (e: React.PointerEvent) => { document.libraryBrush = false; }
+ // return (
+ // <div className={className} key={document[Id] + index}
+ // onPointerEnter={onEnter} onPointerLeave={onLeave}
+ // style={{
+ // outlineColor: "maroon",
+ // outlineStyle: "dashed",
+ // outlineWidth: BoolCast(document.libraryBrush, false) || BoolCast(document.protoBrush, false) ? `1px` : "0px",
+ // }}
+ // onClick={e => { this.props.gotoDocument(index); e.stopPropagation(); }}>
+ // <strong className="presentationView-name">
+ // {`${index + 1}. ${title}`}
+ // </strong>
+ // <button className="presentation-icon" onClick={e => { this.props.deleteDocument(index); e.stopPropagation(); }}>X</button>
+ // <br></br>
+ // <button className={selectedButtons[0] ? "presentation-interaction" : "presentation-interaction-selected"}>A</button>
+ // <button className={selectedButtons[1] ? "presentation-interaction" : "presentation-interaction-selected"}>B</button>
+ // <button className={selectedButtons[2] ? "presentation-interaction" : "presentation-interaction-selected"}>C</button>
+ // <button className={selectedButtons[3] ? "presentation-interaction" : "presentation-interaction-selected"}>D</button>
+ // <button className={selectedButtons[4] ? "presentation-interaction" : "presentation-interaction-selected"}>E</button>
+ // <button className={selectedButtons[5] ? "presentation-interaction" : "presentation-interaction-selected"} onClick={() => this.onGroupClick(document, index, selectedButtons)}>F</button>
+
+ // </div>
+ // );
+
+ // }
+
+ render() {
+ const children = DocListCast(this.props.Document.data);
+ this.initializeGroupArrays(children);
+
+ return (
+ <div className="presentationView-listCont">
+ {children.map((doc: Doc, index: number) => <PresentationElement key={index} mainDocument={this.props.Document} document={doc} index={index} deleteDocument={this.props.deleteDocument} gotoDocument={this.props.gotoDocument} groupedMembers={this.props.groupedMembers} allListElements={children} />)}
+ </div>
+ );
+ }
+}
+
+
+@observer
+export class PresentationView extends React.Component<PresViewProps> {
+ public static Instance: PresentationView;
+
+ @observable groupedMembers: [Doc[]] = [[]];
+
+
+ //observable means render is re-called every time variable is changed
+ @observable
+ collapsed: boolean = false;
+ closePresentation = action(() => this.props.Document.width = 0);
+ next = () => {
+ const current = NumCast(this.props.Document.selectedDoc);
+ this.gotoDocument(current + 1);
+
+ }
+ back = () => {
+ const current = NumCast(this.props.Document.selectedDoc);
+ this.gotoDocument(current - 1);
+ }
+
+ @action
+ public RemoveDoc = (index: number) => {
+ const value = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
+ if (value) {
+ value.splice(index, 1);
+ }
+ }
+
+ public gotoDocument = async (index: number) => {
+ const list = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
+ if (!list) {
+ return;
+ }
+ if (index < 0 || index >= list.length) {
+ return;
+ }
+
+ this.props.Document.selectedDoc = index;
+ const doc = await list[index];
+ DocumentManager.Instance.jumpToDocument(doc);
+ }
+
+ //initilize class variables
+ constructor(props: PresViewProps) {
+ super(props);
+ 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.props.Document.data, listSpec(Doc));
+ if (data) {
+ data.push(doc);
+ } else {
+ this.props.Document.data = new List([doc]);
+ }
+
+ this.props.Document.width = 300;
+ }
+
+ render() {
+ let titleStr = StrCast(this.props.Document.title);
+ let width = NumCast(this.props.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>
+ <button className='presentation-icon' onClick={this.closePresentation}>X</button>
+ </div>
+ <div className="presentation-buttons">
+ <button className="presentation-button" onClick={this.back}>back</button>
+ <button className="presentation-button" onClick={this.next}>next</button>
+ </div>
+ <PresentationViewList Document={this.props.Document} deleteDocument={this.RemoveDoc} gotoDocument={this.gotoDocument} groupedMembers={this.groupedMembers} />
+ </div>
+ );
+ }
+} \ No newline at end of file