diff options
Diffstat (limited to 'src/client/views/PresentationView.tsx')
-rw-r--r-- | src/client/views/PresentationView.tsx | 166 |
1 files changed, 59 insertions, 107 deletions
diff --git a/src/client/views/PresentationView.tsx b/src/client/views/PresentationView.tsx index 3fb24a339..098e725c7 100644 --- a/src/client/views/PresentationView.tsx +++ b/src/client/views/PresentationView.tsx @@ -5,15 +5,20 @@ import "./PresentationView.scss" import "./Main.tsx"; import { DocumentManager } from "../util/DocumentManager"; import { Utils } from "../../Utils"; -import { Doc } from "../../new_fields/Doc"; +import { Doc, DocListCast, DocListCastAsync } from "../../new_fields/Doc"; import { listSpec } from "../../new_fields/Schema"; -import { Cast, NumCast, FieldValue, PromiseValue } from "../../new_fields/Types"; +import { Cast, NumCast, FieldValue, PromiseValue, StrCast } 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; + Document: Doc; +} + +interface PresListProps extends PresViewProps { + deleteDocument(index: number): void; + gotoDocument(index: number): void; } @@ -21,72 +26,40 @@ export interface PresViewProps { /** * 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); - } - } +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) { + renderChild = (document: Doc, index: number) => { let title = document.title; //to get currently selected presentation doc - let selected = NumCast(this.Document.selectedDoc, 0); + let selected = NumCast(this.props.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) { + let className = "presentationView-item"; + if (selected === index) { //this doc is selected - styles.background = "gray"; + className += " presentationView-selected"; } 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> + <div className={className} key={document[Id] + index} 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> + </div> ); } render() { - const children = Cast(this.Document.data, listSpec(Doc), []); + const children = DocListCast(this.props.Document.data); return ( - <div> - {children.map(value => this.renderChild(value))} + <div className="presentationView-listCont"> + {children.map(this.renderChild)} </div> ); } @@ -100,59 +73,42 @@ export class PresentationView extends React.Component<PresViewProps> { //observable means render is re-called every time variable is changed @observable collapsed: boolean = false; - closePresentation = action(() => this.Document!.width = 0); + closePresentation = action(() => this.props.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); - } - } + const current = NumCast(this.props.Document.selectedDoc); + this.gotoDocument(current + 1); } 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); - } + 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); } } - private ref = React.createRef<HTMLDivElement>(); + 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); + } - @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(() => { - if (pv) self.Document = pv; - else { - pv = new Doc(); - pv.title = "Presentation Doc"; - activeW.presentationView = pv; - self.Document = pv; - } - })) - } - }, - { fireImmediately: true }); PresentationView.Instance = this; } @@ -162,36 +118,32 @@ export class PresentationView extends React.Component<PresViewProps> { @action public PinDoc(doc: Doc) { //add this new doc to props.Document - const data = Cast(this.Document!.data, listSpec(Doc)); + const data = Cast(this.props.Document.data, listSpec(Doc)); if (data) { data.push(doc); } else { - this.Document!.data = new List([doc]); + this.props.Document.data = new List([doc]); } - this.Document!.width = 300; + this.props.Document.width = 300; } render() { - if (!this.Document) - return (null); - let titleStr = this.Document.Title; - let width = NumCast(this.Document.width); + 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> - <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> - + <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> - <ul> - <PresentationViewItem /> - </ul> + <PresentationViewList Document={this.props.Document} deleteDocument={this.RemoveDoc} gotoDocument={this.gotoDocument} /> </div> ); } |