aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/MainView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/MainView.tsx')
-rw-r--r--src/client/views/MainView.tsx358
1 files changed, 209 insertions, 149 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index ffbba3a20..660b42290 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,5 +1,6 @@
import { IconName, library } from '@fortawesome/fontawesome-svg-core';
import { faLink, faArrowDown, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faClone, faCloudUploadAlt, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight, faMusic, faObjectGroup, faPause, faPenNib, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faUndoAlt, faTv, faChevronRight, faEllipsisV } from '@fortawesome/free-solid-svg-icons';
+import { faArrowDown, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faClone, faCloudUploadAlt, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight, faMusic, faObjectGroup, faPause, faPenNib, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faTv, faUndoAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, configure, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
@@ -7,24 +8,25 @@ import "normalize.css";
import * as React from 'react';
import { SketchPicker } from 'react-color';
import Measure from 'react-measure';
-import { Doc, DocListCast, Opt, HeightSym } from '../../new_fields/Doc';
-import { List } from '../../new_fields/List';
+import { Doc, DocListCast, Field, FieldResult, HeightSym, Opt } from '../../new_fields/Doc';
import { Id } from '../../new_fields/FieldSymbols';
import { InkTool } from '../../new_fields/InkField';
+import { List } from '../../new_fields/List';
import { listSpec } from '../../new_fields/Schema';
-import { BoolCast, Cast, FieldValue, StrCast, NumCast } from '../../new_fields/Types';
+import { BoolCast, Cast, FieldValue, StrCast } from '../../new_fields/Types';
import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
import { RouteStore } from '../../server/RouteStore';
-import { emptyFunction, returnOne, returnTrue, Utils, returnEmptyString } from '../../Utils';
+import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils } from '../../Utils';
import { DocServer } from '../DocServer';
-import { Docs } from '../documents/Documents';
+import { Docs, DocumentOptions } from '../documents/Documents';
import { ClientUtils } from '../util/ClientUtils';
import { DictationManager } from '../util/DictationManager';
import { SetupDrag } from '../util/DragManager';
import { HistoryUtil } from '../util/History';
+import SharingManager from '../util/SharingManager';
import { Transform } from '../util/Transform';
-import { UndoManager, undoBatch } from '../util/UndoManager';
-import { CollectionBaseView } from './collections/CollectionBaseView';
+import { UndoManager } from '../util/UndoManager';
+import { CollectionBaseView, CollectionViewType } from './collections/CollectionBaseView';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionTreeView } from './collections/CollectionTreeView';
import { ContextMenu } from './ContextMenu';
@@ -33,15 +35,13 @@ import KeyManager from './GlobalKeyHandler';
import { InkingControl } from './InkingControl';
import "./Main.scss";
import { MainOverlayTextBox } from './MainOverlayTextBox';
+import MainViewModal from './MainViewModal';
import { DocumentView } from './nodes/DocumentView';
+import { PresBox } from './nodes/PresBox';
import { OverlayView } from './OverlayView';
import PDFMenu from './pdf/PDFMenu';
import { PreviewCursor } from './PreviewCursor';
import { FilterBox } from './search/FilterBox';
-import PresModeMenu from './presentationview/PresentationModeMenu';
-import { PresBox } from './nodes/PresBox';
-import { LinkFollowBox } from './linking/LinkFollowBox';
-import { DocumentManager } from '../util/DocumentManager';
@observer
export class MainView extends React.Component {
@@ -55,6 +55,8 @@ export class MainView extends React.Component {
@observable private dictationDisplayState = false;
@observable private dictationListeningState: DictationManager.Controls.ListeningUIStatus = false;
+ public hasActiveModal = false;
+
public overlayTimeout: NodeJS.Timeout | undefined;
public initiateDictationFade = () => {
@@ -62,10 +64,17 @@ export class MainView extends React.Component {
this.overlayTimeout = setTimeout(() => {
this.dictationOverlayVisible = false;
this.dictationSuccess = undefined;
+ this.hasActiveModal = false;
setTimeout(() => this.dictatedPhrase = DictationManager.placeholder, 500);
}, duration);
}
+ private urlState: HistoryUtil.DocUrl;
+
+ @computed private get userDoc() {
+ return CurrentUserUtils.UserDocument;
+ }
+
public cancelDictationFade = () => {
if (this.overlayTimeout) {
clearTimeout(this.overlayTimeout);
@@ -74,7 +83,7 @@ export class MainView extends React.Component {
}
@computed private get mainContainer(): Opt<Doc> {
- return FieldValue(Cast(CurrentUserUtils.UserDocument.activeWorkspace, Doc));
+ return this.userDoc ? FieldValue(Cast(this.userDoc.activeWorkspace, Doc)) : CurrentUserUtils.GuestWorkspace;
}
@computed get mainFreeform(): Opt<Doc> {
let docs = DocListCast(this.mainContainer!.data);
@@ -83,7 +92,10 @@ export class MainView extends React.Component {
public isPointerDown = false;
private set mainContainer(doc: Opt<Doc>) {
if (doc) {
- CurrentUserUtils.UserDocument.activeWorkspace = doc;
+ if (!("presentationView" in doc)) {
+ doc.presentationView = new List<Doc>([Docs.Create.TreeDocument([], { title: "Presentation" })]);
+ }
+ this.userDoc ? (this.userDoc.activeWorkspace = doc) : (CurrentUserUtils.GuestWorkspace = doc);
}
}
@@ -128,21 +140,23 @@ export class MainView extends React.Component {
window.removeEventListener("keydown", KeyManager.Instance.handle);
window.addEventListener("keydown", KeyManager.Instance.handle);
- reaction(() => {
- let workspaces = CurrentUserUtils.UserDocument.workspaces;
- let recent = CurrentUserUtils.UserDocument.recentlyClosed;
- if (!(recent instanceof Doc)) return 0;
- if (!(workspaces instanceof Doc)) return 0;
- let workspacesDoc = workspaces;
- let recentDoc = recent;
- let libraryHeight = this.getPHeight() - workspacesDoc[HeightSym]() - recentDoc[HeightSym]() - 20 + CurrentUserUtils.UserDocument[HeightSym]() * 0.00001;
- return libraryHeight;
- }, (libraryHeight: number) => {
- if (libraryHeight && Math.abs(CurrentUserUtils.UserDocument[HeightSym]() - libraryHeight) > 5) {
- CurrentUserUtils.UserDocument.height = libraryHeight;
- }
- (Cast(CurrentUserUtils.UserDocument.recentlyClosed, Doc) as Doc).allowClear = true;
- }, { fireImmediately: true });
+ if (this.userDoc) {
+ reaction(() => {
+ let workspaces = this.userDoc.workspaces;
+ let recent = this.userDoc.recentlyClosed;
+ if (!(recent instanceof Doc)) return 0;
+ if (!(workspaces instanceof Doc)) return 0;
+ let workspacesDoc = workspaces;
+ let recentDoc = recent;
+ let libraryHeight = this.getPHeight() - workspacesDoc[HeightSym]() - recentDoc[HeightSym]() - 20 + this.userDoc[HeightSym]() * 0.00001;
+ return libraryHeight;
+ }, (libraryHeight: number) => {
+ if (libraryHeight && Math.abs(this.userDoc[HeightSym]() - libraryHeight) > 5) {
+ this.userDoc.height = libraryHeight;
+ }
+ (Cast(this.userDoc.recentlyClosed, Doc) as Doc).allowClear = true;
+ }, { fireImmediately: true });
+ }
}
componentWillUnMount() {
@@ -155,7 +169,7 @@ export class MainView extends React.Component {
constructor(props: Readonly<{}>) {
super(props);
MainView.Instance = this;
-
+ this.urlState = HistoryUtil.parseUrl(window.location) || {} as any;
// causes errors to be generated when modifying an observable outside of an action
configure({ enforceActions: "observed" });
if (window.location.pathname !== RouteStore.home) {
@@ -164,6 +178,11 @@ export class MainView extends React.Component {
let type = pathname[0];
if (type === "doc") {
CurrentUserUtils.MainDocId = pathname[1];
+ if (!this.userDoc) {
+ runInAction(() => this.flyoutWidth = 0);
+ DocServer.GetRefField(CurrentUserUtils.MainDocId).then(action((field: Opt<Field>) =>
+ field instanceof Doc && (CurrentUserUtils.GuestTarget = field)));
+ }
}
}
}
@@ -222,69 +241,106 @@ export class MainView extends React.Component {
initAuthenticationRouters = async () => {
// Load the user's active workspace, or create a new one if initial session after signup
- if (!CurrentUserUtils.MainDocId) {
- const doc = await Cast(CurrentUserUtils.UserDocument.activeWorkspace, Doc);
- if (doc) {
+ let received = CurrentUserUtils.MainDocId;
+ if (received && !this.userDoc) {
+ reaction(
+ () => CurrentUserUtils.GuestTarget,
+ target => target && this.createNewWorkspace(),
+ { fireImmediately: true }
+ );
+ } else {
+ if (received && this.urlState.sharing) {
+ reaction(
+ () => {
+ let docking = CollectionDockingView.Instance;
+ return docking && docking.initialized;
+ },
+ initialized => {
+ if (initialized && received) {
+ DocServer.GetRefField(received).then(field => {
+ if (field instanceof Doc && field.viewType !== CollectionViewType.Docking) {
+ CollectionDockingView.AddRightSplit(field, undefined);
+ }
+ });
+ }
+ },
+ );
+ }
+ let doc: Opt<Doc>;
+ if (this.userDoc && (doc = await Cast(this.userDoc.activeWorkspace, Doc))) {
this.openWorkspace(doc);
} else {
this.createNewWorkspace();
}
- } else {
- DocServer.GetRefField(CurrentUserUtils.MainDocId).then(field => {
- field instanceof Doc ? this.openWorkspace(field) :
- this.createNewWorkspace(CurrentUserUtils.MainDocId);
- });
}
}
-
@action
createNewWorkspace = async (id?: string) => {
- let workspaces = Cast(CurrentUserUtils.UserDocument.workspaces, Doc);
- if (!(workspaces instanceof Doc)) return;
- const list = Cast((CurrentUserUtils.UserDocument.workspaces as Doc).data, listSpec(Doc));
- if (list) {
- let freeformDoc = Docs.Create.FreeformDocument([], { x: 0, y: 400, width: this.pwidth * .7, height: this.pheight, title: `WS collection ${list.length + 1}` });
- var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(freeformDoc, freeformDoc, 600)] }] };
- let mainDoc = Docs.Create.DockDocument([CurrentUserUtils.UserDocument, freeformDoc], JSON.stringify(dockingLayout), { title: `Workspace ${list.length + 1}` }, id);
- if (!CurrentUserUtils.UserDocument.linkManagerDoc) {
- let linkManagerDoc = new Doc();
- linkManagerDoc.allLinks = new List<Doc>([]);
- CurrentUserUtils.UserDocument.linkManagerDoc = linkManagerDoc;
+ let freeformOptions: DocumentOptions = {
+ x: 0,
+ y: 400,
+ width: this.pwidth * .7,
+ height: this.pheight,
+ title: "My Blank Collection"
+ };
+ let workspaces: FieldResult<Doc>;
+ let freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
+ var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(freeformDoc, freeformDoc, 600)] }] };
+ let mainDoc = Docs.Create.DockDocument([this.userDoc, freeformDoc], JSON.stringify(dockingLayout), {}, id);
+ if (this.userDoc && ((workspaces = Cast(this.userDoc.workspaces, Doc)) instanceof Doc)) {
+ const list = Cast((workspaces).data, listSpec(Doc));
+ if (list) {
+ if (!this.userDoc.linkManagerDoc) {
+ let linkManagerDoc = new Doc();
+ linkManagerDoc.allLinks = new List<Doc>([]);
+ this.userDoc.linkManagerDoc = linkManagerDoc;
+ }
+ list.push(mainDoc);
+ mainDoc.title = `Workspace ${list.length}`;
}
- list.push(mainDoc);
- // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
- setTimeout(() => {
- this.openWorkspace(mainDoc);
- // let pendingDocument = Docs.StackingDocument([], { title: "New Mobile Uploads" });
- // mainDoc.optionalRightCollection = pendingDocument;
- }, 0);
}
+ // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
+ setTimeout(() => {
+ this.openWorkspace(mainDoc);
+ // let pendingDocument = Docs.StackingDocument([], { title: "New Mobile Uploads" });
+ // mainDoc.optionalRightCollection = pendingDocument;
+ }, 0);
}
@action
openWorkspace = async (doc: Doc, fromHistory = false) => {
CurrentUserUtils.MainDocId = doc[Id];
this.mainContainer = doc;
- const state = HistoryUtil.parseUrl(window.location) || {} as any;
- fromHistory || HistoryUtil.pushState({ type: "doc", docId: doc[Id], readonly: state.readonly, nro: state.nro });
- if (state.readonly === true || state.readonly === null) {
+ let state = this.urlState;
+ if (state.sharing === true && !this.userDoc) {
DocServer.Control.makeReadOnly();
- } else if (state.safe) {
- if (!state.nro) {
+ } else {
+ fromHistory || HistoryUtil.pushState({
+ type: "doc",
+ docId: doc[Id],
+ readonly: state.readonly,
+ nro: state.nro,
+ sharing: false,
+ });
+ if (state.readonly === true || state.readonly === null) {
+ DocServer.Control.makeReadOnly();
+ } else if (state.safe) {
+ if (!state.nro) {
+ DocServer.Control.makeReadOnly();
+ }
+ CollectionBaseView.SetSafeMode(true);
+ } else if (state.nro || state.nro === null || state.readonly === false) {
+ } else if (BoolCast(doc.readOnly)) {
DocServer.Control.makeReadOnly();
+ } else {
+ DocServer.Control.makeEditable();
}
- CollectionBaseView.SetSafeMode(true);
- } else if (state.nro || state.nro === null || state.readonly === false) {
- } else if (BoolCast(doc.readOnly)) {
- DocServer.Control.makeReadOnly();
- } else {
- DocServer.Control.makeEditable();
}
- const col = await Cast(CurrentUserUtils.UserDocument.optionalRightCollection, Doc);
+ let col: Opt<Doc>;
// if there is a pending doc, and it has new data, show it (syip: we use a timeout to prevent collection docking view from being uninitialized)
setTimeout(async () => {
- if (col) {
+ if (this.userDoc && (col = await Cast(this.userDoc.optionalRightCollection, Doc))) {
const l = Cast(col.data, listSpec(Doc));
if (l) {
runInAction(() => CollectionTreeView.NotifsCol = col);
@@ -404,11 +460,12 @@ export class MainView extends React.Component {
}
@computed
get flyout() {
- let sidebar = CurrentUserUtils.UserDocument.sidebar;
- if (!(sidebar instanceof Doc)) return (null);
- let sidebarDoc = sidebar;
+ let sidebar: FieldResult<Field>;
+ if (!this.userDoc || !((sidebar = this.userDoc.sidebar) instanceof Doc)) {
+ return (null);
+ }
return <DocumentView
- Document={sidebarDoc}
+ Document={sidebar}
DataDoc={undefined}
addDocument={undefined}
addDocTab={this.addDocTabFunc}
@@ -435,34 +492,49 @@ export class MainView extends React.Component {
@computed
get mainContent() {
- let sidebar = CurrentUserUtils.UserDocument.sidebar;
- if (!(sidebar instanceof Doc)) return (null);
- return <div className="mainContent" style={{ width: "100%", height: "100%", position: "absolute" }}>
- <div onPointerLeave={this.pointerLeaveDragger}>
- <div className="mainView-libraryHandle"
- style={{ cursor: "ew-resize", left: `${(this.flyoutWidth * (this.flyoutTranslate ? 1 : 0)) - 10}px`, backgroundColor: `${StrCast(sidebar.backgroundColor, "lightGray")}` }}
- onPointerDown={this.onPointerDown} onPointerOver={this.pointerOverDragger}>
- <span title="library View Dragger" style={{
- width: (this.flyoutWidth !== 0 && this.flyoutTranslate) ? "100%" : "5vw",
- height: (this.flyoutWidth !== 0 && this.flyoutTranslate) ? "100%" : "30vh",
- position: "absolute",
- top: (this.flyoutWidth !== 0 && this.flyoutTranslate) ? "" : "-10vh"
- }} />
- </div>
- <div className="mainView-libraryFlyout" style={{
- width: `${this.flyoutWidth}px`,
- zIndex: 1,
- transformOrigin: this.flyoutTranslate ? "" : "left center",
- transition: this.flyoutTranslate ? "" : "width .5s",
- transform: `scale(${this.flyoutTranslate ? 1 : 0.8})`,
- boxShadow: this.flyoutTranslate ? "" : "rgb(156, 147, 150) 0.2vw 0.2vw 0.8vw"
- }}>
- {this.flyout}
- {this.expandButton}
+ if (!this.userDoc) {
+ return (<div>{this.dockingContent}</div>);
+ }
+ let sidebar = this.userDoc.sidebar;
+ if (!(sidebar instanceof Doc)) {
+ return (null);
+ }
+ return (
+ <div className="mainContent" style={{ width: "100%", height: "100%", position: "absolute" }}>
+ <div onPointerLeave={this.pointerLeaveDragger}>
+ <div className="mainView-libraryHandle"
+ style={{ cursor: "ew-resize", left: `${(this.flyoutWidth * (this.flyoutTranslate ? 1 : 0)) - 10}px`, backgroundColor: `${StrCast(sidebar.backgroundColor, "lightGray")}` }}
+ onPointerDown={this.onPointerDown} onPointerOver={this.pointerOverDragger}>
+ <span title="library View Dragger" style={{
+ width: (this.flyoutWidth !== 0 && this.flyoutTranslate) ? "100%" : "5vw",
+ height: (this.flyoutWidth !== 0 && this.flyoutTranslate) ? "100%" : "30vh",
+ position: "absolute",
+ top: (this.flyoutWidth !== 0 && this.flyoutTranslate) ? "" : "-10vh"
+ }} />
+ </div>
+ <div className="mainView-libraryFlyout" style={{
+ width: `${this.flyoutWidth}px`,
+ zIndex: 1,
+ transformOrigin: this.flyoutTranslate ? "" : "left center",
+ transition: this.flyoutTranslate ? "" : "width .5s",
+ transform: `scale(${this.flyoutTranslate ? 1 : 0.8})`,
+ boxShadow: this.flyoutTranslate ? "" : "rgb(156, 147, 150) 0.2vw 0.2vw 0.8vw"
+ }}>
+ {this.flyout}
+ {this.expandButton}
+ </div>
</div>
- </div>
- {this.dockingContent}
- </div>;
+ {this.dockingContent}
+ </div>);
+ }
+
+ @computed get expandButton() {
+ return !this.flyoutTranslate ? (<div className="expandFlyoutButton" title="Re-attach sidebar" onPointerDown={() => {
+ runInAction(() => {
+ this.flyoutWidth = 250;
+ this.flyoutTranslate = true;
+ });
+ }}><FontAwesomeIcon icon="chevron-right" color="grey" size="lg" /></div>) : (null);
}
selected = (tool: InkTool) => {
@@ -481,14 +553,22 @@ export class MainView extends React.Component {
}
}
- toggleLinkFollowBox = (shouldClose: boolean) => {
- if (LinkFollowBox.Instance) {
- let dvs = DocumentManager.Instance.getDocumentViews(LinkFollowBox.Instance.props.Document);
- // if it already exisits, close it
- LinkFollowBox.Instance.props.Document.isMinimized = (dvs.length > 0 && shouldClose);
- }
+ setWriteMode = (mode: DocServer.WriteMode) => {
+ console.log(DocServer.WriteMode[mode]);
+ const mode1 = mode;
+ const mode2 = mode === DocServer.WriteMode.Default ? mode : DocServer.WriteMode.Playground;
+ DocServer.setFieldWriteMode("x", mode1);
+ DocServer.setFieldWriteMode("y", mode1);
+ DocServer.setFieldWriteMode("width", mode1);
+ DocServer.setFieldWriteMode("height", mode1);
+
+ DocServer.setFieldWriteMode("panX", mode2);
+ DocServer.setFieldWriteMode("panY", mode2);
+ DocServer.setFieldWriteMode("scale", mode2);
+ DocServer.setFieldWriteMode("viewType", mode2);
}
+
@observable private _colorPickerDisplay = false;
/* for the expandable add nodes menu. Not included with the miscbuttons because once it expands it expands the whole div with it, making canvas interactions limited. */
nodesMenu() {
@@ -504,12 +584,15 @@ export class MainView extends React.Component {
// let youtubeurl = "https://www.youtube.com/embed/TqcApsGRzWw";
// let addYoutubeSearcher = action(() => Docs.Create.YoutubeDocument(youtubeurl, { width: 600, height: 600, title: "youtube search" }));
- let btns: [React.RefObject<HTMLDivElement>, IconName, string, () => Doc][] = [
+ // let googlePhotosSearch = () => GooglePhotosClientUtils.CollectionFromSearch(Docs.Create.MasonryDocument, { included: [GooglePhotosClientUtils.ContentCategories.LANDSCAPES] });
+
+ let btns: [React.RefObject<HTMLDivElement>, IconName, string, () => Doc | Promise<Doc>][] = [
[React.createRef<HTMLDivElement>(), "object-group", "Add Collection", addColNode],
[React.createRef<HTMLDivElement>(), "tv", "Add Presentation Trail", addPresNode],
[React.createRef<HTMLDivElement>(), "globe-asia", "Add Website", addWebNode],
[React.createRef<HTMLDivElement>(), "bolt", "Add Button", addButtonDocument],
[React.createRef<HTMLDivElement>(), "file", "Add Document Dragger", addDragboxNode],
+ // [React.createRef<HTMLDivElement>(), "object-group", "Test Google Photos Search", googlePhotosSearch],
[React.createRef<HTMLDivElement>(), "cloud-upload-alt", "Import Directory", addImportCollectionNode], //remove at some point in favor of addImportCollectionNode
//[React.createRef<HTMLDivElement>(), "play", "Add Youtube Searcher", addYoutubeSearcher],
];
@@ -531,7 +614,7 @@ export class MainView extends React.Component {
<FontAwesomeIcon icon={btn[1]} size="sm" />
</button>
</div></li>)}
- <li key="linkFollow"><button className="add-button round-button" title="Open Link Follower" onClick={() => this.toggleLinkFollowBox(true)}><FontAwesomeIcon icon="link" size="sm" /></button></li>
+ <li key="undoTest"><button className="add-button round-button" title="Click if undo isn't working" onClick={() => UndoManager.TraceOpenBatches()}><FontAwesomeIcon icon="exclamation" size="sm" /></button></li>
<li key="color"><button className="add-button round-button" title="Select Color" style={{ zIndex: 1000 }} onClick={() => this.toggleColorPicker()}><div className="toolbar-color-button" style={{ backgroundColor: InkingControl.Instance.selectedColor }} >
<div className="toolbar-color-picker" onClick={this.onColorClick} style={this._colorPickerDisplay ? { color: "black", display: "block" } : { color: "black", display: "none" }}>
<SketchPicker color={InkingControl.Instance.selectedColor} onChange={InkingControl.Instance.switchColor} />
@@ -542,6 +625,7 @@ export class MainView extends React.Component {
<li key="marker"><button onClick={() => InkingControl.Instance.switchTool(InkTool.Highlighter)} title="Highlighter" style={this.selected(InkTool.Highlighter)}><FontAwesomeIcon icon="highlighter" size="lg" /></button></li>
<li key="eraser"><button onClick={() => InkingControl.Instance.switchTool(InkTool.Eraser)} title="Eraser" style={this.selected(InkTool.Eraser)}><FontAwesomeIcon icon="eraser" size="lg" /></button></li>
<li key="inkControls"><InkingControl /></li>
+ <li key="logout"><button onClick={() => window.location.assign(Utils.prepend(RouteStore.logout))}>{CurrentUserUtils.GuestWorkspace ? "Exit" : "Log Out"}</button></li>
</ul>
</div>
</div >;
@@ -557,12 +641,8 @@ export class MainView extends React.Component {
/* @TODO this should really be moved into a moveable toolbar component, but for now let's put it here to meet the deadline */
@computed
get miscButtons() {
- let logoutRef = React.createRef<HTMLDivElement>();
-
return [
this.isSearchVisible ? <div className="main-searchDiv" key="search" style={{ top: '34px', right: '1px', position: 'absolute' }} > <FilterBox /> </div> : null,
- <div className="main-buttonDiv" key="logout" style={{ bottom: '0px', right: '1px', position: 'absolute' }} ref={logoutRef}>
- <button onClick={() => window.location.assign(Utils.prepend(RouteStore.logout))}>Log Out</button></div>
];
}
@@ -573,55 +653,35 @@ export class MainView extends React.Component {
this.isSearchVisible = !this.isSearchVisible;
}
- private get dictationOverlay() {
- let display = this.dictationOverlayVisible;
+ @computed private get dictationOverlay() {
let success = this.dictationSuccess;
let result = this.isListening && !this.isListening.interim ? DictationManager.placeholder : `"${this.dictatedPhrase}"`;
+ let dialogueBoxStyle = {
+ background: success === undefined ? "gainsboro" : success ? "lawngreen" : "red",
+ borderColor: this.isListening ? "red" : "black",
+ fontStyle: "italic"
+ };
+ let overlayStyle = {
+ backgroundColor: this.isListening ? "red" : "darkslategrey"
+ };
return (
- <div>
- <div
- className={"dictation-prompt"}
- style={{
- opacity: display ? 1 : 0,
- background: success === undefined ? "gainsboro" : success ? "lawngreen" : "red",
- borderColor: this.isListening ? "red" : "black",
- }}
- >{result}</div>
- <div
- className={"dictation-prompt-overlay"}
- style={{
- opacity: display ? 0.4 : 0,
- backgroundColor: this.isListening ? "red" : "darkslategrey"
- }}
- />
- </div>
+ <MainViewModal
+ contents={result}
+ isDisplayed={this.dictationOverlayVisible}
+ interactive={false}
+ dialogueBoxStyle={dialogueBoxStyle}
+ overlayStyle={overlayStyle}
+ />
);
}
- @computed get miniPresentation() {
- let next = () => PresBox.CurrentPresentation.next();
- let back = () => PresBox.CurrentPresentation.back();
- let startOrResetPres = () => PresBox.CurrentPresentation.startOrResetPres();
- let closePresMode = action(() => { PresBox.CurrentPresentation.presMode = false; this.addDocTabFunc(PresBox.CurrentPresentation.props.Document, undefined, "onRight"); });
- return !PresBox.CurrentPresentation || !PresBox.CurrentPresentation.presMode ? (null) : <PresModeMenu next={next} back={back} presStatus={PresBox.CurrentPresentation.presStatus} startOrResetPres={startOrResetPres} closePresMode={closePresMode} > </PresModeMenu>;
- }
-
- @computed get expandButton() {
- return !this.flyoutTranslate ? (<div className="expandFlyoutButton" title="Re-attach sidebar" onPointerDown={() => {
- runInAction(() => {
- this.flyoutWidth = 250;
- this.flyoutTranslate = true;
- });
- }}><FontAwesomeIcon icon="chevron-right" color="grey" size="lg" /></div>) : (null);
- }
-
render() {
return (
<div id="main-div">
{this.dictationOverlay}
+ <SharingManager />
<DocumentDecorations />
{this.mainContent}
- {this.miniPresentation}
<PreviewCursor />
<ContextMenu />
{this.nodesMenu()}