aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Wilkins <samwilkins333@gmail.com>2020-06-06 00:04:54 -0700
committerSam Wilkins <samwilkins333@gmail.com>2020-06-06 00:04:54 -0700
commit1a6feb447f9c4fd461ba02dc45a93e569a283be0 (patch)
tree2cadb27d639656f51ee7820589fe62cbf1716300 /src
parentcdc9c7e293a656573d49c4265b5867e34e8db7c8 (diff)
initial commit
Diffstat (limited to 'src')
-rw-r--r--src/mobile/ImageUpload.scss55
-rw-r--r--src/mobile/ImageUpload.tsx74
-rw-r--r--src/mobile/MobileInkOverlay.tsx4
-rw-r--r--src/mobile/MobileInterface.scss9
-rw-r--r--src/mobile/MobileInterface.tsx526
-rw-r--r--src/mobile/MobileMain.tsx25
-rw-r--r--src/mobile/MobileMenu.scss240
-rw-r--r--src/mobile/SideBar.scss79
-rw-r--r--src/mobile/SideBar.tsx39
-rw-r--r--src/mobile/WorkSpaceButton.scss0
-rw-r--r--src/mobile/WorkSpaceButton.tsx14
11 files changed, 851 insertions, 214 deletions
diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss
index eea69b81c..6ebf33438 100644
--- a/src/mobile/ImageUpload.scss
+++ b/src/mobile/ImageUpload.scss
@@ -1,12 +1,26 @@
@import "../client/views/globalCssVariables.scss";
.imgupload_cont {
- display: flex;
- justify-content: center;
- flex-direction: column;
- align-items: center;
- width: 100vw;
- height: 100vh;
+ // display: flex;
+ // justify-content: center;
+ // flex-direction: column;
+ // align-items: center;
+ // width: 100vw;
+ // height: 100vh;
+
+ .upload_label {
+ font-weight: normal !important;
+ width: 100%;
+ padding: 13px 12px;
+ border-bottom: 1px solid rgba(200, 200, 200, 0.7);
+ font-family: Arial, Helvetica, sans-serif;
+ font-style: normal;
+ font-weight: normal;
+ user-select: none;
+ font-size: 35px;
+ text-transform: uppercase;
+ color: black;
+ }
.button_file {
text-align: center;
@@ -21,14 +35,27 @@
display: none;
}
- .upload_label,
+ // .upload_label,
+ // .upload_button {
+ // background: $dark-color;
+ // font-size: 500%;
+ // font-family: $sans-serif;
+ // text-align: center;
+ // padding: 5vh;
+ // margin-bottom: 20px;
+ // color: white;
+ // }
+
.upload_button {
- background: $dark-color;
- font-size: 500%;
- font-family: $sans-serif;
- text-align: center;
- padding: 5vh;
- margin-bottom: 20px;
- color: white;
+ width: 100%;
+ padding: 13px 12px;
+ border-bottom: 1px solid rgba(200, 200, 200, 0.7);
+ font-family: Arial, Helvetica, sans-serif;
+ font-style: normal;
+ font-weight: normal;
+ user-select: none;
+ font-size: 35px;
+ text-transform: uppercase;
+ color: black;
}
} \ No newline at end of file
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index b15042f9f..c35c4a917 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -4,16 +4,18 @@ import { Docs } from '../client/documents/Documents';
import "./ImageUpload.scss";
import React = require('react');
import { DocServer } from '../client/DocServer';
-import { Opt, Doc } from '../fields/Doc';
-import { Cast } from '../fields/Types';
-import { listSpec } from '../fields/Schema';
-import { List } from '../fields/List';
import { observer } from 'mobx-react';
import { observable } from 'mobx';
import { Utils } from '../Utils';
-import MobileInterface from './MobileInterface';
-import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
-import { resolvedPorts } from '../client/views/Main';
+import { Networking } from '../client/Network';
+import { Doc, Opt } from '../fields/Doc';
+import { Cast } from '../fields/Types';
+import { listSpec } from '../fields/Schema';
+import { List } from '../fields/List';
+
+export interface ImageUploadProps {
+ Document: Doc;
+}
// const onPointerDown = (e: React.TouchEvent) => {
// let imgInput = document.getElementById("input_image_file");
@@ -24,7 +26,7 @@ import { resolvedPorts } from '../client/views/Main';
const inputRef = React.createRef<HTMLInputElement>();
@observer
-class Uploader extends React.Component {
+export class Uploader extends React.Component<ImageUploadProps> {
@observable error: string = "";
@observable status: string = "";
@@ -39,20 +41,15 @@ class Uploader extends React.Component {
if (files && files.length !== 0) {
console.log(files[0]);
const name = files[0].name;
- const formData = new FormData();
- formData.append("file", files[0]);
-
- const upload = window.location.origin + "/uploadFormData";
+ const res = await Networking.UploadFilesToServer(files[0]);
this.status = "uploading image";
- console.log("uploading image", formData);
- const res = await fetch(upload, {
- method: 'POST',
- body: formData
- });
this.status = "upload image, getting json";
- const json = await res.json();
- json.map(async (file: any) => {
- const path = window.location.origin + file;
+
+ res.map(async ({ result }) => {
+ if (result instanceof Error) {
+ return;
+ }
+ const path = Utils.prepend(result.accessPaths.agnostic.client);
const doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name });
this.status = "getting user document";
@@ -75,12 +72,10 @@ class Uploader extends React.Component {
pending.data = new List([doc]);
}
this.status = "finished";
+ console.log("hi");
}
- });
-
- // console.log(window.location.origin + file[0])
- //imgPrev.setAttribute("src", window.location.origin + files[0].name)
+ });
}
}
} catch (error) {
@@ -91,12 +86,12 @@ class Uploader extends React.Component {
render() {
return (
<div className="imgupload_cont">
- <label htmlFor="input_image_file" className="upload_label">Choose an Image</label>
+ <label htmlFor="input_image_file" className="upload_label" onClick={this.onClick}>Upload Image</label>
<input type="file" accept="image/*" className="input_file" id="input_image_file" ref={inputRef}></input>
- <button onClick={this.onClick} className="upload_button">Upload</button>
+ {/* <div onClick={this.onClick} className="upload_button">Upload</div> */}
<img id="img_preview" src=""></img>
- <p>{this.status}</p>
- <p>{this.error}</p>
+ {/* <p>{this.status}</p>
+ <p>{this.error}</p> */}
</div>
);
}
@@ -104,25 +99,4 @@ class Uploader extends React.Component {
}
-// DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts.socket, "image upload");
-(async () => {
- const info = await CurrentUserUtils.loadCurrentUser();
- DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts.socket, info.email + "mobile");
- await Docs.Prototypes.initialize();
- if (info.id !== "__guest__") {
- // a guest will not have an id registered
- await CurrentUserUtils.loadUserDocument(info);
- }
- document.getElementById('root')!.addEventListener('wheel', event => {
- if (event.ctrlKey) {
- event.preventDefault();
- }
- }, true);
- ReactDOM.render((
- // <Uploader />
- <MobileInterface />
- ),
- document.getElementById('root')
- );
-}
-)(); \ No newline at end of file
+// DocServer.init(window.location.protocol, window.location.hostname, 4321, "image upload");
diff --git a/src/mobile/MobileInkOverlay.tsx b/src/mobile/MobileInkOverlay.tsx
index 973931615..1b3388161 100644
--- a/src/mobile/MobileInkOverlay.tsx
+++ b/src/mobile/MobileInkOverlay.tsx
@@ -4,11 +4,9 @@ import { MobileInkOverlayContent, GestureContent, UpdateMobileInkOverlayPosition
import { observable, action } from "mobx";
import { GestureUtils } from "../pen-gestures/GestureUtils";
import "./MobileInkOverlay.scss";
-import { StrCast, Cast } from '../fields/Types';
import { DragManager } from "../client/util/DragManager";
import { DocServer } from '../client/DocServer';
-import { Doc, DocListCastAsync } from '../fields/Doc';
-import { listSpec } from '../fields/Schema';
+import { Doc } from '../fields/Doc';
@observer
diff --git a/src/mobile/MobileInterface.scss b/src/mobile/MobileInterface.scss
index 4d86e208f..f75e60a37 100644
--- a/src/mobile/MobileInterface.scss
+++ b/src/mobile/MobileInterface.scss
@@ -16,4 +16,13 @@
height: 100%;
position: relative;
touch-action: none;
+ width: 100%;
+}
+
+.mobileInterface-background {
+ height: 100%;
+ width: 100%;
+ position: relative;
+ touch-action: none;
+ background-color: pink;
} \ No newline at end of file
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 6c2e797d6..1f7244653 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1,47 +1,56 @@
import React = require('react');
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faEraser, faHighlighter, faLongArrowAltLeft, faMousePointer, faPenNib } from '@fortawesome/free-solid-svg-icons';
+import { faEraser, faHighlighter, faLongArrowAltLeft, faMousePointer, faPenNib, faThumbtack, faHome } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
-import { DocServer } from '../client/DocServer';
+import * as rp from 'request-promise';
import { Docs } from '../client/documents/Documents';
-import { DocumentManager } from '../client/util/DocumentManager';
-import RichTextMenu from '../client/views/nodes/formattedText/RichTextMenu';
-import { Scripting } from '../client/util/Scripting';
+import { DocumentView } from '../client/views/nodes/DocumentView';
+import { emptyPath, emptyFunction, returnFalse, returnOne, returnTrue, returnZero, Utils } from '../Utils';
import { Transform } from '../client/util/Transform';
-import { DocumentDecorations } from '../client/views/DocumentDecorations';
-import GestureOverlay from '../client/views/GestureOverlay';
+import { Scripting } from '../client/util/Scripting';
import { InkingControl } from '../client/views/InkingControl';
-import { DocumentView } from '../client/views/nodes/DocumentView';
-import { RadialMenu } from '../client/views/nodes/RadialMenu';
-import { PreviewCursor } from '../client/views/PreviewCursor';
+import "./MobileInterface.scss";
+import "./MobileMenu.scss";
+import { DocServer } from '../client/DocServer';
+import { DocumentManager } from '../client/util/DocumentManager';
+import SettingsManager from '../client/util/SettingsManager';
+import { Uploader } from "./ImageUpload";
+import { DockedFrameRenderer } from '../client/views/collections/CollectionDockingView';
import { Doc, DocListCast, FieldResult } from '../fields/Doc';
-import { Id } from '../fields/FieldSymbols';
+import { FieldValue, Cast, StrCast } from '../fields/Types';
import { InkTool } from '../fields/InkField';
import { listSpec } from '../fields/Schema';
-import { Cast, FieldValue } from '../fields/Types';
-import { WebField } from "../fields/URLField";
+import { nullAudio, WebField } from '../fields/URLField';
+import { Id } from '../fields/FieldSymbols';
import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
-import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero } from '../Utils';
-import "./MobileInterface.scss";
-import { CollectionView } from '../client/views/collections/CollectionView';
library.add(faLongArrowAltLeft);
+library.add(faHome);
@observer
-export default class MobileInterface extends React.Component {
+export class MobileInterface extends React.Component {
@observable static Instance: MobileInterface;
@computed private get userDoc() { return Doc.UserDoc(); }
@computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
+ @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; }
// @observable private currentView: "main" | "ink" | "upload" = "main";
- private mainDoc: any = CurrentUserUtils.setupMobileDoc(this.userDoc);
+ @observable private mainDoc: any = CurrentUserUtils.setupMobileDoc(this.userDoc);
@observable private renderView?: () => JSX.Element;
+ @observable private sidebarActive = true;
+
+ public _activeDoc: Doc = this.mainDoc;
// private inkDoc?: Doc;
public drawingInk: boolean = false;
- // private uploadDoc?: Doc;
+ // private _uploadDoc: Doc = this.userDoc;
+ private _child: Doc | null = null;
+ private _parents: Array<Doc> = [];
+ private _menu: Doc = this.mainDoc;
+ private _open: boolean = false;
+ private _library: Doc = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
constructor(props: Readonly<{}>) {
super(props);
@@ -50,7 +59,7 @@ export default class MobileInterface extends React.Component {
@action
componentDidMount = () => {
- library.add(...[faPenNib, faHighlighter, faEraser, faMousePointer]);
+ library.add(...[faPenNib, faHighlighter, faEraser, faMousePointer, faThumbtack]);
if (this.userDoc && !this.mainContainer) {
this.userDoc.activeMobile = this.mainDoc;
@@ -81,6 +90,7 @@ export default class MobileInterface extends React.Component {
onSwitchUpload = async () => {
let width = 300;
let height = 300;
+ const res = await rp.get(Utils.prepend("/getUserDocumentId"));
// get width and height of the collection doc
if (this.mainContainer) {
@@ -102,34 +112,243 @@ export default class MobileInterface extends React.Component {
});
}
- renderDefaultContent = () => {
+ back = () => {
+ const doc = Cast(this._parents.pop(), Doc) as Doc;
+ if (doc === Cast(this._menu, Doc) as Doc) {
+ this._child = null;
+ this.userDoc.activeMobile = this.mainDoc;
+ } else {
+ if (doc) {
+ this._child = doc;
+ this.switchCurrentView((userDoc: Doc) => doc);
+ }
+ }
+ if (doc) {
+ this._activeDoc = doc;
+ }
+ }
+
+ returnHome = () => {
+ this._parents = [];
+ this._activeDoc = this._menu;
+ this.switchCurrentView((userDoc: Doc) => this._menu);
+ this._child = null;
+ }
+
+ displayWorkspaces = () => {
if (this.mainContainer) {
- return <DocumentView
- Document={this.mainContainer}
- DataDoc={undefined}
- LibraryPath={emptyPath}
- addDocument={returnFalse}
- addDocTab={returnFalse}
- pinToPres={emptyFunction}
- rootSelected={returnFalse}
- removeDocument={undefined}
- onClick={undefined}
- ScreenToLocalTransform={Transform.Identity}
- ContentScaling={returnOne}
- NativeHeight={returnZero}
- NativeWidth={returnZero}
- PanelWidth={() => window.screen.width}
- PanelHeight={() => window.screen.height}
- renderDepth={0}
- focus={emptyFunction}
- backgroundColor={returnEmptyString}
- parentActive={returnTrue}
- whenActiveChanged={emptyFunction}
- bringToFront={emptyFunction}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined} />;
+ const backgroundColor = () => "white";
+ return (
+ <div style={{ position: "relative", top: '200px', height: `calc(100% - 250px)`, width: "100%", overflow: "hidden" }}>
+ <DocumentView
+ Document={this.mainContainer}
+ DataDoc={undefined}
+ LibraryPath={emptyPath}
+ addDocument={returnFalse}
+ addDocTab={returnFalse}
+ pinToPres={emptyFunction}
+ rootSelected={returnFalse}
+ removeDocument={undefined}
+ onClick={undefined}
+ ScreenToLocalTransform={Transform.Identity}
+ ContentScaling={returnOne}
+ NativeHeight={returnZero}
+ NativeWidth={returnZero}
+ PanelWidth={() => window.screen.width}
+ PanelHeight={() => window.screen.height}
+ renderDepth={0}
+ focus={emptyFunction}
+ backgroundColor={backgroundColor}
+ parentActive={returnTrue}
+ whenActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ />
+ </div>
+ );
+ }
+ }
+
+ handleClick(doc: Doc) {
+ const children = DocListCast(doc.data);
+ if (doc.type !== "collection") {
+ this._parents.push(this._activeDoc);
+ this._activeDoc = doc;
+ this.switchCurrentView((userDoc: Doc) => doc);
+ this.toggleSidebar();
+ } else if (doc.type === "collection" && children.length === 0) {
+ console.log("This collection has no children");
+ } else {
+ this._parents.push(this._activeDoc);
+ this._activeDoc = doc;
+ this.switchCurrentView((userDoc: Doc) => doc);
+ this._child = doc;
+ }
+
+ // let sidebar = document.getElementById("sidebar") as HTMLElement;
+ // sidebar.classList.toggle('active');
+ }
+
+ createPathname = () => {
+ let pathname = "";
+ this._parents.map((doc: Doc, index: any) => {
+ if (doc === this.mainDoc) {
+ pathname = pathname + doc.title;
+ } else {
+ pathname = pathname + " > " + doc.title;
+ }
+ });
+ if (this._activeDoc === this.mainDoc) {
+ pathname = pathname + this._activeDoc.title;
+ } else {
+ pathname = pathname + " > " + this._activeDoc.title;
+ }
+ return pathname;
+ }
+
+ @action
+ toggleSidebar = () => this.sidebarActive = !this.sidebarActive
+
+ openLibrary() {
+ this._activeDoc = this.mainDoc;
+ this.switchCurrentView(() => this.mainDoc);
+ this._child = this._library;
+ }
+
+ renderDefaultContent = () => {
+ const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+ const buttons = DocListCast(this._child ? this._child.data : workspaces.data).map((doc: Doc, index: any) => {
+ return (
+ <div
+ className="item"
+ key={index}
+ onClick={() => this.handleClick(doc)}>{doc.title}
+ <div className="type">{doc.type}</div>
+ <FontAwesomeIcon className="right" icon="angle-right" size="lg" />
+ </div>);
+ });
+ return (
+ <>
+ <div className="navbar">
+ <div className={"header"}>{this.sidebarActive ? StrCast(this._activeDoc.title) : "Menu"}</div>
+ <div
+ className={`toggle-btn ${this.sidebarActive ? "active" : ""}`}
+ onClick={this.toggleSidebar}
+ />
+ </div>
+ <div className="pathbar">
+ <div className="pathname">{this.createPathname()}</div>
+ </div>
+ <div className={`sidebar ${this.sidebarActive ? "active" : ""}`}>
+ <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
+ {this._child ?
+ <>
+ <div className="back" onClick={this.back}>&#8592;</div>
+ <div>{buttons}</div>
+ <div className="item" key="home" onClick={this.returnHome}>Home</div>
+ </> :
+ <>
+ {buttons}
+ {/* <div className="item" key="library" onClick={this.openLibrary}>
+ Library
+ </div> */}
+ <Uploader Document={workspaces} />
+ <div className="item" key="audio" onClick={this.recordAudio}>Record Audio</div>
+ <div className="item" key="presentation" onClick={this.openDefaultPresentation}>Presentation</div>
+ <div className="item" key="settings" onClick={() => SettingsManager.Instance.open()}>Settings</div>
+ </>
+ }
+ </div>
+ {this._child ? null : <div>{this.renderView}</div>}
+ </>
+ );
+ }
+
+ pinToPresentation = () => {
+ // Only making button available if it is an image
+ if (this._activeDoc.type === "image") {
+ const isPinned = this._activeDoc && Doc.isDocPinned(this._activeDoc);
+ return <div className="pinButton"
+ title={Doc.isDocPinned(this._activeDoc) ? "Unpin from presentation" : "Pin to presentation"}
+ style={{ backgroundColor: isPinned ? "black" : "white", color: isPinned ? "white" : "black" }}
+ onClick={e => {
+ if (isPinned) {
+ DockedFrameRenderer.UnpinDoc(this._activeDoc);
+ }
+ else {
+ DockedFrameRenderer.PinDoc(this._activeDoc);
+ }
+ }}>
+ <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
+ />
+ </div>;
+ }
+ }
+
+ recordAudio = async () => {
+ // upload to server with known URL
+ this._parents.push(this._activeDoc);
+ const audioDoc = Cast(Docs.Create.AudioDocument(nullAudio, { _width: 200, _height: 100, title: "mobile audio" }), Doc) as Doc;
+ if (audioDoc) {
+ console.log("audioClicked: " + audioDoc.title);
+ this._activeDoc = audioDoc;
+ this.switchCurrentView((userDoc: Doc) => audioDoc);
+ this.toggleSidebar();
+ }
+ const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc;
+ if (audioRightSidebar) {
+ console.log(audioRightSidebar.title);
+ const data = Cast(audioRightSidebar.data, listSpec(Doc));
+ if (data) {
+ data.push(audioDoc);
+ }
+ }
+ }
+
+ openDefaultPresentation = () => {
+ this._parents.push(this._activeDoc);
+ const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
+
+ if (presentation) {
+ console.log("presentation clicked: " + presentation.title);
+ this._activeDoc = presentation;
+ this.switchCurrentView((userDoc: Doc) => presentation);
+ this.toggleSidebar();
+ }
+ }
+
+ // mobileHome = () => {
+ // return (
+ // <div className="homeContainer">
+ // <div className="uploadButton">
+
+ // </div>
+ // <div className="presentationButton">
+
+ // </div>
+ // <div className="recordAudioButton">
+
+ // </div>
+ // <div className="inkButton">
+
+ // </div>
+ // <div className="settingsButton">
+
+ // </div>
+ // </div>
+ // );
+ // }
+
+ renderActiveCollection = (userDoc: Doc) => {
+ if (this.activeContainer) {
+ const active = Cast(this.activeContainer.data, listSpec(Doc));
+ if (active) {
+ return (
+ <div className="mobileInterface-background">HELLO!</div>
+ );
+ }
}
- return "hello";
}
onBack = (e: React.MouseEvent) => {
@@ -164,60 +383,15 @@ export default class MobileInterface extends React.Component {
panelHeight = () => window.innerHeight;
panelWidth = () => window.innerWidth;
- renderInkingContent = () => {
- console.log("rendering inking content");
- // TODO: support panning and zooming
- // TODO: handle moving of ink strokes
- if (this.mainContainer) {
- return (
- <div className="mobileInterface">
- <div className="mobileInterface-inkInterfaceButtons">
- <div className="navButtons">
- <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing">BACK</button>
- </div>
- <div className="inkSettingButtons">
- <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing"><FontAwesomeIcon icon="long-arrow-alt-left" /></button>
- </div>
- <div className="navButtons">
- <button className="mobileInterface-button" onClick={this.shiftLeft} title="Shift left">left</button>
- <button className="mobileInterface-button" onClick={this.shiftRight} title="Shift right">right</button>
- </div>
- </div>
- <CollectionView
- Document={this.mainContainer}
- DataDoc={undefined}
- LibraryPath={emptyPath}
- fieldKey={""}
- dropAction={"alias"}
- bringToFront={emptyFunction}
- addDocTab={returnFalse}
- pinToPres={emptyFunction}
- PanelWidth={this.panelWidth}
- PanelHeight={this.panelHeight}
- NativeHeight={returnZero}
- NativeWidth={returnZero}
- focus={emptyFunction}
- isSelected={returnFalse}
- select={emptyFunction}
- active={returnFalse}
- ContentScaling={returnOne}
- whenActiveChanged={returnFalse}
- ScreenToLocalTransform={Transform.Identity}
- renderDepth={0}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- rootSelected={returnTrue}>
- </CollectionView>
- </div>
- );
- }
- }
+ //WAS 3
+
+ //WAS 1
upload = async (e: React.MouseEvent) => {
if (this.mainContainer) {
const data = Cast(this.mainContainer.data, listSpec(Doc));
if (data) {
- const collectionDoc = await data[1]; // this should be the collection doc since the positions should be locked
+ const collectionDoc = await data[1]; //this should be the collection doc since the positions should be locked
const children = DocListCast(collectionDoc.data);
const uploadDoc = children.length === 1 ? children[0] : Docs.Create.StackingDocument(children, {
title: "Mobile Upload Collection", backgroundColor: "white", lockedPosition: true, _width: 300, _height: 300
@@ -260,45 +434,6 @@ export default class MobileInterface extends React.Component {
}
}
- renderUploadContent() {
- if (this.mainContainer) {
- return (
- <div className="mobileInterface" onDragOver={this.onDragOver}>
- <div className="mobileInterface-inkInterfaceButtons">
- <button className="mobileInterface-button cancel" onClick={this.onBack} title="Back">BACK</button>
- {/* <button className="mobileInterface-button" onClick={this.clearUpload} title="Clear Upload">CLEAR</button> */}
- {/* <button className="mobileInterface-button" onClick={this.addWeb} title="Add Web Doc to Upload Collection"></button> */}
- <button className="mobileInterface-button" onClick={this.upload} title="Upload">UPLOAD</button>
- </div>
- <DocumentView
- Document={this.mainContainer}
- DataDoc={undefined}
- LibraryPath={emptyPath}
- addDocument={returnFalse}
- addDocTab={returnFalse}
- pinToPres={emptyFunction}
- rootSelected={returnFalse}
- removeDocument={undefined}
- onClick={undefined}
- ScreenToLocalTransform={Transform.Identity}
- ContentScaling={returnOne}
- NativeHeight={returnZero}
- NativeWidth={returnZero}
- PanelWidth={() => window.screen.width}
- PanelHeight={() => window.screen.height}
- renderDepth={0}
- focus={emptyFunction}
- backgroundColor={returnEmptyString}
- parentActive={returnTrue}
- whenActiveChanged={emptyFunction}
- bringToFront={emptyFunction}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined} />
- </div>
- );
- }
- }
-
onDragOver = (e: React.DragEvent) => {
e.preventDefault();
e.stopPropagation();
@@ -314,18 +449,22 @@ export default class MobileInterface extends React.Component {
<GestureOverlay>
{this.renderView ? this.renderView() : this.renderDefaultContent()}
</GestureOverlay> */}
-
+ {/* <GestureOverlay> */}
+ <SettingsManager />
+ {this.displayWorkspaces()}
+ {this.pinToPresentation()}
+ {/* </GestureOverlay> */}
{/* <DictationOverlay />
<SharingManager />
<GoogleAuthenticationManager /> */}
- <DocumentDecorations />
- <GestureOverlay>
- {this.renderView ? this.renderView() : this.renderDefaultContent()}
- </GestureOverlay>
- <PreviewCursor />
+ {/* <DocumentDecorations /> */}
+ <div>
+ {this.renderDefaultContent()}
+ </div>
+ {/* <PreviewCursor /> */}
{/* <ContextMenu /> */}
- <RadialMenu />
- <RichTextMenu />
+ {/* <RadialMenu />
+ <RichTextMenu /> */}
{/* <PDFMenu />
<MarqueeOptionsMenu />
<OverlayView /> */}
@@ -335,9 +474,102 @@ export default class MobileInterface extends React.Component {
}
Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); });
-Scripting.addGlobal(function onSwitchMobileInking() { return MobileInterface.Instance.onSwitchInking(); });
-Scripting.addGlobal(function renderMobileInking() { return MobileInterface.Instance.renderInkingContent(); });
-Scripting.addGlobal(function onSwitchMobileUpload() { return MobileInterface.Instance.onSwitchUpload(); });
-Scripting.addGlobal(function renderMobileUpload() { return MobileInterface.Instance.renderUploadContent(); });
-Scripting.addGlobal(function addWebToMobileUpload() { return MobileInterface.Instance.addWebToCollection(); });
+// WAS 2
+
+// 1
+// renderUploadContent() {
+// if (this.mainContainer) {
+// return (
+// <div className="mobileInterface" onDragOver={this.onDragOver}>
+// <div className="mobileInterface-inkInterfaceButtons">
+// <button className="mobileInterface-button cancel" onClick={this.onBack} title="Back">BACK</button>
+// {/* <button className="mobileInterface-button" onClick={this.clearUpload} title="Clear Upload">CLEAR</button> */}
+// {/* <button className="mobileInterface-button" onClick={this.addWeb} title="Add Web Doc to Upload Collection"></button> */}
+// <button className="mobileInterface-button" onClick={this.upload} title="Upload">UPLOAD</button>
+// </div>
+// <DocumentView
+// Document={this.mainContainer}
+// DataDoc={undefined}
+// LibraryPath={emptyPath}
+// addDocument={returnFalse}
+// addDocTab={returnFalse}
+// pinToPres={emptyFunction}
+// rootSelected={returnFalse}
+// removeDocument={undefined}
+// onClick={undefined}
+// ScreenToLocalTransform={Transform.Identity}
+// ContentScaling={returnOne}
+// NativeHeight={returnZero}
+// NativeWidth={returnZero}
+// PanelWidth={() => window.screen.width}
+// PanelHeight={() => window.screen.height}
+// renderDepth={0}
+// focus={emptyFunction}
+// backgroundColor={returnEmptyString}
+// parentActive={returnTrue}
+// whenActiveChanged={emptyFunction}
+// bringToFront={emptyFunction}
+// ContainingCollectionView={undefined}
+// ContainingCollectionDoc={undefined} />
+// </div>
+// );
+// }
+// }
+
+// 2
+// Scripting.addGlobal(function onSwitchMobileInking() { return MobileInterface.Instance.onSwitchInking(); });
+// Scripting.addGlobal(function renderMobileInking() { return MobileInterface.Instance.renderInkingContent(); });
+// Scripting.addGlobal(function onSwitchMobileUpload() { return MobileInterface.Instance.onSwitchUpload(); });
+// Scripting.addGlobal(function renderMobileUpload() { return MobileInterface.Instance.renderUploadContent(); });
+ // Scripting.addGlobal(function addWebToMobileUpload() { return MobileInterface.Instance.addWebToCollection(); });
+
+// 3
+ // renderInkingContent = () => {
+ // console.log("rendering inking content");
+ // // TODO: support panning and zooming
+ // // TODO: handle moving of ink strokes
+ // if (this.mainContainer) {
+ // return (
+ // <div className="mobileInterface">
+ // <div className="mobileInterface-inkInterfaceButtons">
+ // <div className="navButtons">
+ // <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing">BACK</button>
+ // </div>
+ // <div className="inkSettingButtons">
+ // <button className="mobileInterface-button cancel" onClick={this.onBack} title="Cancel drawing"><FontAwesomeIcon icon="long-arrow-alt-left" /></button>
+ // </div>
+ // <div className="navButtons">
+ // <button className="mobileInterface-button" onClick={this.shiftLeft} title="Shift left">left</button>
+ // <button className="mobileInterface-button" onClick={this.shiftRight} title="Shift right">right</button>
+ // </div>
+ // </div>
+ // <CollectionView
+ // Document={this.mainContainer}
+ // DataDoc={undefined}
+ // LibraryPath={emptyPath}
+ // fieldKey={""}
+ // dropAction={"alias"}
+ // bringToFront={emptyFunction}
+ // addDocTab={returnFalse}
+ // pinToPres={emptyFunction}
+ // PanelWidth={this.panelWidth}
+ // PanelHeight={this.panelHeight}
+ // NativeHeight={returnZero}
+ // NativeWidth={returnZero}
+ // focus={emptyFunction}
+ // isSelected={returnFalse}
+ // select={emptyFunction}
+ // active={returnFalse}
+ // ContentScaling={returnOne}
+ // whenActiveChanged={returnFalse}
+ // ScreenToLocalTransform={Transform.Identity}
+ // renderDepth={0}
+ // ContainingCollectionView={undefined}
+ // ContainingCollectionDoc={undefined}
+ // rootSelected={returnTrue}>
+ // </CollectionView>
+ // </div>
+ // );
+ // }
+ // }
diff --git a/src/mobile/MobileMain.tsx b/src/mobile/MobileMain.tsx
new file mode 100644
index 000000000..34f06438f
--- /dev/null
+++ b/src/mobile/MobileMain.tsx
@@ -0,0 +1,25 @@
+import { DocServer } from '../client/DocServer';
+import { Docs } from '../client/documents/Documents';
+import * as ReactDOM from "react-dom";
+import { MobileInterface } from './MobileInterface';
+import * as React from "react";
+import { AssignAllExtensions } from '../extensions/General/Extensions';
+import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
+
+AssignAllExtensions();
+
+(async () => {
+ const info = await CurrentUserUtils.loadCurrentUser();
+ DocServer.init(window.location.protocol, window.location.hostname, 4321, info.email + " (mobile)");
+ await Docs.Prototypes.initialize();
+ if (info.id !== "__guest__") {
+ // a guest will not have an id registered
+ await CurrentUserUtils.loadUserDocument(info);
+ }
+ document.getElementById('root')!.addEventListener('wheel', event => {
+ if (event.ctrlKey) {
+ event.preventDefault();
+ }
+ }, true);
+ ReactDOM.render(<MobileInterface />, document.getElementById('root'));
+})(); \ No newline at end of file
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
new file mode 100644
index 000000000..250340e36
--- /dev/null
+++ b/src/mobile/MobileMenu.scss
@@ -0,0 +1,240 @@
+$navbar-height: 120px;
+$pathbar-height: 50px;
+
+* {
+ margin: 0px;
+ padding: 0px;
+ box-sizing: border-box;
+ font-family: "Open Sans";
+}
+
+body {
+ overflow: hidden;
+}
+
+.navbar {
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ width: 100vw;
+ height: $navbar-height;
+ background-color: whitesmoke;
+ border-bottom: 5px solid black;
+}
+
+.navbar .toggle-btn {
+ position: absolute;
+ right: 20px;
+ top: 30px;
+ height: 70px;
+ width: 70px;
+ transition: all 300ms ease-in-out 200ms;
+}
+
+.navbar .header {
+ position: absolute;
+ top: 50%;
+ top: calc(9px + 50%);
+ right: 50%;
+ transform: translate(50%, -50%);
+ font-size: 40;
+ user-select: none;
+ text-transform: uppercase;
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+.navbar .toggle-btn span {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 70%;
+ height: 4px;
+ background: black;
+ transition: all 200ms ease;
+}
+
+.navbar .toggle-btn span:nth-child(1) {
+ transition: top 200ms ease-in-out;
+ top: 30%;
+}
+
+.navbar .toggle-btn span:nth-child(3) {
+ transition: top 200ms ease-in-out;
+ top: 70%;
+}
+
+.navbar .toggle-btn.active {
+ transition: transform 200ms ease-in-out 200ms;
+ transform: rotate(135deg);
+}
+
+.navbar .toggle-btn.active span:nth-child(1) {
+ top: 50%;
+}
+
+.navbar .toggle-btn.active span:nth-child(2) {
+ transform: translate(-50%, -50%) rotate(90deg);
+}
+
+.navbar .toggle-btn.active span:nth-child(3) {
+ top: 50%;
+}
+
+.sidebar {
+ position: absolute;
+ top: 200px;
+ opacity: 0;
+ right: -100%;
+ width: 100%;
+ height: calc(100% - (200px));
+ z-index: 5;
+ background-color: whitesmoke;
+ transition: all 400ms ease 50ms;
+ padding: 20px;
+ // border-right: 5px solid black;
+}
+
+.sidebar .item {
+ width: 100%;
+ padding: 13px 12px;
+ border-bottom: 1px solid rgba(200, 200, 200, 0.7);
+ font-family: Arial, Helvetica, sans-serif;
+ font-style: normal;
+ font-weight: normal;
+ user-select: none;
+ font-size: 35px;
+ text-transform: uppercase;
+ color: black;
+}
+
+.sidebar .home {
+ position: absolute;
+ top: -135px;
+ right: calc(50% + 80px);
+ transform: translate(0%, -50%);
+ font-size: 40;
+ user-select: none;
+ text-transform: uppercase;
+ font-family: Arial, Helvetica, sans-serif;
+ z-index: 200;
+}
+
+.type {
+ display: inline;
+ text-transform: lowercase;
+ margin-left: 20px;
+ font-size: 35px;
+ font-style: italic;
+ color: rgb(28, 28, 28);
+}
+
+.right {
+ margin-left: 20px;
+ z-index: 200;
+}
+
+.left {
+ width: 100%;
+ height: 100%;
+}
+
+.sidebar .logout {
+ width: 100%;
+ padding: 13px 12px;
+ border-bottom: 1px solid rgba(200, 200, 200, 0.7);
+ font-family: Arial, Helvetica, sans-serif;
+ font-style: normal;
+ font-weight: normal;
+ user-select: none;
+ font-size: 30px;
+ text-transform: uppercase;
+ color: black;
+}
+
+.sidebar .settings {
+ width: 100%;
+ padding: 13px 12px;
+ border-bottom: 1px solid rgba(200, 200, 200, 0.7);
+ font-family: Arial, Helvetica, sans-serif;
+ font-style: normal;
+ font-weight: normal;
+ user-select: none;
+ font-size: 30px;
+ text-transform: uppercase;
+ color: black;
+}
+
+
+.sidebar.active {
+ right: 0%;
+ opacity: 1;
+}
+
+.back {
+ position: absolute;
+ top: -140px;
+ left: 50px;
+ transform: translate(0%, -50%);
+ color: black;
+ font-size: 60;
+ user-select: none;
+ text-transform: uppercase;
+ z-index: 100;
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+
+.pathbar {
+ position: absolute;
+ top: 118px;
+ background: #1a1a1a;
+ z-index: 20;
+ border-radius: 0px;
+ width: 100%;
+ height: 80px;
+ transition: all 400ms ease 50ms;
+}
+
+.pathname {
+ position: relative;
+ font-size: 25;
+ top: 50%;
+ width: 90%;
+ left: 3%;
+ color: whitesmoke;
+ transform: translate(0%, -50%);
+ z-index: 20;
+ font-family: sans-serif;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ direction: rtl;
+ text-align: left;
+ text-transform: uppercase;
+}
+
+.homeContainer {
+ position: relative;
+ top: 200px;
+ height: calc(100% - 250px);
+ width: 90%;
+ overflow: scroll;
+ left: 5%;
+ background-color: lightpink;
+}
+
+.pinButton {
+ position: relative;
+ width: 100px;
+ height: 100px;
+ font-size: 90px;
+ text-align: center;
+ left: 50%;
+ transform: translate(-50%, 0);
+ border-style: solid;
+ border-radius: 50px;
+ border-width: medium;
+ background-color: pink;
+ z-index: 100;
+} \ No newline at end of file
diff --git a/src/mobile/SideBar.scss b/src/mobile/SideBar.scss
new file mode 100644
index 000000000..fb6d13a2b
--- /dev/null
+++ b/src/mobile/SideBar.scss
@@ -0,0 +1,79 @@
+* {
+ margin:0px;
+ padding:0px;
+ box-sizing:border-box;
+ font-family:"Open Sans";
+}
+body {
+ overflow:hidden;
+}
+.navbar {
+ position:fixed;
+ top:0px;
+ left:0px;
+ width:100vw;
+ height:50px;
+ background:rgba(0,0,0,0.95);
+}
+.navbar .toggle-btn {
+ position:absolute;
+ right:20px;
+ height:50px;
+ width:50px;
+ transition:all 300ms ease-in-out 200ms;
+}
+.navbar .toggle-btn span {
+ position:absolute;
+ top:50%;
+ left:50%;
+ transform:translate(-50%,-50%);
+ width:70%;
+ height:4px;
+ background:#eee;
+ transition:all 200ms ease;
+}
+.navbar .toggle-btn span:nth-child(1) {
+ transition:top 200ms ease-in-out;
+ top:30%;
+}
+.navbar .toggle-btn span:nth-child(3) {
+ transition:top 200ms ease-in-out;
+ top:70%;
+}
+.navbar .toggle-btn.active {
+ transition:transform 200ms ease-in-out 200ms;
+ transform:rotate(135deg);
+}
+.navbar .toggle-btn.active span:nth-child(1) {
+ top:50%;
+}
+.navbar .toggle-btn.active span:nth-child(2) {
+ transform:translate(-50%,-50%) rotate(90deg);
+}
+.navbar .toggle-btn.active span:nth-child(3) {
+ top:50%;
+}
+.sidebar {
+ position:absolute;
+ top:50px;
+ opacity:0;
+ right:-100%;
+ width:100vw;
+ height:calc(100vh - 45px);
+ z-index:5;
+ background:rgba(40,40,40,1);
+ transition:all 400ms ease 50ms;
+ padding:15px;
+}
+.sidebar .item {
+ width:100%;
+ padding:13px 6px;
+ border-bottom:1px solid rgba(200,200,200,0.7);
+ font-size:18px;
+ text-transform:uppercase;
+ color:rgba(250,250,250,0.95);
+}
+.sidebar.active {
+ right:0%;
+ opacity:1;
+} \ No newline at end of file
diff --git a/src/mobile/SideBar.tsx b/src/mobile/SideBar.tsx
new file mode 100644
index 000000000..a06069ed8
--- /dev/null
+++ b/src/mobile/SideBar.tsx
@@ -0,0 +1,39 @@
+import React = require("react");
+import { observer } from "mobx-react";
+import "./SideBar.scss";
+import { computed } from "mobx";
+import { DocumentView } from '../client/views/nodes/DocumentView';
+
+@observer
+export class SideBar extends React.Component<{ views: (DocumentView | undefined)[], stack?: any }, {}>{
+
+ constructor(props: { views: (DocumentView | undefined)[] }) {
+ super(props);
+ }
+
+ @computed
+ onClick() {
+ document.getElementsByClassName('sidebar')
+ [0].classList.toggle('active');
+ }
+
+ render() {
+ return (
+ <>
+ <div className="navbar">
+ <div className="toggle-btn" onClick={this.onClick}>
+ <span></span>
+ <span></span>
+ <span></span>
+ </div>
+ </div>
+ <div className="sidebar">
+ <div className="item">Workspace1</div>
+ <div className="item">Workspace2</div>
+ <div className="item">Workspace3</div>
+ </div>
+ </>
+ );
+ }
+
+} \ No newline at end of file
diff --git a/src/mobile/WorkSpaceButton.scss b/src/mobile/WorkSpaceButton.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/mobile/WorkSpaceButton.scss
diff --git a/src/mobile/WorkSpaceButton.tsx b/src/mobile/WorkSpaceButton.tsx
new file mode 100644
index 000000000..70c3e6edc
--- /dev/null
+++ b/src/mobile/WorkSpaceButton.tsx
@@ -0,0 +1,14 @@
+import React = require('react');
+import { observer } from "mobx-react";
+import { observable } from 'mobx';
+
+interface IProps {
+ open: boolean;
+}
+
+@observer
+export class MenuButton extends React.Component<IProps> {
+ @observable static Instance: MenuButton;
+
+
+} \ No newline at end of file