From 88593faa4777b622ed5a3208f6462cf7b307b83a Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Tue, 26 May 2020 23:09:56 -0700 Subject: pulled from master --- src/.DS_Store | Bin 6148 -> 8196 bytes src/client/util/CurrentUserUtils.ts | 4 + src/client/views/nodes/FieldView.tsx | 6 +- src/mobile/ImageUpload.scss | 55 +++- src/mobile/ImageUpload.tsx | 67 ++-- src/mobile/MobileInterface.scss | 9 + src/mobile/MobileInterface.tsx | 600 ++++++++++++++++++++++++++--------- src/mobile/MobileMenu.scss | 240 ++++++++++++++ 8 files changed, 770 insertions(+), 211 deletions(-) create mode 100644 src/mobile/MobileMenu.scss (limited to 'src') diff --git a/src/.DS_Store b/src/.DS_Store index 5b35884bd..299b902c6 100644 Binary files a/src/.DS_Store and b/src/.DS_Store differ diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 496099557..377f908e9 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -444,6 +444,10 @@ export class CurrentUserUtils { }); } + static setupMobileMenu(userDoc: Doc) { + return CurrentUserUtils.setupWorkspaces(userDoc); + } + static setupMobileInkingDoc(userDoc: Doc) { return Docs.Create.FreeformDocument([], { title: "Mobile Inking", backgroundColor: "white" }); } diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index e9dc43bd8..0bb1401aa 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -91,9 +91,9 @@ export class FieldView extends React.Component { else if (field instanceof VideoField) { return ; } - else if (field instanceof AudioField) { - return ; - } else if (field instanceof DateField) { + // else if (field instanceof AudioField) { + // return ; + else if (field instanceof DateField) { return

{field.date.toLocaleString()}

; } else if (field instanceof Doc) { diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss index eea69b81c..715924cba 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..2552e2112 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -4,16 +4,19 @@ 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 { Opt, Doc, DocListCast } 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 { MobileDocumentUploadContent } from '../server/Message'; + +export interface ImageUploadProps { + Document: Doc; +} // const onPointerDown = (e: React.TouchEvent) => { // let imgInput = document.getElementById("input_image_file"); @@ -24,7 +27,7 @@ import { resolvedPorts } from '../client/views/Main'; const inputRef = React.createRef(); @observer -class Uploader extends React.Component { +export class Uploader extends React.Component { @observable error: string = ""; @observable status: string = ""; @@ -39,20 +42,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 +73,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 +87,12 @@ class Uploader extends React.Component { render() { return (
- + - + {/*
Upload
*/}

{this.status}

-

{this.error}

+ {/*

{this.error}

*/}
); } @@ -104,25 +100,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(( - // - - ), - document.getElementById('root') - ); -} -)(); \ No newline at end of file +// DocServer.init(window.location.protocol, window.location.hostname, 4321, "image upload"); \ No newline at end of file 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..9b28d066c 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -1,47 +1,68 @@ 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 ReactDOM from "react-dom"; +import * as rp from 'request-promise'; +import { CurrentUserUtils } from '../client/util/CurrentUserUtils'; +import { FieldValue, Cast, StrCast } from '../fields/Types'; +import { Doc, DocListCast, Opt } from '../fields/Doc'; 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 { CollectionView } from '../client/views/collections/CollectionView'; +import { DocumentView } from '../client/views/nodes/DocumentView'; +import { emptyPath, emptyFunction, returnFalse, returnOne, returnEmptyString, returnTrue, returnZero, Utils } from '../Utils'; import { Transform } from '../client/util/Transform'; -import { DocumentDecorations } from '../client/views/DocumentDecorations'; +import { Scripting } from '../client/util/Scripting'; import GestureOverlay from '../client/views/GestureOverlay'; import { InkingControl } from '../client/views/InkingControl'; -import { DocumentView } from '../client/views/nodes/DocumentView'; -import { RadialMenu } from '../client/views/nodes/RadialMenu'; +import { InkTool } from '../fields/InkField'; +import "./MobileInterface.scss"; +import "./MobileMenu.scss"; +import { DocServer } from '../client/DocServer'; +import { DocumentDecorations } from '../client/views/DocumentDecorations'; import { PreviewCursor } from '../client/views/PreviewCursor'; -import { Doc, DocListCast, FieldResult } from '../fields/Doc'; +import { RadialMenu } from '../client/views/nodes/RadialMenu'; import { Id } from '../fields/FieldSymbols'; -import { InkTool } from '../fields/InkField'; +import { WebField, nullAudio } from "../fields/URLField"; +import { FieldResult } from "../fields/Doc"; +import { AssignAllExtensions } from '../extensions/General/Extensions'; import { listSpec } from '../fields/Schema'; -import { Cast, FieldValue } from '../fields/Types'; -import { WebField } from "../fields/URLField"; -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'; +import { DocumentManager } from '../client/util/DocumentManager'; +import RichTextMenu from '../client/views/nodes/formattedText/RichTextMenu'; +import { MainView } from '../client/views/MainView'; +import SettingsManager from '../client/util/SettingsManager'; +import { Uploader } from "./ImageUpload"; +import { Upload } from '../server/SharedMediaTypes'; +import { createTypePredicateNodeWithModifier } from 'typescript'; +import { AudioBox } from '../client/views/nodes/AudioBox'; +import { List } from '../fields/List'; 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.setupMobileMenu(this.userDoc); @observable private renderView?: () => JSX.Element; + 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 = []; + 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 +71,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 +102,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 +124,286 @@ export default class MobileInterface extends React.Component { }); } - renderDefaultContent = () => { + toggleSidebar = () => { + console.log("clicked"); + let menuButton = document.getElementById("menuButton") as HTMLElement; + menuButton.classList.toggle('active'); + + let sidebar = document.getElementById("sidebar") as HTMLElement; + sidebar.classList.toggle('active'); + + let header = document.getElementById("header") as HTMLElement; + + if (!sidebar.classList.contains('active')) { + header.textContent = String(this._activeDoc.title); + } else { + header.textContent = "menu"; + } + } + + back = () => { + let 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 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 ( +
+ window.screen.width} + PanelHeight={() => window.screen.height} + renderDepth={0} + focus={emptyFunction} + backgroundColor={backgroundColor} + parentActive={returnTrue} + whenActiveChanged={emptyFunction} + bringToFront={emptyFunction} + ContainingCollectionView={undefined} + ContainingCollectionDoc={undefined} + /> +
+ ); + } + } + + handleClick(doc: Doc) { + let 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; + } + + openLibrary() { + this._activeDoc = this.mainDoc; + this.switchCurrentView((userDoc: Doc) => this.mainDoc); + this._child = this._library; + } + + renderDefaultContent = () => { + const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc; + let buttons = DocListCast(workspaces.data).map((doc: Doc, index: any) => { + return ( +
this.handleClick(doc)}>{doc.title} +
{doc.type}
+ +
); + }); + + if (this._child) { + buttons = DocListCast(this._child.data).map((doc: Doc, index: any) => { + return ( +
this.handleClick(doc)}>{doc.title} +
{doc.type}
+ +
); + }); + } + + if (!this._child) { + return ( +
+
+ + +
+
+
+ {this.createPathname()} +
+
+ +
+ {this.renderView} +
+
+ ); + } + else { + return ( +
+
+ + +
+
+
+ {this.createPathname()} +
+
+ +
+ ); + } + } + + recordAudio = async () => { + // upload to server with known URL + + 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 = () => { + 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 ( + //
+ //
+ + //
+ //
+ + //
+ //
+ + //
+ //
+ + //
+ //
+ + //
+ //
+ // ); + // } + + renderActiveCollection = (userDoc: Doc) => { + if (this.activeContainer) { + const active = Cast(this.activeContainer.data, listSpec(Doc)); + if (active) { + return ( +
HELLO!
+ ); + } } - return "hello"; } onBack = (e: React.MouseEvent) => { @@ -164,60 +438,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 ( -
-
-
- -
-
- -
-
- - -
-
- - -
- ); - } - } + //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 @@ -259,46 +488,6 @@ export default class MobileInterface extends React.Component { } } } - - renderUploadContent() { - if (this.mainContainer) { - return ( -
-
- - {/* */} - {/* */} - -
- window.screen.width} - PanelHeight={() => window.screen.height} - renderDepth={0} - focus={emptyFunction} - backgroundColor={returnEmptyString} - parentActive={returnTrue} - whenActiveChanged={emptyFunction} - bringToFront={emptyFunction} - ContainingCollectionView={undefined} - ContainingCollectionDoc={undefined} /> -
- ); - } - } - onDragOver = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); @@ -314,18 +503,21 @@ export default class MobileInterface extends React.Component { {this.renderView ? this.renderView() : this.renderDefaultContent()} */} - + {/* */} + + {this.displayWorkspaces()} + {/* */} {/* */} - - - {this.renderView ? this.renderView() : this.renderDefaultContent()} - - + {/* */} +
+ {this.renderDefaultContent()} +
+ {/* */} {/* */} - - + {/* + */} {/* */} @@ -335,9 +527,121 @@ 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 + +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(, document.getElementById('root')); +})(); + + +// 1 +// renderUploadContent() { +// if (this.mainContainer) { +// return ( +//
+//
+// +// {/* */} +// {/* */} +// +//
+// window.screen.width} +// PanelHeight={() => window.screen.height} +// renderDepth={0} +// focus={emptyFunction} +// backgroundColor={returnEmptyString} +// parentActive={returnTrue} +// whenActiveChanged={emptyFunction} +// bringToFront={emptyFunction} +// ContainingCollectionView={undefined} +// ContainingCollectionDoc={undefined} /> +//
+// ); +// } +// } + +// 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 ( + //
+ //
+ //
+ // + //
+ //
+ // + //
+ //
+ // + // + //
+ //
+ // + // + //
+ // ); + // } + // } \ 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 -- cgit v1.2.3-70-g09d2 From 662ab0537e6b7b3d15fd44b6e2695052025ed83b Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Sun, 31 May 2020 15:34:51 -0700 Subject: removed unecessary imports --- src/client/util/CurrentUserUtils.ts | 12 ++++++------ src/mobile/ImageUpload.tsx | 1 - src/mobile/MobileInterface.tsx | 26 +++++++++++++++++--------- 3 files changed, 23 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 377f908e9..1cce81ce6 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -614,12 +614,12 @@ export class CurrentUserUtils { /// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window static setupDockedButtons(doc: Doc) { - if (doc["dockedBtn-pen"] === undefined) { - doc["dockedBtn-pen"] = CurrentUserUtils.ficon({ - onClick: ScriptField.MakeScript("activatePen(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this, this.inkWidth, this.backgroundColor)"), - author: "systemTemplates", title: "ink mode", icon: "pen-nib", ischecked: ComputedField.MakeFunction(`sameDocs(this.activePen.inkPen, this)`), activePen: doc - }); - } + // if (doc["dockedBtn-pen"] === undefined) { + doc["dockedBtn-pen"] = CurrentUserUtils.ficon({ + onClick: ScriptField.MakeScript("activatePen(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this, this.inkWidth, this.backgroundColor)"), + author: "systemTemplates", title: "ink mode", icon: "pen-nib", ischecked: ComputedField.MakeFunction(`sameDocs(this.activePen.inkPen, this)`), activePen: doc + }); + // } if (doc["dockedBtn-undo"] === undefined) { doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), title: "undo button", icon: "undo-alt" }); } diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx index 2552e2112..fb0e444b5 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -12,7 +12,6 @@ import { observer } from 'mobx-react'; import { observable } from 'mobx'; import { Utils } from '../Utils'; import { Networking } from '../client/Network'; -import { MobileDocumentUploadContent } from '../server/Message'; export interface ImageUploadProps { Document: Doc; diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 9b28d066c..4c36fdb9b 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -7,7 +7,7 @@ import { observer } from 'mobx-react'; import * as ReactDOM from "react-dom"; import * as rp from 'request-promise'; import { CurrentUserUtils } from '../client/util/CurrentUserUtils'; -import { FieldValue, Cast, StrCast } from '../fields/Types'; +import { FieldValue, Cast, StrCast, BoolCast } from '../fields/Types'; import { Doc, DocListCast, Opt } from '../fields/Doc'; import { Docs } from '../client/documents/Documents'; import { CollectionView } from '../client/views/collections/CollectionView'; @@ -34,20 +34,21 @@ import RichTextMenu from '../client/views/nodes/formattedText/RichTextMenu'; import { MainView } from '../client/views/MainView'; import SettingsManager from '../client/util/SettingsManager'; import { Uploader } from "./ImageUpload"; -import { Upload } from '../server/SharedMediaTypes'; import { createTypePredicateNodeWithModifier } from 'typescript'; import { AudioBox } from '../client/views/nodes/AudioBox'; import { List } from '../fields/List'; +import { ScriptField, ComputedField } from '../fields/ScriptField'; library.add(faLongArrowAltLeft); library.add(faHome); @observer -export class MobileInterface extends React.Component { +export default 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; } + private get darkScheme() { return BoolCast(Cast(this.userDoc?.activeWorkspace, Doc, null)?.darkScheme); } // @observable private currentView: "main" | "ink" | "upload" = "main"; @observable private mainDoc: any = CurrentUserUtils.setupMobileMenu(this.userDoc); @observable private renderView?: () => JSX.Element; @@ -301,6 +302,9 @@ export class MobileInterface extends React.Component {
SettingsManager.Instance.open()}> Settings
+
CurrentUserUtils.setupDockedButtons(this._activeDoc)}> + Ink +
@@ -333,6 +337,9 @@ export class MobileInterface extends React.Component {
{buttons}
+
CurrentUserUtils.setupDockedButtons(this.userDoc)}> + Ink +
Home
@@ -493,6 +500,7 @@ export class MobileInterface extends React.Component { e.stopPropagation(); } + render() { // const content = this.currentView === "main" ? this.mainContent : // this.currentView === "ink" ? this.inkContent : @@ -505,19 +513,19 @@ export class MobileInterface extends React.Component { */} {/* */} - {this.displayWorkspaces()} + + {this.displayWorkspaces()} + {this.renderDefaultContent()} + {/* */} {/* */} {/* */} -
- {this.renderDefaultContent()} -
{/* */} {/* */} - {/* - */} + + {/* */} {/* */} -- cgit v1.2.3-70-g09d2 From cd2376cef00ae2b06b53480646a1e9ac8b246630 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Sun, 31 May 2020 23:08:34 -0700 Subject: fixed path bug --- src/mobile/MobileInterface.tsx | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 4c36fdb9b..5c89d7612 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -64,6 +64,7 @@ export default class MobileInterface extends React.Component { private _menu: Doc = this.mainDoc; private _open: boolean = false; private _library: Doc = Cast(this.userDoc.myWorkspaces, Doc) as Doc; + private _ink: boolean = false; constructor(props: Readonly<{}>) { super(props); @@ -90,14 +91,13 @@ export default class MobileInterface extends React.Component { } onSwitchInking = () => { - InkingControl.Instance.switchTool(InkTool.Pen); - MobileInterface.Instance.drawingInk = true; + if (!this._ink) { + InkingControl.Instance.switchTool(InkTool.Pen); + MobileInterface.Instance.drawingInk = true; - DocServer.Mobile.dispatchOverlayTrigger({ - enableOverlay: true, - width: window.innerWidth, - height: window.innerHeight - }); + } else { + MobileInterface.Instance.drawingInk = false; + } } onSwitchUpload = async () => { @@ -215,25 +215,34 @@ export default class MobileInterface extends React.Component { this.switchCurrentView((userDoc: Doc) => doc); this._child = doc; } - - // let sidebar = document.getElementById("sidebar") as HTMLElement; - // sidebar.classList.toggle('active'); } createPathname = () => { - let pathname = ""; + let pathname = "workspaces"; this._parents.map((doc: Doc, index: any) => { if (doc === this.mainDoc) { - pathname = pathname + doc.title; + pathname = pathname; + } else if (doc.title === "mobile audio" || doc.title === "Presentation") { + pathname = pathname + } else if (doc.type !== "collection") { + pathname = pathname } else { pathname = pathname + " > " + doc.title; } }); if (this._activeDoc === this.mainDoc) { - pathname = pathname + this._activeDoc.title; + pathname = pathname; } else { pathname = pathname + " > " + this._activeDoc.title; } + + if (this._activeDoc.title === "mobile audio") { + pathname = this._activeDoc.title; + } + + if (this._activeDoc.title === "Presentation") { + pathname = this._activeDoc.title; + } return pathname; } @@ -302,7 +311,7 @@ export default class MobileInterface extends React.Component {
SettingsManager.Instance.open()}> Settings
-
CurrentUserUtils.setupDockedButtons(this._activeDoc)}> +
this.onSwitchInking()}> Ink
@@ -351,7 +360,7 @@ export default class MobileInterface extends React.Component { 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); @@ -370,6 +379,7 @@ export default class MobileInterface extends React.Component { } openDefaultPresentation = () => { + this._parents.push(this._activeDoc); const presentation = Cast(Doc.UserDoc().activePresentation, Doc) as Doc; if (presentation) { @@ -515,8 +525,8 @@ export default class MobileInterface extends React.Component { {this.displayWorkspaces()} - {this.renderDefaultContent()} + {this.renderDefaultContent()} {/* */} {/* -- cgit v1.2.3-70-g09d2 From 8fd63cf68228105aca4622a55bfa9a69527ef341 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Mon, 1 Jun 2020 20:33:06 -0700 Subject: toggle for ink, scroll menu --- src/mobile/MobileInterface.tsx | 46 +++++++++++++++++++++++++++++++++--------- src/mobile/MobileMenu.scss | 12 +++++++++++ 2 files changed, 49 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 5c89d7612..dc0d70c0b 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -69,6 +69,7 @@ export default class MobileInterface extends React.Component { constructor(props: Readonly<{}>) { super(props); MobileInterface.Instance = this; + } @action @@ -78,6 +79,8 @@ export default class MobileInterface extends React.Component { if (this.userDoc && !this.mainContainer) { this.userDoc.activeMobile = this.mainDoc; } + InkingControl.Instance.switchTool(InkTool.None) + MobileInterface.Instance.drawingInk = false; } @action @@ -94,9 +97,33 @@ export default class MobileInterface extends React.Component { if (!this._ink) { InkingControl.Instance.switchTool(InkTool.Pen); MobileInterface.Instance.drawingInk = true; + this._ink = true; + DocServer.Mobile.dispatchOverlayTrigger({ + enableOverlay: true, + width: window.innerWidth, + height: window.innerHeight + }); } else { + InkingControl.Instance.switchTool(InkTool.None) MobileInterface.Instance.drawingInk = false; + this._ink = false; + + DocServer.Mobile.dispatchOverlayTrigger({ + enableOverlay: false, + width: window.innerWidth, + height: window.innerHeight + }); + } + + this.toggleSidebar(); + } + + getInkStatus = () => { + if (this._ink) { + return "ink off"; + } else { + return "ink on"; } } @@ -144,7 +171,7 @@ export default class MobileInterface extends React.Component { back = () => { let doc = Cast(this._parents.pop(), Doc) as Doc; - if (doc == Cast(this._menu, Doc) as Doc) { + if (doc === Cast(this._menu, Doc) as Doc) { this._child = null; this.userDoc.activeMobile = this.mainDoc; } else { @@ -223,9 +250,9 @@ export default class MobileInterface extends React.Component { if (doc === this.mainDoc) { pathname = pathname; } else if (doc.title === "mobile audio" || doc.title === "Presentation") { - pathname = pathname + pathname = pathname; } else if (doc.type !== "collection") { - pathname = pathname + pathname = pathname; } else { pathname = pathname + " > " + doc.title; } @@ -283,6 +310,7 @@ export default class MobileInterface extends React.Component {
+