aboutsummaryrefslogtreecommitdiff
path: root/src/mobile
diff options
context:
space:
mode:
Diffstat (limited to 'src/mobile')
-rw-r--r--src/mobile/ImageUpload.scss139
-rw-r--r--src/mobile/ImageUpload.tsx171
-rw-r--r--src/mobile/InkControls.tsx0
-rw-r--r--src/mobile/MobileInkOverlay.scss39
-rw-r--r--src/mobile/MobileInkOverlay.tsx183
-rw-r--r--src/mobile/MobileInterface.scss445
-rw-r--r--src/mobile/MobileInterface.tsx872
-rw-r--r--src/mobile/MobileMain.tsx26
-rw-r--r--src/mobile/MobileMenu.scss271
9 files changed, 0 insertions, 2146 deletions
diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss
deleted file mode 100644
index e4156ee8e..000000000
--- a/src/mobile/ImageUpload.scss
+++ /dev/null
@@ -1,139 +0,0 @@
-@import '../client/views/global/globalCssVariables.module.scss';
-
-.imgupload_cont {
- display: flex;
- justify-content: center;
- flex-direction: column;
- align-items: center;
- max-width: 400px;
- min-width: 400px;
-
- .upload_label {
- font-weight: 700;
- color: black;
- background-color: rgba(0, 0, 0, 0);
- border: solid 3px black;
- margin: 10px;
- font-size: 30;
- height: 70px;
- width: 80%;
- display: flex;
- font-family: sans-serif;
- text-transform: uppercase;
- justify-content: center;
- flex-direction: column;
- border-radius: 10px;
- }
-
- .file {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- direction: ltr;
- }
-
- .button_file {
- text-align: center;
- height: 50%;
- width: 50%;
- background-color: paleturquoise;
- color: grey;
- font-size: 3em;
- }
-
- .inputfile {
- width: 0.1px;
- height: 0.1px;
- opacity: 0;
- overflow: hidden;
- position: absolute;
- z-index: -1;
- }
-
- .inputfile + label {
- font-weight: 700;
- color: black;
- background-color: rgba(0, 0, 0, 0);
- border: solid 3px black;
- margin: 10px;
- font-size: 30;
- height: 70px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- margin-top: 30px;
- width: 80%;
- display: flex;
- font-family: sans-serif;
- text-transform: uppercase;
- justify-content: center;
- flex-direction: column;
- border-radius: 10px;
- }
-
- .inputfile.active + label {
- font-style: italic;
- color: black;
- background-color: lightgreen;
- border: solid 3px darkgreen;
- }
-
- .status {
- font-size: 2em;
- }
-}
-
-.image-upload {
- top: 100%;
- opacity: 0;
-}
-
-.image-upload.active {
- top: 0;
- position: absolute;
- z-index: 999;
- height: 100vh;
- width: 100vw;
- opacity: 1;
-}
-
-.uploadContainer {
- top: 40;
- position: absolute;
- z-index: 1000;
- height: 20vh;
- width: 80vw;
- opacity: 1;
-}
-
-.closeUpload {
- position: absolute;
- border-radius: 10px;
- top: 3;
- color: black;
- font-size: 30;
- right: 3;
- z-index: 1002;
- padding: 0px 3px;
- background: rgba(0, 0, 0, 0);
- transition: 0.5s ease all;
- border: 0px solid;
-}
-
-.loadingImage {
- display: inline-flex;
- width: max-content;
-}
-
-.loadingSlab {
- position: relative;
- width: 30px;
- height: 30px;
- margin: 10;
- border-radius: 20px;
- opacity: 0.2;
- background-color: black;
- transition:
- all 2s,
- opacity 1.5s;
-}
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
deleted file mode 100644
index 7a1e35636..000000000
--- a/src/mobile/ImageUpload.tsx
+++ /dev/null
@@ -1,171 +0,0 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import * as rp from 'request-promise';
-import { ClientUtils } from '../ClientUtils';
-import { DocServer } from '../client/DocServer';
-import { Networking } from '../client/Network';
-import { Docs } from '../client/documents/Documents';
-import { MainViewModal } from '../client/views/MainViewModal';
-import { Doc, Opt } from '../fields/Doc';
-import { List } from '../fields/List';
-import { listSpec } from '../fields/Schema';
-import { Cast } from '../fields/Types';
-import './ImageUpload.scss';
-
-const { DFLT_IMAGE_NATIVE_DIM } = require('../client/views/global/globalCssVariables.module.scss'); // prettier-ignore
-
-export interface ImageUploadProps {
- Document: Doc; // Target document for upload (upload location)
-}
-
-const inputRef = React.createRef<HTMLInputElement>();
-const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', ''));
-
-@observer
-export class Uploader extends React.Component<ImageUploadProps> {
- @observable nm: string = 'Choose files'; // Text of 'Choose Files' button
- @observable process: string = ''; // Current status of upload
- @observable private dialogueBoxOpacity = 1;
-
- onClick = async () => {
- try {
- // eslint-disable-next-line react/destructuring-assignment
- const col = this.props.Document;
- await Docs.Prototypes.initialize();
- const imgPrev = document.getElementById('img_preview');
- this.setOpacity(1, '1'); // Slab 1
- if (imgPrev && inputRef.current) {
- const { files } = inputRef.current;
- this.setOpacity(2, '1'); // Slab 2
- if (files && files.length !== 0) {
- this.process = 'Uploading Files';
- for (let index = 0; index < files.length; ++index) {
- const file = files[index];
- // eslint-disable-next-line no-await-in-loop
- const res = await Networking.UploadFilesToServer({ file });
- this.setOpacity(3, '1'); // Slab 3
- // For each item that the user has selected
- res.map(async ({ result }) => {
- const { name } = file;
- if (result instanceof Error) {
- return;
- }
- const path = result.accessPaths.agnostic.client;
- let doc = null;
- // Case 1: File is a video
- if (file.type === 'video/mp4') {
- doc = Docs.Create.VideoDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, title: name });
- // Case 2: File is a PDF document
- } else if (file.type === 'application/pdf') {
- doc = Docs.Create.PdfDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, title: name });
- // Case 3: File is another document type (most likely Image)
- } else {
- doc = Docs.Create.ImageDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, title: name });
- }
- this.setOpacity(4, '1'); // Slab 4
- const docidsRes = await rp.get(ClientUtils.prepend('/getUserDocumentIds'));
- if (!docidsRes) {
- throw new Error('No user id returned');
- }
- const field = await DocServer.GetRefField(JSON.parse(docidsRes).userDocumentId);
- let pending: Opt<Doc>;
- if (field instanceof Doc) {
- pending = col;
- }
- if (pending) {
- const data = Cast(pending.data, listSpec(Doc));
- if (data) data.push(doc);
- else pending.data = new List([doc]);
- this.setOpacity(5, '1'); // Slab 5
- this.process = 'File ' + (index + 1).toString() + ' Uploaded';
- this.setOpacity(6, '1'); // Slab 6
- }
- if (index + 1 === files.length) {
- this.process = 'Uploads Completed';
- this.setOpacity(7, '1'); // Slab 7
- }
- });
- }
- // Case in which the user pressed upload and no files were selected
- } else {
- this.process = 'No file selected';
- }
- // Three seconds after upload the menu will reset
- setTimeout(this.clearUpload, 3000);
- }
- } catch (error) {
- console.log(JSON.stringify(error));
- }
- };
-
- // Returns the upload interface for mobile
- private get uploadInterface() {
- return (
- <div className="imgupload_cont">
- <div className="closeUpload" onClick={() => this.closeUpload()}>
- <FontAwesomeIcon icon="window-close" size="lg" />
- </div>
- <FontAwesomeIcon icon="upload" size="lg" style={{ fontSize: '130' }} />
- <input type="file" accept="application/pdf, video/*,image/*" className={`inputFile ${this.nm !== 'Choose files' ? 'active' : ''}`} id="input_image_file" ref={inputRef} onChange={this.inputLabel} multiple />
- <label className="file" id="label" htmlFor="input_image_file">
- {this.nm}
- </label>
- <div className="upload_label" onClick={this.onClick}>
- Upload
- </div>
- <img id="img_preview" src="" alt="" />
- <div className="loadingImage">
- <div className="loadingSlab" id="slab1" />
- <div className="loadingSlab" id="slab2" />
- <div className="loadingSlab" id="slab3" />
- <div className="loadingSlab" id="slab4" />
- <div className="loadingSlab" id="slab5" />
- <div className="loadingSlab" id="slab6" />
- <div className="loadingSlab" id="slab7" />
- </div>
- <p className="status">{this.process}</p>
- </div>
- );
- }
-
- // Updates label after a files is selected (so user knows a file is uploaded)
- inputLabel = async () => {
- const files: FileList | null = await inputRef.current!.files;
- if (files && files.length === 1) {
- this.nm = files[0].name;
- } else if (files && files.length > 1) {
- this.nm = files.length.toString() + ' files selected';
- }
- }; // Loops through load icons, and resets buttons
- @action
- clearUpload = () => {
- for (let i = 1; i < 8; i++) {
- this.setOpacity(i, '0.2');
- }
- this.nm = 'Choose files';
-
- if (inputRef.current) {
- inputRef.current.value = '';
- }
- this.process = '';
- };
-
- // Clears the upload and closes the upload menu
- closeUpload = () => {
- this.clearUpload();
- };
-
- // Handles the setting of the loading bar
- setOpacity = (index: number, opacity: string) => {
- const slab = document.getElementById('slab' + index);
- if (slab) slab.style.opacity = opacity;
- };
-
- render() {
- return <MainViewModal contents={this.uploadInterface} isDisplayed interactive dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} closeOnExternalClick={this.closeUpload} />;
- }
-}
diff --git a/src/mobile/InkControls.tsx b/src/mobile/InkControls.tsx
deleted file mode 100644
index e69de29bb..000000000
--- a/src/mobile/InkControls.tsx
+++ /dev/null
diff --git a/src/mobile/MobileInkOverlay.scss b/src/mobile/MobileInkOverlay.scss
deleted file mode 100644
index b9c1fb146..000000000
--- a/src/mobile/MobileInkOverlay.scss
+++ /dev/null
@@ -1,39 +0,0 @@
-.mobileInkOverlay {
- border: 10px dashed red;
- background-color: rgba(0, 0, 0, .05);
-}
-
-.mobileInkOverlay-border {
- // background-color: rgba(0, 255, 0, .4);
- position: absolute;
- pointer-events: auto;
- cursor: pointer;
-
- &.top {
- width: calc(100% + 20px);
- height: 10px;
- top: -10px;
- left: -10px;
- }
-
- &.left {
- width: 10px;
- height: calc(100% + 20px);
- top: -10px;
- left: -10px;
- }
-
- &.right {
- width: 10px;
- height: calc(100% + 20px);
- top: -10px;
- right: -10px;
- }
-
- &.bottom {
- width: calc(100% + 20px);
- height: 10px;
- bottom: -10px;
- left: -10px;
- }
-} \ No newline at end of file
diff --git a/src/mobile/MobileInkOverlay.tsx b/src/mobile/MobileInkOverlay.tsx
deleted file mode 100644
index 6babd2f39..000000000
--- a/src/mobile/MobileInkOverlay.tsx
+++ /dev/null
@@ -1,183 +0,0 @@
-import { action, observable } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { DocServer } from '../client/DocServer';
-import { DragManager } from '../client/util/DragManager';
-import { Doc } from '../fields/Doc';
-import { Gestures } from '../pen-gestures/GestureTypes';
-import { GestureContent, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent } from '../server/Message';
-import './MobileInkOverlay.scss';
-
-@observer
-export default class MobileInkOverlay extends React.Component {
- public static Instance: MobileInkOverlay;
-
- @observable private _scale: number = 1;
- @observable private _width: number = 0;
- @observable private _height: number = 0;
- @observable private _x: number = -300;
- @observable private _y: number = -300;
- @observable private _text: string = '';
-
- @observable private _offsetX: number = 0;
- @observable private _offsetY: number = 0;
- @observable private _isDragging: boolean = false;
- private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
-
- constructor(props: Readonly<{}>) {
- super(props);
- MobileInkOverlay.Instance = this;
- }
-
- initialSize(mobileWidth: number, mobileHeight: number) {
- const maxWidth = window.innerWidth - 30;
- const maxHeight = window.innerHeight - 30; // -30 for padding
- if (mobileWidth > maxWidth || mobileHeight > maxHeight) {
- const scale = Math.min(maxWidth / mobileWidth, maxHeight / mobileHeight);
- return { width: mobileWidth * scale, height: mobileHeight * scale, scale: scale };
- }
- return { width: mobileWidth, height: mobileHeight, scale: 1 };
- }
-
- @action
- initMobileInkOverlay(content: MobileInkOverlayContent) {
- const { width, height, text } = content;
- const scaledSize = this.initialSize(width ? width : 0, height ? height : 0);
- this._width = scaledSize.width;
- this._height = scaledSize.height;
- this._scale = scaledSize.scale;
- this._x = 300; // TODO: center on screen
- this._y = 25; // TODO: center on screen
- this._text = text ? text : '';
- }
-
- @action
- updatePosition(content: UpdateMobileInkOverlayPositionContent) {
- const { dx, dy, dsize } = content;
- if (dx) this._x += dx;
- if (dy) this._y += dy;
- // TODO: scale dsize
- }
-
- drawStroke = (content: GestureContent) => {
- // TODO: figure out why strokes drawn in corner of mobile interface dont get inserted
-
- const { points, bounds } = content;
- console.log('received points', points, bounds);
-
- const B = {
- right: bounds.right * this._scale + this._x,
- left: bounds.left * this._scale + this._x, // TODO: scale
- bottom: bounds.bottom * this._scale + this._y,
- top: bounds.top * this._scale + this._y, // TODO: scale
- width: bounds.width * this._scale,
- height: bounds.height * this._scale,
- };
-
- const target = document.elementFromPoint(this._x + 10, this._y + 10);
- target?.dispatchEvent(
- new CustomEvent<GestureEvent>('dashOnGesture', {
- bubbles: true,
- detail: {
- points: points,
- gesture: Gestures.Stroke,
- bounds: B,
- },
- })
- );
- };
-
- uploadDocument = async (content: MobileDocumentUploadContent) => {
- const { docId } = content;
- const doc = await DocServer.GetRefField(docId);
-
- if (doc && doc instanceof Doc) {
- const target = document.elementFromPoint(this._x + 10, this._y + 10);
- const dragData = new DragManager.DocumentDragData([doc]);
- const complete = new DragManager.DragCompleteEvent(false, dragData);
-
- if (target) {
- console.log('dispatching upload doc!!!!', target, doc);
- target.dispatchEvent(
- new CustomEvent<DragManager.DropEvent>('dashOnDrop', {
- bubbles: true,
- detail: {
- x: this._x,
- y: this._y,
- complete: complete,
- altKey: false,
- metaKey: false,
- ctrlKey: false,
- shiftKey: false,
- embedKey: false,
- },
- })
- );
- } else {
- alert('TARGET IS UNDEFINED');
- }
- }
- };
-
- @action
- dragStart = (e: React.PointerEvent) => {
- document.removeEventListener('pointermove', this.dragging);
- document.removeEventListener('pointerup', this.dragEnd);
- document.addEventListener('pointermove', this.dragging);
- document.addEventListener('pointerup', this.dragEnd);
-
- this._isDragging = true;
- this._offsetX = e.pageX - this._mainCont.current!.getBoundingClientRect().left;
- this._offsetY = e.pageY - this._mainCont.current!.getBoundingClientRect().top;
-
- e.preventDefault();
- e.stopPropagation();
- };
-
- @action
- dragging = (e: PointerEvent) => {
- const x = e.pageX - this._offsetX;
- const y = e.pageY - this._offsetY;
-
- // TODO: don't allow drag over library?
- this._x = Math.min(Math.max(x, 0), window.innerWidth - this._width);
- this._y = Math.min(Math.max(y, 0), window.innerHeight - this._height);
-
- e.preventDefault();
- e.stopPropagation();
- };
-
- @action
- dragEnd = (e: PointerEvent) => {
- document.removeEventListener('pointermove', this.dragging);
- document.removeEventListener('pointerup', this.dragEnd);
-
- this._isDragging = false;
-
- e.preventDefault();
- e.stopPropagation();
- };
-
- render() {
- return (
- <div
- className="mobileInkOverlay"
- style={{
- width: this._width,
- height: this._height,
- position: 'absolute',
- transform: `translate(${this._x}px, ${this._y}px)`,
- zIndex: 30000,
- pointerEvents: 'none',
- borderStyle: this._isDragging ? 'solid' : 'dashed',
- }}
- ref={this._mainCont}>
- <p>{this._text}</p>
- <div className="mobileInkOverlay-border top" onPointerDown={this.dragStart}></div>
- <div className="mobileInkOverlay-border bottom" onPointerDown={this.dragStart}></div>
- <div className="mobileInkOverlay-border left" onPointerDown={this.dragStart}></div>
- <div className="mobileInkOverlay-border right" onPointerDown={this.dragStart}></div>
- </div>
- );
- }
-}
diff --git a/src/mobile/MobileInterface.scss b/src/mobile/MobileInterface.scss
deleted file mode 100644
index 4b32c3da0..000000000
--- a/src/mobile/MobileInterface.scss
+++ /dev/null
@@ -1,445 +0,0 @@
-$navbar-height: 120px;
-$pathbar-height: 50px;
-
-@media only screen and (max-device-width: 480px) {
- * {
- margin: 0px;
- padding: 0px;
- box-sizing: border-box;
- font-family: sans-serif;
- }
-}
-
-body {
- overflow: hidden;
-}
-
-.mobileInterface-container {
- height: 100%;
- position: relative;
- touch-action: none;
- width: 100%;
-
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-}
-
-// Topbar of Dash Mobile
-.navbar {
- position: fixed;
- top: 0px;
- left: 0px;
- width: 100vw;
- height: $navbar-height;
- background-color: whitesmoke;
- z-index: 150;
-
- .cover {
- position: absolute;
- right: 0px;
- top: 0px;
- height: 120px;
- width: 120px;
- background-color: whitesmoke;
- z-index: 200;
- }
-
- .toggle-btn {
- position: absolute;
- right: 20px;
- top: 30px;
- height: 70px;
- width: 70px;
- transition: all 400ms ease-in-out 200ms;
- z-index: 180;
- }
-
- .background {
- position: absolute;
- right: 0px;
- top: 0px;
- height: 120px;
- width: 120px;
- //border: 1px solid black;
- }
-
- .background.active {
- background-color: lightgrey;
- }
-
- .toggle-btn-home {
- right: -200px;
- }
-
- .header {
- position: absolute;
- top: 50%;
- top: calc(9px + 50%);
- right: 50%;
- transform: translate(50%, -50%);
- font-size: 40;
- font-weight: 700;
- text-align: center;
- user-select: none;
- text-transform: uppercase;
- font-family: Arial, Helvetica, sans-serif;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- direction: ltr;
- width: 600px;
- }
-
- .toggle-btn span {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 70%;
- height: 4px;
- background: black;
- transition: all 200ms ease;
- z-index: 180;
- }
-
- .toggle-btn span:nth-child(1) {
- transition: top 200ms ease-in-out;
- top: 30%;
- }
-
- .toggle-btn span:nth-child(3) {
- transition: top 200ms ease-in-out;
- top: 70%;
- }
-
- .toggle-btn.active {
- transition: transform 200ms ease-in-out 200ms;
- transform: rotate(135deg);
- }
-
- .toggle-btn.active span:nth-child(1) {
- top: 50%;
- }
-
- .toggle-btn.active span:nth-child(2) {
- transform: translate(-50%, -50%) rotate(90deg);
- }
-
- .toggle-btn.active span:nth-child(3) {
- top: 50%;
- }
-}
-
-.sidebar {
- position: fixed;
- top: 120px;
- opacity: 0;
- right: -100%;
- width: 80%;
- height: calc(80% - (120px));
- z-index: 101;
- background-color: whitesmoke;
- transition: all 400ms ease 50ms;
- padding: 20px;
- box-shadow: 0 0 5px 5px grey;
-
- .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;
- display: inline-flex;
- font-size: 35px;
- text-transform: uppercase;
- color: black;
- }
-
- .ink:focus {
- outline: 1px solid blue;
- }
-
- .sidebarButtons {
- top: 80px;
- position: relative;
- }
-}
-
-
-
-
-
-
-.blanket {
- position: fixed;
- top: 120px;
- opacity: 0.5;
- right: -100%;
- width: 100%;
- height: calc(100% - (120px));
- z-index: 101;
- background-color: grey;
- padding: 20px;
-}
-
-.blanket.active {
- position: absolute;
- right: 0%;
- z-index: 100;
-}
-
-.home {
- position: absolute;
- top: 30px;
- left: 30px;
- font-size: 60;
- user-select: none;
- text-transform: uppercase;
- font-family: Arial, Helvetica, sans-serif;
- z-index: 200;
-}
-
-.item-type {
- display: inline;
- text-transform: lowercase;
- margin-left: 20px;
- font-size: 35px;
- font-style: italic;
- color: rgb(28, 28, 28);
-}
-
-.item-title {
- max-width: 70%;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.right {
- margin-left: 20px;
- z-index: 200;
-}
-
-.open {
- right: 20px;
- font-size: 35;
- position: absolute;
-}
-
-.left {
- width: 100%;
- height: 100%;
-}
-
-
-
-.sidebar.active {
- position: absolute;
- right: 0%;
- opacity: 1;
- z-index: 101;
-}
-
-.back {
- position: absolute;
- left: 42px;
- top: 0;
- background: #1a1a1a;
- width: 50px;
- height: 100%;
- display: flex;
- justify-content: center;
- text-align: center;
- flex-direction: column;
- align-items: center;
- border-radius: 10px;
- font-size: 25px;
- user-select: none;
- z-index: 100;
-}
-
-.pathbar {
- position: fixed;
- top: 118px;
- left: 0px;
- background: #1a1a1a;
- z-index: 120;
- border-radius: 0px;
- width: 100%;
- height: 80px;
- overflow: hidden;
-
- .pathname {
- position: relative;
- font-size: 25;
- top: 50%;
- width: 86%;
- left: 12%;
- 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;
- }
-
- .scrollmenu {
- overflow: auto;
- width: 100%;
- height: 100%;
- white-space: nowrap;
- display: inline-flex;
- }
-
- .hidePath {
- position: absolute;
- height: 100%;
- width: 200px;
- left: 0px;
- top: 0px;
- background-image: linear-gradient(to right, #1a1a1a, rgba(0, 0, 0, 0));
- text-align: center;
- user-select: none;
- z-index: 99;
- pointer-events: none;
- }
-
- .pathbarItem {
- position: relative;
- display: flex;
- align-items: center;
- color: whitesmoke;
- text-align: center;
- justify-content: center;
- user-select: none;
- transform: translate(100px, 0px);
- font-size: 30px;
- padding: 10px;
- text-transform: uppercase;
-
- .pathbarText {
- font-family: sans-serif;
- text-align: center;
- height: 50px;
- padding: 10px;
- font-size: 30px;
- border-radius: 10px;
- text-transform: uppercase;
- margin-left: 20px;
- position: relative;
- }
-
- .pathIcon {
- transform: translate(0px, 0px);
- position: relative;
- }
- }
-}
-
-
-/**
-* docButton appears at the bottom of mobile document
-* Buttons include: pin to presentation, download, upload, reload
-*/
-.docButton {
- position: relative;
- width: 100px;
- display: flex;
- height: 100px;
- font-size: 70px;
- text-align: center;
- border: 3px solid black;
- margin: 20px;
- z-index: 100;
- border-radius: 100%;
- justify-content: center;
- flex-direction: column;
- align-items: center;
-}
-
-.docButtonContainer {
- top: 80%;
- position: absolute;
- display: flex;
- transform: translate(-50%, 0);
- left: 50%;
- z-index: 100;
-}
-
-.toolbar {
- left: 50%;
- transform: translate(-50%);
- position: absolute;
- height: max-content;
- top: 0px;
- border-radius: 20px;
- background-color: lightgrey;
- opacity: 0;
- transition: all 400ms ease 50ms;
-}
-
-.toolbar.active {
- display: inline-block;
- width: 300px;
- padding: 5px;
- opacity: 1;
- height: max-content;
- top: -450px;
-}
-
-.colorSelector {
- position: absolute;
- top: 550px;
- left: 280px;
- transform: translate(-50%, 0);
- z-index: 100;
- display: inline-flex;
- width: max-content;
- height: max-content;
- pointer-events: all;
- font-size: 80px;
- user-select: none;
-}
-
-// Menu buttons for toggling between list and icon view
-.homeSwitch {
- position: fixed;
- top: 212;
- right: 36px;
- display: inline-flex;
- width: max-content;
- z-index: 99;
- height: 70px;
-
- .list {
- width: 70px;
- height: 70px;
- margin: 5;
- padding: 10;
- align-items: center;
- text-align: center;
- font-size: 50;
- border-style: solid;
- border-width: 3;
- border-color: black;
- background: whitesmoke;
- align-self: center;
- border-radius: 10px;
- }
-
- .list.active {
- color: darkred;
- border-color: darkred;
- }
-} \ No newline at end of file
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
deleted file mode 100644
index d8ba89fdb..000000000
--- a/src/mobile/MobileInterface.tsx
+++ /dev/null
@@ -1,872 +0,0 @@
-import { library } from '@fortawesome/fontawesome-svg-core';
-import {
- faAddressCard,
- faAlignLeft,
- faAlignRight,
- faAngleDoubleLeft,
- faAngleRight,
- faArrowDown,
- faArrowLeft,
- faArrowRight,
- faArrowUp,
- faArrowsAltH,
- faAsterisk,
- faBars,
- faBell,
- faBolt,
- faBook,
- faBrain,
- faBullseye,
- faCalculator,
- faCamera,
- faCaretDown,
- faCaretLeft,
- faCaretRight,
- faCaretSquareDown,
- faCaretSquareRight,
- faCaretUp,
- faCat,
- faCheck,
- faChevronLeft,
- faChevronRight,
- faClipboard,
- faClone,
- faCloudUploadAlt,
- faCommentAlt,
- faCompressArrowsAlt,
- faCut,
- faEdit,
- faEllipsisV,
- faEraser,
- faExclamation,
- faExpand,
- faExternalLinkAlt,
- faExternalLinkSquareAlt,
- faEye,
- faFileAlt,
- faFileAudio,
- faFileDownload,
- faFilePdf,
- faFilm,
- faFilter,
- faFolderOpen,
- faFont,
- faGlobeAsia,
- faHandPointLeft,
- faHighlighter,
- faHome,
- faImage,
- faLocationArrow,
- faLongArrowAltLeft,
- faLongArrowAltRight,
- faMicrophone,
- faCircleHalfStroke,
- faMinus,
- faMobile,
- faMousePointer,
- faMusic,
- faObjectGroup,
- faPaintBrush,
- faPalette,
- faPause,
- faPen,
- faPenNib,
- faPhone,
- faPlay,
- faPlus,
- faPortrait,
- faQuestionCircle,
- faQuoteLeft,
- faRedoAlt,
- faReply,
- faSearch,
- faStamp,
- faStickyNote,
- faStop,
- faTasks,
- faTerminal,
- faTh,
- faThLarge,
- faThumbtack,
- faTimes,
- faToggleOn,
- faTrash,
- faTrashAlt,
- faTree,
- faTv,
- faUndoAlt,
- faVideo,
- faWindowClose,
- faWindowMaximize,
- faFile as fileSolid,
-} from '@fortawesome/free-solid-svg-icons';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable, runInAction } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../ClientUtils';
-import { CollectionViewType, DocumentType } from '../client/documents/DocumentTypes';
-import { Docs, DocumentOptions } from '../client/documents/Documents';
-import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
-import { ScriptingGlobals } from '../client/util/ScriptingGlobals';
-import { SettingsManager } from '../client/util/SettingsManager';
-import { Transform } from '../client/util/Transform';
-import { UndoManager } from '../client/util/UndoManager';
-import { DashboardView } from '../client/views/DashboardView';
-import { GestureOverlay } from '../client/views/GestureOverlay';
-import { AudioBox } from '../client/views/nodes/AudioBox';
-import { DocumentView } from '../client/views/nodes/DocumentView';
-import { RadialMenu } from '../client/views/nodes/RadialMenu';
-import { RichTextMenu } from '../client/views/nodes/formattedText/RichTextMenu';
-import { Doc, DocListCast } from '../fields/Doc';
-import { InkTool } from '../fields/InkField';
-import { List } from '../fields/List';
-import { ScriptField } from '../fields/ScriptField';
-import { Cast, FieldValue, StrCast } from '../fields/Types';
-import './AudioUpload.scss';
-import { Uploader } from './ImageUpload';
-import './ImageUpload.scss';
-import './MobileInterface.scss';
-import { emptyFunction } from '../Utils';
-
-library.add(
- ...[
- faTasks,
- faReply,
- faQuoteLeft,
- faHandPointLeft,
- faFolderOpen,
- faAngleDoubleLeft,
- faExternalLinkSquareAlt,
- faMobile,
- faThLarge,
- faWindowClose,
- faEdit,
- faTrashAlt,
- faPalette,
- faAngleRight,
- faBell,
- faTrash,
- faCamera,
- faExpand,
- faCaretDown,
- faCaretLeft,
- faCaretRight,
- faCaretSquareDown,
- faCaretSquareRight,
- faArrowsAltH,
- faPlus,
- faMinus,
- faTerminal,
- faToggleOn,
- fileSolid,
- faExternalLinkAlt,
- faLocationArrow,
- faSearch,
- faFileDownload,
- faStop,
- faCalculator,
- faWindowMaximize,
- faAddressCard,
- faQuestionCircle,
- faArrowLeft,
- faArrowRight,
- faArrowDown,
- faArrowUp,
- faBolt,
- faBullseye,
- faCaretUp,
- faCat,
- faCheck,
- faChevronRight,
- faClipboard,
- faClone,
- faCloudUploadAlt,
- faCommentAlt,
- faCompressArrowsAlt,
- faCut,
- faEllipsisV,
- faEraser,
- faExclamation,
- faFileAlt,
- faFileAudio,
- faFilePdf,
- faFilm,
- faFilter,
- faFont,
- faGlobeAsia,
- faHighlighter,
- faLongArrowAltRight,
- faMicrophone,
- faCircleHalfStroke,
- faMousePointer,
- faMusic,
- faObjectGroup,
- faPause,
- faPen,
- faPenNib,
- faPhone,
- faPlay,
- faPortrait,
- faRedoAlt,
- faStamp,
- faStickyNote,
- faThumbtack,
- faTree,
- faTv,
- faUndoAlt,
- faBook,
- faVideo,
- faAsterisk,
- faBrain,
- faImage,
- faPaintBrush,
- faTimes,
- faEye,
- faHome,
- faLongArrowAltLeft,
- faBars,
- faTh,
- faChevronLeft,
- faAlignLeft,
- faAlignRight,
- ].map(m => m as any)
-);
-
-@observer
-export class MobileInterface extends React.Component {
- static Instance: MobileInterface;
- private _library: Doc;
- private _mainDoc: any = CurrentUserUtils.setupActiveMobileMenu(Doc.UserDoc());
- @observable private _sidebarActive: boolean = false; //to toggle sidebar display
- @observable private _imageUploadActive: boolean = false; //to toggle image upload
- @observable private _audioUploadActive: boolean = false;
- @observable private _menuListView: boolean = false; //to switch between menu view (list / icon)
- @observable private _ink: boolean = false; //toggle whether ink is being dispalyed
- @observable private _homeMenu: boolean = true; // to determine whether currently at home menu
- @observable private dashboards: Doc | null = null; // currently selected document
- @observable private _activeDoc: Doc = this._mainDoc; // doc updated as the active mobile page is updated (initially home menu)
- @observable private _homeDoc: Doc = this._mainDoc; // home menu as a document
- @observable private _parents: Array<Doc> = []; // array of parent docs (for pathbar)
-
- @computed private get mainContainer() {
- return Doc.UserDoc() ? FieldValue(Cast(Doc.UserDoc().activeMobile, Doc)) : Doc.GuestMobile;
- }
-
- constructor(props: Readonly<{}>) {
- super(props);
- this._library = CurrentUserUtils.setupDashboards(Doc.UserDoc(), 'myDashboards'); // to access documents in Dash Web
- MobileInterface.Instance = this;
- }
-
- @action
- componentDidMount() {
- // if the home menu is in list view -> adjust the menu toggle appropriately
- this._menuListView = this._homeDoc._type_collection === 'stacking' ? true : false;
- Doc.ActiveTool = InkTool.None; // ink should intially be set to none
- Doc.UserDoc().activeMobile = this._homeDoc; // active mobile set to home
- AudioBox.Enabled = true;
-
- // remove double click to avoid mobile zoom in
- document.removeEventListener('dblclick', this.onReactDoubleClick);
- document.addEventListener('dblclick', this.onReactDoubleClick);
- }
-
- @action
- componentWillUnmount = () => {
- document.removeEventListener('dblclick', this.onReactDoubleClick);
- };
-
- // Prevent zooming in when double tapping the screen
- onReactDoubleClick = (e: MouseEvent) => {
- e.stopPropagation();
- };
-
- // Switch the mobile view to the given doc
- @action
- switchCurrentView = (doc: Doc, renderView?: () => JSX.Element, onSwitch?: () => void) => {
- if (!Doc.UserDoc()) return;
- if (this._activeDoc === this._homeDoc) {
- this._parents.push(this._activeDoc);
- this._homeMenu = false;
- }
- this._activeDoc = doc;
- Doc.UserDoc().activeMobile = doc;
- onSwitch?.();
-
- // Ensures that switching to home is not registed
- UndoManager.undoStack.length = 0;
- UndoManager.redoStack.length = 0;
- };
-
- // For toggling the hamburger menu
- @action
- toggleSidebar = () => {
- this._sidebarActive = !this._sidebarActive;
-
- if (this._ink) {
- this.onSwitchInking();
- }
- };
- /**
- * Method called when 'Library' button is pressed on the home screen
- */
- switchToLibrary = async () => {
- this.switchCurrentView(this._library);
- runInAction(() => (this._homeMenu = false));
- this.toggleSidebar();
- };
-
- /**
- * Back method for navigating through items
- */
- @action
- back = () => {
- const header = document.getElementById('header') as HTMLElement;
- const doc = Cast(this._parents.pop(), Doc) as Doc; // Parent document
- // Case 1: Parent document is 'dashboards'
- if (doc === (Cast(this._library, Doc) as Doc)) {
- this.dashboards = null;
- this.switchCurrentView(this._library);
- // Case 2: Parent document is the 'home' menu (root node)
- } else if (doc === (Cast(this._homeDoc, Doc) as Doc)) {
- this._homeMenu = true;
- this._parents = [];
- this.dashboards = null;
- this.switchCurrentView(this._homeDoc);
- // Case 3: Parent document is any document
- } else if (doc) {
- this.dashboards = doc;
- this.switchCurrentView(doc);
- this._homeMenu = false;
- header.textContent = String(doc.title);
- }
- this._ink = false; // turns ink off
- };
-
- /**
- * Return 'Home", which implies returning to 'Home' menu buttons
- */
- @action
- returnHome = () => {
- if (!this._homeMenu || this._sidebarActive) {
- this._homeMenu = true;
- this._parents = [];
- this.dashboards = null;
- this.switchCurrentView(this._homeDoc);
- }
- if (this._sidebarActive) {
- this.toggleSidebar();
- }
- };
-
- /**
- * Return to primary Dashboard in library (Dashboards Doc)
- */
- @action
- returnMain = () => {
- this._parents = [this._homeDoc];
- this.switchCurrentView(this._library);
- this._homeMenu = false;
- this.dashboards = null;
- };
-
- /**
- * Note: window.innerWidth and window.screen.width compute different values.
- * window.screen.width is the display size, however window.innerWidth is the
- * display resolution which computes differently.
- */
- returnWidth = () => window.innerWidth; //The windows width
- returnHeight = () => window.innerHeight - 300; //Calculating the windows height (-300 to account for topbar)
- whitebackground = () => 'white';
- /**
- * DocumentView for graphic display of all documents
- */
- @computed get displayDashboards() {
- return !this.mainContainer ? null : (
- <div style={{ position: 'relative', top: '198px', height: `calc(100% - 350px)`, width: '100%', left: '0%' }}>
- <DocumentView
- Document={this.mainContainer}
- addDocument={returnFalse}
- addDocTab={returnFalse}
- pinToPres={emptyFunction}
- removeDocument={undefined}
- ScreenToLocalTransform={Transform.Identity}
- PanelWidth={this.returnWidth}
- PanelHeight={this.returnHeight}
- renderDepth={0}
- isDocumentActive={returnTrue}
- isContentActive={emptyFunction}
- focus={emptyFunction}
- styleProvider={this.whitebackground}
- containerViewPath={returnEmptyDoclist}
- whenChildContentsActiveChanged={emptyFunction}
- childFilters={returnEmptyFilter}
- childFiltersByRanges={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- />
- </div>
- );
- }
-
- /**
- * Handles the click functionality in the library panel.
- * Navigates to the given doc and updates the sidebar.
- * @param doc: doc for which the method is called
- */
- handleClick = async (doc: Doc) => {
- runInAction(() => {
- if (doc.type !== 'collection' && this._sidebarActive) {
- this._parents.push(this._activeDoc);
- this.switchCurrentView(doc);
- this._homeMenu = false;
- this.toggleSidebar();
- } else {
- this._parents.push(this._activeDoc);
- this.switchCurrentView(doc);
- this._homeMenu = false;
- this.dashboards = doc;
- }
- });
- };
-
- /**
- * Called when an item in the library is clicked and should
- * be opened (open icon on RHS of all menu items)
- * @param doc doc to be opened
- */
- @action
- openFromSidebar = (doc: Doc) => {
- this._parents.push(this._activeDoc);
- this.switchCurrentView(doc);
- this._homeMenu = false;
- this.dashboards = doc;
- this.toggleSidebar();
- };
-
- // Renders the graphical pathbar
- renderPathbar = () => {
- const docPath = [...this._parents, this._activeDoc];
- const items = docPath.map((doc: Doc, index: any) => (
- <div className="pathbarItem" key={index}>
- {index === 0 ? null : <FontAwesomeIcon key="icon" className="pathIcon" icon="angle-right" size="lg" />}
- <div className="pathbarText" style={{ backgroundColor: this._homeMenu || doc === this._activeDoc ? 'rgb(119,17,37)' : undefined }} onClick={() => this.handlePathClick(doc, index)}>
- {StrCast(doc.title)}
- </div>
- </div>
- ));
- return (
- <div className="pathbar">
- <div className="scrollmenu">{items}</div>
- {!this._parents.length ? null : (
- <div className="back">
- <FontAwesomeIcon onClick={this.back} icon={'chevron-left'} color="white" size={'2x'} />
- </div>
- )}
- <div className="hidePath" />
- </div>
- );
- };
-
- // Handles when user clicks on a document in the pathbar
- @action
- handlePathClick = async (doc: Doc, index: number) => {
- const library = await this._library;
- if (doc === library) {
- this.dashboards = null;
- this.switchCurrentView(doc);
- this._parents.length = index;
- } else if (doc === this._homeDoc) {
- this.returnHome();
- } else {
- this.dashboards = doc;
- this.switchCurrentView(doc);
- this._parents.length = index;
- }
- };
-
- // Renders the contents of the menu and sidebar
- @computed get renderDefaultContent() {
- if (this._homeMenu) {
- return (
- <div>
- <div className="navbar">
- <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
- <div className="header" id="header">
- {StrCast(this._homeDoc.title)}
- </div>
- <div className="cover" id="cover" onClick={e => e.stopPropagation()}></div>
- <div className="toggle-btn" id="menuButton" onClick={this.toggleSidebar}>
- <span></span>
- <span></span>
- <span></span>
- </div>
- </div>
- {this.renderPathbar()}
- </div>
- );
- }
- // stores dashboards documents as 'dashboards' variable
- let dashboards = Doc.MyDashboards;
- if (this.dashboards) {
- dashboards = this.dashboards;
- }
- // returns a list of navbar buttons as 'buttons'
- const buttons = DocListCast(dashboards.data).map((doc: Doc, index: any) => {
- if (doc.type !== 'ink') {
- return (
- <div className="item" key={index}>
- <div className="item-title" onClick={() => this.handleClick(doc)}>
- {' '}
- {doc.title as string}{' '}
- </div>
- <div className="item-type" onClick={() => this.handleClick(doc)}>
- {doc.type as string}
- </div>
- <FontAwesomeIcon onClick={() => this.handleClick(doc)} className="right" icon="angle-right" size="lg" style={{ display: `${doc.type === 'collection' ? 'block' : 'none'}` }} />
- <FontAwesomeIcon className="open" onClick={() => this.openFromSidebar(doc)} icon="external-link-alt" size="lg" />
- </div>
- );
- }
- });
-
- return (
- <div>
- <div className="navbar">
- <FontAwesomeIcon className="home" icon="home" onClick={this.returnHome} />
- <div className="header" id="header">
- {this._sidebarActive ? 'library' : (this._activeDoc.title as string)}
- </div>
- <div className={`toggle-btn ${this._sidebarActive ? 'active' : ''}`} onClick={this.toggleSidebar}>
- <span></span>
- <span></span>
- <span></span>
- </div>
- <div className={`background ${this._sidebarActive ? 'active' : ''}`} onClick={this.toggleSidebar}></div>
- </div>
- {this.renderPathbar()}
- <div className={`sidebar ${this._sidebarActive ? 'active' : ''}`}>
- <div className="sidebarButtons">
- {this.dashboards ? (
- <>
- {buttons}
- <div className="item" key="home" onClick={this.returnMain} style={{ opacity: 0.7 }}>
- <FontAwesomeIcon className="right" icon="angle-double-left" size="lg" />
- <div className="item-type">Return to dashboards</div>
- </div>
- </>
- ) : (
- <>
- {buttons}
- <div className="item" style={{ opacity: 0.7 }} onClick={() => this.createNewDashboard()}>
- <FontAwesomeIcon className="right" icon="plus" size="lg" />
- <div className="item-type">Create New Dashboard</div>
- </div>
- </>
- )}
- </div>
- </div>
- <div className={`blanket ${this._sidebarActive ? 'active' : ''}`} onClick={this.toggleSidebar}></div>
- </div>
- );
- }
-
- /**
- * Handles the 'Create New Dashboard' button in the menu (taken from MainView.tsx)
- */
- @action
- createNewDashboard = (id?: string) => {
- const scens = Doc.MyDashboards;
- const dashboardCount = DocListCast(scens.data).length + 1;
- const freeformOptions: DocumentOptions = {
- x: 0,
- y: 400,
- title: 'Collection ' + dashboardCount,
- };
-
- const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
- const dashboardDoc = DashboardView.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, 'row');
-
- const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
- const cloneDashboard = ScriptField.MakeScript(`cloneDashboard()`);
- dashboardDoc.contextMenuScripts = new List<ScriptField>([toggleComic!, cloneDashboard!]);
- dashboardDoc.contextMenuLabels = new List<string>(['Toggle Comic Mode', 'New Dashboard Layout']);
-
- Doc.AddDocToList(scens, 'data', dashboardDoc);
- };
-
- // Button for switching between pen and ink mode
- @action
- onSwitchInking = () => {
- const button = document.getElementById('inkButton') as HTMLElement;
- button.style.backgroundColor = this._ink ? 'white' : 'black';
- button.style.color = this._ink ? 'black' : 'white';
-
- if (!this._ink) {
- Doc.ActiveTool = InkTool.Pen;
- this._ink = true;
- } else {
- Doc.ActiveTool = InkTool.None;
- this._ink = false;
- }
- };
-
- // The static ink menu that appears at the top
- @computed get inkMenu() {
- return this._activeDoc._type_collection !== CollectionViewType.Docking || !this._ink ? null : <div className="colorSelector">{/* <CollectionFreeFormViewChrome /> */}</div>;
- }
-
- // DocButton that uses UndoManager and handles the opacity change if CanUndo is true
- @computed get undo() {
- if (this.mainContainer && this._activeDoc.type === 'collection' && this._activeDoc !== this._homeDoc && this._activeDoc !== Doc.SharingDoc() && this._activeDoc.title !== 'WORKSPACES') {
- return (
- <div
- className="docButton"
- style={{ backgroundColor: 'black', color: 'white', fontSize: '60', opacity: UndoManager.CanUndo() ? '1' : '0.4' }}
- id="undoButton"
- title="undo"
- onClick={(e: React.MouseEvent) => {
- UndoManager.Undo();
- e.stopPropagation();
- }}>
- <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="undo-alt" />
- </div>
- );
- } else return null;
- }
-
- // DocButton that uses UndoManager and handles the opacity change if CanRedo is true
- @computed get redo() {
- if (this.mainContainer && this._activeDoc.type === 'collection' && this._activeDoc !== this._homeDoc && this._activeDoc !== Doc.SharingDoc() && this._activeDoc.title !== 'WORKSPACES') {
- return (
- <div
- className="docButton"
- style={{ backgroundColor: 'black', color: 'white', fontSize: '60', opacity: UndoManager.CanRedo() ? '1' : '0.4' }}
- id="undoButton"
- title="redo"
- onClick={(e: React.MouseEvent) => {
- UndoManager.Redo();
- e.stopPropagation();
- }}>
- <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="redo-alt" />
- </div>
- );
- } else return null;
- }
-
- // DocButton for switching into ink mode
- @computed get drawInk() {
- return !this.mainContainer || this._activeDoc._type_collection !== CollectionViewType.Docking ? null : (
- <div className="docButton" id="inkButton" onClick={this.onSwitchInking}>
- <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib" />
- </div>
- );
- }
-
- // DocButton: Button that appears on the bottom of the screen to initiate image upload
- @computed get uploadImageButton() {
- if (this._activeDoc.type === DocumentType.COL && this._activeDoc !== this._homeDoc && this._activeDoc._type_collection !== CollectionViewType.Docking && this._activeDoc.title !== 'WORKSPACES') {
- return (
- <div className="docButton" id="imageButton" onClick={this.toggleUpload}>
- <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload" />
- </div>
- );
- } else return null;
- }
-
- // DocButton to download images on the mobile
- @computed get downloadDocument() {
- if (this._activeDoc.type === 'image' || this._activeDoc.type === 'pdf' || this._activeDoc.type === 'video') {
- return (
- <div className="docButton" title={'Download Image'} style={{ backgroundColor: 'white', color: 'black' }} onClick={e => window.open(this._activeDoc['data-path']?.toString())}>
- {' '}
- {/* daa-path holds the url */}
- <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="download" />
- </div>
- );
- } else return null;
- }
-
- // DocButton for pinning images to presentation
- @computed get pinToPresentation() {
- // Only making button available if it is an image
- if (!(this._activeDoc.type === 'collection' || this._activeDoc.type === 'presentation')) {
- return (
- <div className="docButton" title={'Pin to presentation'} style={{ backgroundColor: 'white', color: 'black' }} onClick={e => DocumentView.PinDoc(this._activeDoc, {})}>
- <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
- </div>
- );
- } else return null;
- }
-
- // Buttons for switching the menu between large and small icons
- @computed get switchMenuView() {
- return this._activeDoc.title !== this._homeDoc.title ? null : (
- <div className="homeSwitch">
- <div className={`list ${!this._menuListView ? 'active' : ''}`} onClick={this.changeToIconView}>
- <FontAwesomeIcon size="sm" icon="th-large" />
- </div>
- <div className={`list ${this._menuListView ? 'active' : ''}`} onClick={this.changeToListView}>
- <FontAwesomeIcon size="sm" icon="bars" />
- </div>
- </div>
- );
- }
-
- // Logic for switching the menu into the icons
- @action
- changeToIconView = () => {
- if ((this._homeDoc._type_collection = 'stacking')) {
- this._menuListView = false;
- this._homeDoc._type_collection = 'masonry';
- this._homeDoc.columnWidth = 300;
- this._homeDoc._columnWidth = 300;
- const menuButtons = DocListCast(this._homeDoc.data);
- menuButtons.map(doc => {
- const buttonData = DocListCast(doc.data);
- buttonData[1]._nativeWidth = 0.1;
- buttonData[1]._width = 0.1;
- buttonData[1]._dimMagnitude = 0;
- buttonData[1]._opacity = 0;
- doc._nativeWidth = 400;
- });
- }
- };
-
- // Logic for switching the menu into the stacking view
- @action
- changeToListView = () => {
- if ((this._homeDoc._type_collection = 'masonry')) {
- this._homeDoc._type_collection = 'stacking';
- this._menuListView = true;
- const menuButtons = DocListCast(this._homeDoc.data);
- menuButtons.map(doc => {
- const buttonData = DocListCast(doc.data);
- buttonData[1]._nativeWidth = 450;
- buttonData[1]._dimMagnitude = 2;
- buttonData[1]._opacity = 1;
- doc._nativeWidth = 900;
- });
- }
- };
-
- // For setting up the presentation document for the home menu
- @action
- setupDefaultPresentation = () => {
- const presentation = Doc.ActivePresentation;
-
- if (presentation) {
- this.switchCurrentView(presentation);
- this._homeMenu = false;
- }
- };
-
- // For toggling image upload pop up
- @action
- toggleUpload = () => (this._imageUploadActive = !this._imageUploadActive);
-
- // For toggling audio record and dictate pop up
- @action
- toggleAudio = () => (this._audioUploadActive = !this._audioUploadActive);
-
- // Button for toggling the upload pop up in a collection
- @action
- toggleUploadInCollection = () => {
- const button = document.getElementById('imageButton') as HTMLElement;
- button.style.backgroundColor = this._imageUploadActive ? 'white' : 'black';
- button.style.color = this._imageUploadActive ? 'black' : 'white';
-
- this._imageUploadActive = !this._imageUploadActive;
- };
-
- // For closing the image upload pop up
- @action
- closeUpload = () => {
- this._imageUploadActive = false;
- };
-
- // Returns the image upload pop up
- @computed get uploadImage() {
- const doc = !this._homeMenu ? this._activeDoc : (Cast(Doc.SharingDoc(), Doc) as Doc);
- return <Uploader Document={doc} />;
- }
-
- // Radial menu can only be used if it is a colleciton and it is not a homeDoc
- // (and cannot be used on Dashboard to avoid pin to presentation opening on right)
- @computed get displayRadialMenu() {
- return this._activeDoc.type === 'collection' && this._activeDoc !== this._homeDoc && this._activeDoc._type_collection !== CollectionViewType.Docking ? <RadialMenu /> : null;
- }
-
- onDragOver = (e: React.DragEvent) => {
- e.preventDefault();
- e.stopPropagation();
- };
-
- /**
- * MENU BUTTON
- * Switch view from mobile menu to access the mobile uploads
- * Global function name: openMobileUploads()
- */
- @action
- switchToMobileUploads = () => {
- const mobileUpload = Cast(Doc.SharingDoc(), Doc) as Doc;
- this.switchCurrentView(mobileUpload);
- this._homeMenu = false;
- };
-
- render() {
- return (
- <div className="mobileInterface-container" onDragOver={this.onDragOver}>
- <SettingsManager />
- <div className={`image-upload ${this._imageUploadActive ? 'active' : ''}`}>{this.uploadImage}</div>
- {this.switchMenuView}
- {this.inkMenu}
- <GestureOverlay isActive={true}>
- <div style={{ display: 'none' }}>
- <RichTextMenu key="rich" />
- </div>
- <div className="docButtonContainer">
- {this.pinToPresentation}
- {this.downloadDocument}
- {this.undo}
- {this.redo}
- {this.drawInk}
- {this.uploadImageButton}
- </div>
- {this.displayDashboards}
- {this.renderDefaultContent}
- </GestureOverlay>
- {this.displayRadialMenu}
- </div>
- );
- }
-}
-
-//Global functions for mobile menu
-ScriptingGlobals.add(function switchToMobileLibrary() {
- return MobileInterface.Instance.switchToLibrary();
-}, 'opens the library to navigate through dashboards on Dash Mobile');
-ScriptingGlobals.add(function openMobileUploads() {
- return MobileInterface.Instance.toggleUpload();
-}, 'opens the upload files menu for Dash Mobile');
-ScriptingGlobals.add(function switchToMobileUploadCollection() {
- return MobileInterface.Instance.switchToMobileUploads();
-}, 'opens the mobile uploads collection on Dash Mobile');
-ScriptingGlobals.add(function openMobileAudio() {
- return MobileInterface.Instance.toggleAudio();
-}, 'opens the record and dictate menu on Dash Mobile');
-ScriptingGlobals.add(function switchToMobilePresentation() {
- return MobileInterface.Instance.setupDefaultPresentation();
-}, 'opens the presentation on Dash Mobile');
-ScriptingGlobals.add(function openMobileSettings() {
- return SettingsManager.Instance.openMgr();
-}, 'opens settings on Dash Mobile');
-
-// Other global functions for mobile
-ScriptingGlobals.add(
- function switchMobileView(doc: Doc, renderView?: () => JSX.Element, onSwitch?: () => void) {
- return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch);
- },
- 'changes the active document displayed on the Dash Mobile',
- '(doc: any)'
-);
diff --git a/src/mobile/MobileMain.tsx b/src/mobile/MobileMain.tsx
deleted file mode 100644
index 07839b6f6..000000000
--- a/src/mobile/MobileMain.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import * as React from 'react';
-import * as ReactDOM from 'react-dom';
-import { DocServer } from '../client/DocServer';
-import { Docs } from '../client/documents/Documents';
-import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
-import { AssignAllExtensions } from '../extensions/Extensions';
-import { MobileInterface } from './MobileInterface';
-
-AssignAllExtensions();
-
-(async () => {
- const info = await CurrentUserUtils.loadCurrentUser();
- DocServer.init(window.location.protocol, window.location.hostname, 4321, info.email + ' (mobile)');
- await Docs.Prototypes.initialize();
- await CurrentUserUtils.loadUserDocument(info);
- document.getElementById('root')!.addEventListener(
- 'wheel',
- event => {
- if (event.ctrlKey) {
- event.preventDefault();
- }
- },
- true
- );
- ReactDOM.render(<MobileInterface />, document.getElementById('root'));
-})();
diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss
deleted file mode 100644
index 7f286efc4..000000000
--- a/src/mobile/MobileMenu.scss
+++ /dev/null
@@ -1,271 +0,0 @@
-$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%;
-}
-// .navbar .home {
-// position: relative;
-// right: 5px;
-// transform: translate(50%, -50%);
-// font-size: 40;
-// user-select: none;
-// text-transform: uppercase;
-// font-family: Arial, Helvetica, sans-serif;
-// z-index: 200;
-// }
-
-.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;
- // overflow-y: auto;
- // -webkit-overflow-scrolling: touch;
-
- // 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 .ink {
- 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 .ink:focus {
- outline: 1px solid blue;
-}
-
-.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