diff options
Diffstat (limited to 'src/client/views')
-rw-r--r-- | src/client/views/collections/CollectionSubView.tsx | 30 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/LoadingBox.scss | 33 | ||||
-rw-r--r-- | src/client/views/nodes/LoadingBox.tsx | 66 |
4 files changed, 126 insertions, 5 deletions
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index e33bb77de..d7d988c19 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -446,6 +446,7 @@ export function CollectionSubView<X>(moreProps?: X) { } this.slowLoadDocuments(files, options, generatedDocuments, text, completed, e.clientX, e.clientY, addDocument).then(batch.end); } + slowLoadDocuments = async ( files: File[] | string, options: DocumentOptions, @@ -456,11 +457,30 @@ export function CollectionSubView<X>(moreProps?: X) { clientY: number, addDocument: (doc: Doc | Doc[]) => boolean ) => { - const disposer = OverlayView.Instance.addElement(<ReactLoading type={'spinningBubbles'} color={'green'} height={250} width={250} />, { x: clientX - 125, y: clientY - 125 }); + // create placeholder docs + // inside placeholder docs have some func that + + // TODO: once loading thing is moved it should update the x and y of the file it is placeholder for + let pileUpDoc = undefined; + // const disposer = OverlayView.Instance.addElement(<ReactLoading type={'spinningBubbles'} color={'green'} height={250} width={250} />, { x: clientX - 125, y: clientY - 125 }); if (typeof files === 'string') { - generatedDocuments.push(...(await DocUtils.uploadYoutubeVideo(files, options))); + // uploadYoutubeVideo and similar should return a placeholder, one for each placeholder + // generatedDocuments.push(Docs.Create.LoadingDocument(files, options)); + const loading = Docs.Create.LoadingDocument(files, options); + generatedDocuments.push(loading); + Docs.Create.docsToFiles.set(loading, files); + DocUtils.uploadYoutubeVideoLoading(files, {}, loading); } else { - generatedDocuments.push(...(await DocUtils.uploadFilesToDocs(files, options))); + // uploadFilesToDocs and similar should return a placeholder, one for each placeholder + generatedDocuments.push( + ...files.map(file => { + const loading = Docs.Create.LoadingDocument(file, options); + // now that there is a doc do whatever slowload was going to do with that file + Docs.Create.docsToFiles.set(loading, file); + DocUtils.uploadFileToDoc(file, {}, loading); + return loading; + }) + ); } if (generatedDocuments.length) { // Creating a dash document @@ -476,7 +496,8 @@ export function CollectionSubView<X>(moreProps?: X) { if (completed) completed(set); else { if (isFreeformView && generatedDocuments.length > 1) { - addDocument(DocUtils.pileup(generatedDocuments, options.x as number, options.y as number)!); + pileUpDoc = DocUtils.pileup(generatedDocuments, options.x as number, options.y as number)!; + addDocument(pileUpDoc); } else { generatedDocuments.forEach(addDocument); } @@ -488,7 +509,6 @@ export function CollectionSubView<X>(moreProps?: X) { alert('Document upload failed - possibly an unsupported file type.'); } } - disposer(); }; } diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 381436a56..4d4985f2a 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -43,6 +43,7 @@ import { VideoBox } from './VideoBox'; import { WebBox } from './WebBox'; import React = require('react'); import XRegExp = require('xregexp'); +import { LoadingBox } from './LoadingBox'; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? @@ -267,6 +268,7 @@ export class DocumentContentsView extends React.Component< DataVizBox, HTMLtag, ComparisonBox, + LoadingBox, }} bindings={bindings} jsx={layoutFrame} diff --git a/src/client/views/nodes/LoadingBox.scss b/src/client/views/nodes/LoadingBox.scss new file mode 100644 index 000000000..f6912f547 --- /dev/null +++ b/src/client/views/nodes/LoadingBox.scss @@ -0,0 +1,33 @@ +.loadingBoxContainer { + display: flex; + flex-direction: column; + align-content: center; + justify-content: center; + background-color: #fdfdfd; +} + +.textContainer { + margin: 5px; +} + +.textContainer { + justify-content: center; + align-content: center; +} + +.textContainer, +.text { + overflow: hidden; + text-overflow: ellipsis; + max-width: 80%; + text-align: center; +} + +.headerText { + text-align: center; + font-weight: bold; +} + +.spinner { + text-align: center; +} diff --git a/src/client/views/nodes/LoadingBox.tsx b/src/client/views/nodes/LoadingBox.tsx new file mode 100644 index 000000000..ab8878fc1 --- /dev/null +++ b/src/client/views/nodes/LoadingBox.tsx @@ -0,0 +1,66 @@ +import { observer } from 'mobx-react'; +import { ViewBoxAnnotatableComponent } from '../DocComponent'; +import { FieldView, FieldViewProps } from './FieldView'; +import * as React from 'react'; +import './LoadingBox.scss'; +import ReactLoading from 'react-loading'; +import { StrCast } from '../../../fields/Types'; +import { computed } from 'mobx'; +import { Docs } from '../../documents/Documents'; + +/** + * LoadingBox Class represents a placeholder doc for documents that are currently + * being uploaded to the server and being fetched by the client. The LoadingBox doc is then used to + * generate the actual type of doc that is required once the document has been successfully uploaded. + * + * Design considerations: + * We are using the docToFiles map in Documents to keep track of all files being uploaded in one session of the client. + * If the file is not found we assume an error has occurred with the file upload, e.g. it has been interrupted by a client refresh + * or network issues. The docToFiles essentially gets reset everytime the page is refreshed. + * + * TODOs: + * 1) ability to query server to retrieve files that already exist if users upload duplicate files. + * 2) ability to restart upload if there is an error + * 3) detect network error and notify the user + * 4 )if file upload gets interrupted, it still gets uploaded to the server if there are no network interruptions which leads to unused space. this could be + * handled with (1) + * + * @author naafiyan + */ +@observer +export class LoadingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { + public static LayoutString(fieldKey: string) { + return FieldView.LayoutString(LoadingBox, fieldKey); + } + + /** + * Returns true if file is uploading, false otherwise + */ + @computed private get isLoading(): boolean { + const file = Docs.Create.docsToFiles.get(this.rootDoc); + return file ? true : false; + } + + constructor(props: any) { + super(props); + } + + render() { + return ( + <div className="loadingBoxContainer"> + {this.isLoading ? ( + <div className="textContainer"> + <p className="headerText">Loading:</p> + <span className="text">{StrCast(this.rootDoc.title)}</span> + <ReactLoading type={'spinningBubbles'} color={'blue'} height={100} width={100} /> + </div> + ) : ( + <div className="textContainer"> + <p className="headerText">Error Loading File: </p> + <span className="text">{StrCast(this.rootDoc.title)}</span> + </div> + )} + </div> + ); + } +} |