From 4b1dc65c9e0bb917c1f1f780f8a63fc0c91b4ad6 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Tue, 16 Jun 2020 23:53:16 +0800 Subject: mobile menu bug fixes + doc button fix --- src/client/views/nodes/AudioBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 1a935d9b0..2e0be1c6a 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -228,7 +228,7 @@ export class AudioBox extends ViewBoxBaseComponent
- +
*/} - {/* */} -
- {this.renderAllGroups(groups)} -
- - ); - } else { - return ( - this._editingLink = undefined)}> - ); - } + return
this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}> + {!this._editingLink ? + this.renderAllGroups(groups) : + this._editingLink = undefined)} /> + } +
; } } \ No newline at end of file diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index 43dd698ad..b5d113ca0 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -175,76 +175,29 @@ @media only screen and (max-device-width: 480px) { - - .audiobox-container, - .audiobox-container-interactive { - width: max-content; - /* align-self: center; */ - left: 50%; - top: 40%; - transform: translate(-50%, 0); - height: 100px; - position: absolute; - display: flex; - pointer-events: all; - /* cursor: default; */ - } - - .audiobox-container .audiobox-buttons, - .audiobox-container-interactive .audiobox-buttons { - display: flex; - width: 500px; - /* left: 50%; */ - /* transform: translate(-50%,0); */ - align-items: center; - } - .audiobox-dictation { + font-size: 5em; + display: flex; width: 100; - height: 100; - font-size: 50; - /* background-color: white; */ + justify-content: center; + flex-direction: column; + align-items: center; } - .audiobox-container .audiobox-record-interactive, - .audiobox-container-interactive .audiobox-record-interactive { - width: 95%; - user-select: none; - font-size: 50px; - font-weight: 100; - left: 5%; + .audiobox-container .audiobox-record, + .audiobox-container-interactive .audiobox-record { + pointer-events: all; + font-size: 3em; + width: 100%; height: 100%; position: relative; + pointer-events: none; } .audiobox-container .audiobox-controls .audiobox-player .audiobox-playhead, .audiobox-container .audiobox-controls .audiobox-player .audiobox-dictation, .audiobox-container-interactive .audiobox-controls .audiobox-player .audiobox-playhead, .audiobox-container-interactive .audiobox-controls .audiobox-player .audiobox-dictation { - position: relative; - align-self: center; - width: 50px; - height: max-content; - padding: 0; - } - - .audiobox-container .audiobox-controls .audiobox-player, - .audiobox-container-interactive .audiobox-controls .audiobox-player { - margin-top: auto; - margin-bottom: auto; - width: 100%; - height: 100%; - position: relative; - padding-right: 5px; - display: flex; - } - - .audiobox-container .audiobox-controls, - .audiobox-container-interactive .audiobox-controls { - width: 500px; - height: 100%; - position: relative; - display: flex; - padding-left: 2px; + width: 70px; } } \ No newline at end of file diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index cb0582d87..d5288fff6 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -193,7 +193,7 @@ export class AudioBox extends ViewBoxBaseComponent { + private _linkButton = React.createRef(); + + @action + onLinkButtonMoved = (e: PointerEvent) => { + if (this._linkButton.current !== null) { + const linkDrag = UndoManager.StartBatch("Drag Link"); + this.props.View && DragManager.StartLinkDrag(this._linkButton.current, this.props.View.props.Document, e.pageX, e.pageY, { + dragComplete: dropEv => { + const linkDoc = dropEv.linkDragData?.linkDocument as Doc; // equivalent to !dropEve.aborted since linkDocument is only assigned on a completed drop + if (this.props.View && linkDoc) { + !linkDoc.linkRelationship && (Doc.GetProto(linkDoc).linkRelationship = "hyperlink"); + + // we want to allow specific views to handle the link creation in their own way (e.g., rich text makes text hyperlinks) + // the dragged view can regiser a linkDropCallback to be notified that the link was made and to update their data structures + // however, the dropped document isn't so accessible. What we do is set the newly created link document on the documentView + // The documentView passes a function prop returning this link doc to its descendants who can react to changes to it. + dropEv.linkDragData?.linkDropCallback?.(dropEv.linkDragData); + runInAction(() => this.props.View._link = linkDoc); + setTimeout(action(() => this.props.View._link = undefined), 0); + } + linkDrag?.end(); + }, + hideSource: false + }); + return true; + } + return false; + } + + @observable static StartLink: DocumentView | undefined; + onLinkButtonDown = (e: React.PointerEvent): void => { + setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => { + if (doubleTap) { + DocumentLinksButton.StartLink = this.props.View; + } else { + DocumentLinksButton.EditLink = this.props.View; + DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY]; + } + })); + } + completeLink = (e: React.PointerEvent): void => { + setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e, doubleTap) => { + if (doubleTap) { + if (DocumentLinksButton.StartLink === this.props.View) { + DocumentLinksButton.StartLink = undefined; + } else { + DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View && + DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag"); + } + } + })); + } + + @observable + public static EditLink: DocumentView | undefined; + public static EditLinkLoc: number[] = [0, 0]; + + @computed + get linkButton() { + const links = DocListCast(this.props.View.props.Document.links); + return (!links.length || links[0].hidden) && !this.props.AlwaysOn ? (null) : +
+
LinkDocPreview.LinkInfo = undefined)} + onPointerEnter={action(e => LinkDocPreview.LinkInfo = { + addDocTab: this.props.View.props.addDocTab, + linkSrc: this.props.View.props.Document, + linkDoc: links[0], + Location: [e.clientX, e.clientY + 20] + })} > + {links.length ? links.length : } +
+ {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ?
: (null)} + {DocumentLinksButton.StartLink === this.props.View ?
: (null)} +
; + } + render() { + return this.linkButton; + } +} \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index d31ec8c1a..afd28534e 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -42,6 +42,7 @@ import { LinkAnchorBox } from './LinkAnchorBox'; import { RadialMenu } from './RadialMenu'; import React = require("react"); import { MobileInterface } from '../../../mobile/MobileInterface'; +import { DocumentLinksButton } from './DocumentLinksButton'; library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight, fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale, @@ -585,10 +586,14 @@ export class DocumentView extends DocComponent(Docu toggleLinkButtonBehavior = (): void => { if (this.Document.isLinkButton || this.layoutDoc.onClick || this.Document.ignoreClick) { this.Document.isLinkButton = false; + const first = DocListCast(this.Document.links).find(d => d instanceof Doc); + first && (first.hidden = false); this.Document.ignoreClick = false; this.layoutDoc.onClick = undefined; } else { this.Document.isLinkButton = true; + const first = DocListCast(this.Document.links).find(d => d instanceof Doc); + first && (first.hidden = true); this.Document.followLinkZoom = false; this.Document.followLinkLocation = undefined; } @@ -598,8 +603,12 @@ export class DocumentView extends DocComponent(Docu toggleFollowInPlace = (): void => { if (this.Document.isLinkButton) { this.Document.isLinkButton = false; + const first = DocListCast(this.Document.links).find(d => d instanceof Doc); + first && (first.hidden = false); } else { this.Document.isLinkButton = true; + const first = DocListCast(this.Document.links).find(d => d instanceof Doc); + first && (first.hidden = true); this.Document.followLinkZoom = true; this.Document.followLinkLocation = "inPlace"; } @@ -609,6 +618,8 @@ export class DocumentView extends DocComponent(Docu toggleFollowOnRight = (): void => { if (this.Document.isLinkButton) { this.Document.isLinkButton = false; + const first = DocListCast(this.Document.links).find(d => d instanceof Doc); + first && (first.hidden = false); } else { this.Document.isLinkButton = true; this.Document.followLinkZoom = false; @@ -737,10 +748,8 @@ export class DocumentView extends DocComponent(Docu const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null); templateDoc && optionItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "onRight"), icon: "eye" }); - if (!options) { - options = { description: "Options...", subitems: optionItems, icon: "compass" }; - cm?.addItem(options); - } + optionItems.push({ description: "Toggle Show Each Link Dot", event: () => this.layoutDoc.showLinks = !this.layoutDoc.showLinks, icon: "eye" }); + !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); const existingOnClick = cm?.findByDescription("OnClick..."); const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; @@ -1039,7 +1048,8 @@ export class DocumentView extends DocComponent(Docu select={this.select} onClick={this.onClickHandler} layoutKey={this.finalLayoutKey} /> - {this.anchors} + {this.layoutDoc.showLinks ? this.anchors : (null)} + {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.props.dontRegisterView ? (null) : }
); } @@ -1063,7 +1073,7 @@ export class DocumentView extends DocComponent(Docu anchorPanelHeight = () => this.props.PanelHeight() || 1; @computed get anchors() { TraceMobx(); - return this.layoutDoc.presBox ? (null) : DocListCast(this.Document.links).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) => + return this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.layoutDoc.presBox || this.props.dontRegisterView ? (null) : DocListCast(this.Document.links).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) => (Docu PanelWidth={this.anchorPanelWidth} PanelHeight={this.anchorPanelHeight} ContentScaling={returnOne} + dontRegisterView={false} forcedBackgroundColor={returnTransparent} removeDocument={this.hideLinkAnchor} pointerEvents={false} @@ -1194,7 +1205,10 @@ export class DocumentView extends DocComponent(Docu color: StrCast(this.layoutDoc.color, "inherit"), outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px", border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined, - boxShadow: this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined, + boxShadow: this.Document.isLinkButton && !this.props.dontRegisterView && this.props.forcedBackgroundColor?.(this.Document) !== "transparent" ? + StrCast(this.props.Document._linkButtonShadow, "lightblue 0em 0em 1em") : + this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : + undefined, background: finalColor, opacity: finalOpacity, fontFamily: StrCast(this.Document._fontFamily, "inherit"), diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index 2b64cdab6..2bcc6168b 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -18,6 +18,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { SelectionManager } from "../../util/SelectionManager"; import { TraceMobx } from "../../../fields/util"; import { Id } from "../../../fields/FieldSymbols"; +import { LinkDocPreview } from "./LinkDocPreview"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -132,6 +133,13 @@ export class LinkAnchorBox extends ViewBoxBaseComponent LinkDocPreview.LinkInfo = undefined)} + onPointerEnter={action(e => LinkDocPreview.LinkInfo = { + addDocTab: this.props.addDocTab, + linkSrc: this.props.ContainingCollectionDoc!, + linkDoc: this.rootDoc, + Location: [e.clientX, e.clientY + 20] + })} onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle} onContextMenu={this.specificContextMenu} ref={this._ref} style={{ background: c, diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx new file mode 100644 index 000000000..126dc240a --- /dev/null +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -0,0 +1,107 @@ +import { action, computed, observable, runInAction } from 'mobx'; +import { observer } from "mobx-react"; +import wiki from "wikijs"; +import { Doc, DocCastAsync, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; +import { Cast, FieldValue, NumCast } from "../../../fields/Types"; +import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnZero } from "../../../Utils"; +import { Docs } from "../../documents/Documents"; +import { DocumentManager } from "../../util/DocumentManager"; +import { Transform } from "../../util/Transform"; +import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; +import React = require("react"); +import { DocumentView } from './DocumentView'; + +interface Props { + linkDoc?: Doc; + linkSrc?: Doc; + href?: string; + backgroundColor: (doc: Doc) => string; + addDocTab: (document: Doc, where: string) => boolean; + location: number[]; +} +@observer +export class LinkDocPreview extends React.Component { + @observable public static LinkInfo: Opt<{ linkDoc?: Doc; addDocTab: (document: Doc, where: string) => boolean, linkSrc: Doc; href?: string; Location: number[] }>; + @observable _targetDoc: Opt; + @observable _toolTipText = ""; + + componentDidUpdate() { this.updatePreview() } + componentDidMount() { this.updatePreview() } + async updatePreview() { + const linkDoc = this.props.linkDoc; + const linkSrc = this.props.linkSrc; + if (this.props.href) { + if (this.props.href.startsWith("https://en.wikipedia.org/wiki/")) { + wiki().page(this.props.href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(action(summary => this._toolTipText = summary.substring(0, 500)))); + } else { + runInAction(() => this._toolTipText = "external => " + this.props.href); + } + } else if (linkDoc && linkSrc) { + const anchor = FieldValue(Doc.AreProtosEqual(FieldValue(Cast(linkDoc.anchor1, Doc)), linkSrc) ? Cast(linkDoc.anchor2, Doc) : (Cast(linkDoc.anchor1, Doc)) || linkDoc); + const target = anchor?.annotationOn ? await DocCastAsync(anchor.annotationOn) : anchor; + runInAction(() => { + this._toolTipText = ""; + this._targetDoc = target; + if (anchor !== this._targetDoc && anchor && this._targetDoc) { + this._targetDoc._scrollY = NumCast(anchor?.y); + } + }); + } + } + pointerDown = (e: React.PointerEvent) => { + if (this.props.linkDoc && this.props.linkSrc) { + DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.linkSrc, + (doc: Doc, followLinkLocation: string) => this.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation)); + } else if (this.props.href) { + this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { title: this.props.href, _width: 200, _height: 400, UseCors: true }), "onRight"); + } + } + width = () => Math.min(350, NumCast(this._targetDoc?.[WidthSym](), 350)); + height = () => Math.min(350, NumCast(this._targetDoc?.[HeightSym](), 350)); + @computed get targetDocView() { + return !this._targetDoc ? +
+
+ {this._toolTipText} +
+
: + ; + } + + render() { + return
+ {this.targetDocView} +
; + } +} \ No newline at end of file diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 5e32b3ef8..839943aac 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -11,7 +11,7 @@ import { EditorState, NodeSelection, TextSelection } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { Doc } from "../../../../fields/Doc"; import { DarkPastelSchemaPalette, PastelSchemaPalette } from '../../../../fields/SchemaHeaderField'; -import { Cast, StrCast } from "../../../../fields/Types"; +import { Cast, StrCast, BoolCast } from "../../../../fields/Types"; import { unimplementedFunction, Utils } from "../../../../Utils"; import { DocServer } from "../../../DocServer"; import { LinkManager } from "../../../util/LinkManager"; @@ -72,7 +72,7 @@ export default class RichTextMenu extends AntimodeMenu { super(props); RichTextMenu.Instance = this; this._canFade = false; - this.Pinned = true; + this.Pinned = BoolCast(Doc.UserDoc()["menuRichText-pinned"]); this.fontSizeOptions = [ { mark: schema.marks.pFontSize.create({ fontSize: 7 }), title: "Set font size", label: "7pt", command: this.changeFontSize }, @@ -147,7 +147,6 @@ export default class RichTextMenu extends AntimodeMenu { this.updateFromDash(view, lastState, this.editorProps); } - public MakeLinkToSelection = (linkDocId: string, title: string, location: string, targetDocId: string): string => { if (this.view) { const link = this.view.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + linkDocId), title: title, location: location, linkId: linkDocId, targetId: targetDocId }); @@ -750,7 +749,7 @@ export default class RichTextMenu extends AntimodeMenu { @action toggleMenuPin = (e: React.MouseEvent) => { - this.Pinned = !this.Pinned; + Doc.UserDoc()["menuRichText-pinned"] = this.Pinned = !this.Pinned; if (!this.Pinned) { this.fadeOut(true); } @@ -779,7 +778,7 @@ export default class RichTextMenu extends AntimodeMenu { this.createHighlighterButton(), this.createLinkButton(), this.createBrushButton(), - this.createButton("indent", "Summarize", undefined, this.insertSummarizer), + this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer), this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote), ]}
; diff --git a/src/mobile/AudioUpload.scss b/src/mobile/AudioUpload.scss index 9fe442e55..6e64d9e2e 100644 --- a/src/mobile/AudioUpload.scss +++ b/src/mobile/AudioUpload.scss @@ -5,8 +5,45 @@ justify-content: center; flex-direction: column; align-items: center; - max-width: 400px; - min-width: 400px; + margin-top: 10px; + height: 400px; + width: 600px; +} + +.upload_label { + position: relative; + font-weight: 700; + color: black; + background-color: rgba(0, 0, 0, 0); + border: solid 3px black; + margin: 10px; + font-size: 30; + height: 70px; + width: 60%; + display: inline-flex; + font-family: sans-serif; + text-transform: uppercase; + justify-content: center; + flex-direction: column; + border-radius: 10px; +} + +.restart_label { + position: relative; + font-weight: 700; + color: black; + background-color: rgba(0, 0, 0, 0); + border: solid 3px black; + margin: 10px; + font-size: 30; + height: 70px; + width: 60%; + display: inline-flex; + font-family: sans-serif; + text-transform: uppercase; + justify-content: center; + flex-direction: column; + border-radius: 10px; } .audio-upload { diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx index 7ea11ee84..f859b0ba3 100644 --- a/src/mobile/AudioUpload.tsx +++ b/src/mobile/AudioUpload.tsx @@ -5,11 +5,11 @@ import "./ImageUpload.scss"; import React = require('react'); import { DocServer } from '../client/DocServer'; import { observer } from 'mobx-react'; -import { observable, action } from 'mobx'; -import { Utils, emptyPath, returnFalse, emptyFunction, returnOne, returnZero, returnTrue } from '../Utils'; +import { observable, action, computed } from 'mobx'; +import { Utils, emptyPath, returnFalse, emptyFunction, returnOne, returnZero, returnTrue, returnEmptyFilter } from '../Utils'; import { Networking } from '../client/Network'; import { Doc, Opt } from '../fields/Doc'; -import { Cast } from '../fields/Types'; +import { Cast, FieldValue } from '../fields/Types'; import { listSpec } from '../fields/Schema'; import { List } from '../fields/List'; import { Scripting } from '../client/util/Scripting'; @@ -38,185 +38,100 @@ export class AudioUpload extends React.Component { @observable status: string = ""; @observable nm: string = "Choose files"; @observable process: string = ""; + @observable public _audioCol: Doc = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc; - onClick = async () => { - try { - await Docs.Prototypes.initialize(); - const imgPrev = document.getElementById("img_preview"); - const slab1 = document.getElementById("slab1"); - if (slab1) { - slab1.style.opacity = "1"; - } - if (imgPrev) { - const files: FileList | null = inputRef.current!.files; - const slab2 = document.getElementById("slab2"); - if (slab2) { - slab2.style.opacity = "1"; - } - if (files && files.length !== 0) { - this.process = "Uploading Files"; - for (let index = 0; index < files.length; ++index) { - const file = files[index]; - const res = await Networking.UploadFilesToServer(file); - const slab3 = document.getElementById("slab3"); - if (slab3) { - slab3.style.opacity = "1"; - } - res.map(async ({ result }) => { - const name = file.name; - if (result instanceof Error) { - return; - } - const path = Utils.prepend(result.accessPaths.agnostic.client); - let doc = null; - console.log("type: " + file.type); - if (file.type === "video/mp4") { - doc = Docs.Create.VideoDocument(path, { _nativeWidth: 200, _width: 200, title: name }); - } else if (file.type === "application/pdf") { - doc = Docs.Create.PdfDocument(path, { _width: 200, title: name }); - } else { - doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name }); - } - const slab4 = document.getElementById("slab4"); - if (slab4) { - slab4.style.opacity = "1"; - } - const res = await rp.get(Utils.prepend("/getUserDocumentId")); - if (!res) { - throw new Error("No user id returned"); - } - const field = await DocServer.GetRefField(res); - let pending: Opt; - if (field instanceof Doc) { - pending = await Cast(field.mobileUpload, Doc); - } - if (pending) { - const data = await Cast(pending.data, listSpec(Doc)); - if (data) { - data.push(doc); - } else { - pending.data = new List([doc]); - } - this.status = "finished"; - const slab5 = document.getElementById("slab5"); - if (slab5) { - slab5.style.opacity = "1"; - } - this.process = "File " + (index + 1).toString() + " Uploaded"; - const slab6 = document.getElementById("slab6"); - if (slab6) { - slab6.style.opacity = "1"; - } - const slab7 = document.getElementById("slab7"); - if (slab7) { - slab7.style.opacity = "1"; - } - - } - }); - } - } else { - this.process = "No file selected"; - } - setTimeout(this.clearUpload, 3000); - } - } catch (error) { - this.error = JSON.stringify(error); - } - } - - // Updates label after a files is selected (so user knows a file is uploaded) - inputLabel = async () => { - const files: FileList | null = inputRef.current!.files; - await files; - if (files && files.length === 1) { - console.log(files); - this.nm = files[0].name; - } else if (files && files.length > 1) { - console.log(files.length); - this.nm = files.length.toString() + " files selected"; - } - } @action clearUpload = () => { - const slab1 = document.getElementById("slab1"); - if (slab1) { - slab1.style.opacity = "0.4"; - } - const slab2 = document.getElementById("slab2"); - if (slab2) { - slab2.style.opacity = "0.4"; - } - const slab3 = document.getElementById("slab3"); - if (slab3) { - slab3.style.opacity = "0.4"; + for (let i = 1; i < 8; i++) { + this.setOpacity(i, "0.2"); } - const slab4 = document.getElementById("slab4"); - if (slab4) { - slab4.style.opacity = "0.4"; - } - const slab5 = document.getElementById("slab5"); - if (slab5) { - slab5.style.opacity = "0.4"; - } - const slab6 = document.getElementById("slab6"); - if (slab6) { - slab6.style.opacity = "0.4"; - } - const slab7 = document.getElementById("slab7"); - if (slab7) { - slab7.style. - opacity = "0.4"; - } - this.nm = "Choose files"; - - if (inputRef.current) { - inputRef.current.value = ""; - } - this.process = ""; - console.log(inputRef.current!.files); + this._audioCol = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc; } - + closeUpload = () => { + this.clearUpload(); + MobileInterface.Instance.toggleAudio(); + } private get uploadInterface() { - const audioDoc = Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio" }), Doc) as Doc; - return ( -
-
+ <> +
this.closeUpload()}>
- 1000} - PanelHeight={() => 1000} - NativeHeight={returnZero} - NativeWidth={returnZero} - renderDepth={0} - focus={emptyFunction} - backgroundColor={() => "white"} - parentActive={returnTrue} - whenActiveChanged={emptyFunction} - bringToFront={emptyFunction} - ContainingCollectionView={undefined} - ContainingCollectionDoc={undefined} - /> -
+ +
+ 600} + PanelHeight={() => 400} + NativeHeight={returnZero} + NativeWidth={returnZero} + renderDepth={0} + focus={emptyFunction} + backgroundColor={() => "rgba(0,0,0,0)"} + parentActive={returnTrue} + whenActiveChanged={emptyFunction} + bringToFront={emptyFunction} + ContainingCollectionView={undefined} + ContainingCollectionDoc={undefined} + /> +
+
+ Restart +
+
+ Upload +
+
+
+
+
+
+
+
+
+
+ ); } + setOpacity = (i: number, o: string) => { + const slab = document.getElementById("slab0" + i); + if (slab) { + console.log(slab?.id); + slab.style.opacity = o; + } + } + + // Pushing the audio doc onto Dash Web through the right side bar + uploadAudio = () => { + console.log("uploading"); + const audioRightSidebar = Cast(Doc.UserDoc().rightSidebarCollection, Doc) as Doc; + const audioDoc = this._audioCol; + const data = Cast(audioRightSidebar.data, listSpec(Doc)); + for (let i = 1; i < 8; i++) { + setTimeout(() => this.setOpacity(i, "1"), i * 200); + } + if (data) { + data.push(audioDoc); + } + + setTimeout(this.clearUpload, 3000); + } + @observable private dialogueBoxOpacity = 1; @observable private overlayOpacity = 0.4; diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss index b64aac338..890258918 100644 --- a/src/mobile/ImageUpload.scss +++ b/src/mobile/ImageUpload.scss @@ -9,13 +9,19 @@ min-width: 400px; .upload_label { - font-size: 3em; font-weight: 700; - color: white; - background-color: black; - display: inline-block; - margin: 10; - width: 100%; + 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; } @@ -26,10 +32,6 @@ direction: ltr; } - .upload_label:hover { - background-color: darkred; - } - .button_file { text-align: center; height: 50%; @@ -49,20 +51,31 @@ } .inputfile+label { - font-size: 3em; font-weight: 700; - color: white; - background-color: black; - display: inline-block; + 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: 100%; + width: 80%; + display: flex; + font-family: sans-serif; + text-transform: uppercase; + justify-content: center; + flex-direction: column; border-radius: 10px; } - .inputfile:focus+label, - .inputfile+label:hover { - background-color: darkred; + .inputfile.active+label { + font-style: italic; + color: black; + background-color: lightgreen; + border: solid 3px darkgreen; } .status { @@ -71,16 +84,6 @@ } -.backgroundUpload { - height: 100vh; - top: 0; - z-index: 999; - width: 100vw; - position: absolute; - background-color: lightgrey; - opacity: 0.4; -} - .image-upload { top: 100%; opacity: 0; @@ -129,7 +132,7 @@ height: 30px; margin: 10; border-radius: 20px; - opacity: 0.3; + opacity: 0.2; background-color: black; transition: all 2s, opacity 1.5s; } \ No newline at end of file diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx index b712d52cc..6a5a2dd5b 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -43,21 +43,18 @@ export class Uploader extends React.Component { await Docs.Prototypes.initialize(); const imgPrev = document.getElementById("img_preview"); // Slab 1 - const slab1 = document.getElementById("slab1"); - if (slab1) slab1.style.opacity = "1"; + this.setOpacity(1, "1"); if (imgPrev) { const files: FileList | null = inputRef.current!.files; // Slab 2 - const slab2 = document.getElementById("slab2"); - if (slab2) slab2.style.opacity = "1"; + this.setOpacity(2, "1"); if (files && files.length !== 0) { this.process = "Uploading Files"; for (let index = 0; index < files.length; ++index) { const file = files[index]; const res = await Networking.UploadFilesToServer(file); // Slab 3 - const slab3 = document.getElementById("slab3"); - if (slab3) slab3.style.opacity = "1"; + this.setOpacity(3, "1"); res.map(async ({ result }) => { const name = file.name; if (result instanceof Error) { @@ -74,8 +71,7 @@ export class Uploader extends React.Component { doc = Docs.Create.ImageDocument(path, { _nativeWidth: 400, _width: 400, title: name }); } // Slab 4 - const slab4 = document.getElementById("slab4"); - if (slab4) slab4.style.opacity = "1"; + this.setOpacity(4, "1"); const res = await rp.get(Utils.prepend("/getUserDocumentId")); if (!res) { throw new Error("No user id returned"); @@ -94,13 +90,15 @@ export class Uploader extends React.Component { if (data) data.push(doc); else pending.data = new List([doc]); this.status = "finished"; - const slab5 = document.getElementById("slab5"); - if (slab5) slab5.style.opacity = "1"; + this.setOpacity(5, "1"); // Slab 5 this.process = "File " + (index + 1).toString() + " Uploaded"; - const slab6 = document.getElementById("slab6"); - if (slab6) slab6.style.opacity = "1"; - const slab7 = document.getElementById("slab7"); - if (slab7) slab7.style.opacity = "1"; + this.setOpacity(6, "1"); // Slab 6 + this.setOpacity(7, "1"); // Slab 7 + } + console.log("i: " + index + 1); + console.log("l: " + files.length); + if ((index + 1) === files.length) { + this.process = "Uploads Completed"; } }); } @@ -129,20 +127,9 @@ export class Uploader extends React.Component { @action clearUpload = () => { - const slab1 = document.getElementById("slab1"); - if (slab1) slab1.style.opacity = "0.4"; - const slab2 = document.getElementById("slab2"); - if (slab2) slab2.style.opacity = "0.4"; - const slab3 = document.getElementById("slab3"); - if (slab3) slab3.style.opacity = "0.4"; - const slab4 = document.getElementById("slab4"); - if (slab4) slab4.style.opacity = "0.4"; - const slab5 = document.getElementById("slab5"); - if (slab5) slab5.style.opacity = "0.4"; - const slab6 = document.getElementById("slab6"); - if (slab6) slab6.style.opacity = "0.4"; - const slab7 = document.getElementById("slab7"); - if (slab7) slab7.style.opacity = "0.4"; + for (let i = 1; i < 8; i++) { + this.setOpacity(i, "0.2"); + } this.nm = "Choose files"; if (inputRef.current) { @@ -152,24 +139,33 @@ export class Uploader extends React.Component { console.log(inputRef.current!.files); } + closeUpload = () => { + this.clearUpload(); + MobileInterface.Instance.toggleUpload(); + } + + setOpacity = (i: number, o: string) => { + const slab = document.getElementById("slab" + i); + if (slab) { + console.log(slab?.id); + slab.style.opacity = o; + } + } private get uploadInterface() { return (
-
+
this.closeUpload()}>
- + +
- -     Upload + Upload
- {/*
Upload
*/} - {/*

{this.status}

-

{this.error}

*/}
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index a1719c015..5894326ab 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { library } from '@fortawesome/fontawesome-svg-core'; import { - faTasks, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus, + 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, faFile as 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, @@ -43,8 +43,9 @@ import { AudioUpload } from "./AudioUpload"; import { Cast, FieldValue } from '../fields/Types'; import { CollectionView } from '../client/views/collections/CollectionView'; import { InkingStroke } from '../client/views/InkingStroke'; +import RichTextMenu from "../client/views/nodes/formattedText/RichTextMenu"; -library.add(faTasks, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus, +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, @@ -387,13 +388,13 @@ export class MobileInterface extends React.Component { return (
this.handleClick(doc)}> -
{doc.title}
-
{doc.type}
- + key={index}> +
this.handleClick(doc)}> {doc.title}
+
this.handleClick(doc)}>{doc.type}
+ this.handleClick(doc)} className="right" icon="angle-right" size="lg" style={{ display: `${doc.type === "collection" ? "block" : "none"}` }} /> this.openFromSidebar(doc)} icon="external-link-alt" size="lg" /> -
); +
+ ); } }); @@ -440,7 +441,7 @@ export class MobileInterface extends React.Component { } /** - * Handles the Create New Workspace button in the menu + * Handles the Create New Workspace button in the menu (taken from MainView.tsx) */ @action createNewWorkspace = async (id?: string) => { @@ -759,12 +760,7 @@ export class MobileInterface extends React.Component { toggle = this.toggleUpload; } return ( -
-
- -
- -
+ ); } @@ -815,6 +811,7 @@ export class MobileInterface extends React.Component { {this.switchMenuView()} {this.inkMenu()} +
{this.pinToPresentation()} {this.downloadDocument()} @@ -843,6 +840,6 @@ Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.I Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); }); Scripting.addGlobal(function openMobileAudio() { return MobileInterface.Instance.toggleAudio(); }); Scripting.addGlobal(function openMobileSettings() { return SettingsManager.Instance.open(); }); -Scripting.addGlobal(function openWorkspaces() { return MobileInterface.Instance.openWorkspaces(); }); +Scripting.addGlobal(function openMobileWorkspaces() { return MobileInterface.Instance.openWorkspaces(); }); Scripting.addGlobal(function uploadImageMobile() { return MobileInterface.Instance.toggleUpload(); }); Scripting.addGlobal(function switchToMobileUploads() { return MobileInterface.Instance.switchToMobileUploads(); }); diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss index 53bc48034..c499e6d1e 100644 --- a/src/mobile/MobileMenu.scss +++ b/src/mobile/MobileMenu.scss @@ -176,6 +176,7 @@ body { .open { right: 20px; + font-size: 35; position: absolute; } -- cgit v1.2.3-70-g09d2