From 0bd7f4f85be56de4326f0671453fc5e5e917a5d0 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Sun, 7 Jun 2020 21:22:25 -0700 Subject: pull current work in --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 80ee2a65d..8b0c72f5e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -597,7 +597,7 @@ export class CollectionFreeFormView extends CollectionSubView { // bcz: theres should be a better way of doing these than referencing these static instances directly MarqueeOptionsMenu.Instance?.fadeOut(true);// I think it makes sense for the marquee menu to go away when panned. -syip2 - PDFMenu.Instance.fadeOut(true); + // PDFMenu.Instance.fadeOut(true); const [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY); this.setPan((this.Document._panX || 0) - dx, (this.Document._panY || 0) - dy, undefined, true); -- cgit v1.2.3-70-g09d2 From ba0d831691e81903ab1fb9482ba5dcad0a769881 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Thu, 11 Jun 2020 23:40:49 -0700 Subject: functioning with new ink --- src/client/views/AntimodeMenu.scss | 9 ++--- .../collectionFreeForm/InkOptionsMenu.scss | 38 ++++++++++++++++++++-- .../collectionFreeForm/InkOptionsMenu.tsx | 16 +++++++-- src/mobile/MobileInterface.tsx | 15 +++++---- src/mobile/MobileMenu.scss | 9 +++-- 5 files changed, 71 insertions(+), 16 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss index 9c5bf0a1f..170631422 100644 --- a/src/client/views/AntimodeMenu.scss +++ b/src/client/views/AntimodeMenu.scss @@ -53,18 +53,19 @@ display: flex; &.with-rows { - flex-direction: column + flex-direction: column-reverse; } .antimodeMenu-row { display: flex; - height: 35px; + height: 100%; + width:100%; } .antimodeMenu-button { background-color: transparent; - width: 35px; - height: 35px; + width: 100px; + height: 100px; &.active { background-color: #121212; diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss index 3671a84b9..72fdf5af9 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss @@ -4,7 +4,6 @@ height: 100%; } - } .sketch-picker { @@ -31,7 +30,42 @@ background: #323232; display: block; - } } +@media only screen and (max-width: 1000px) { + .antimodeMenu-button { + .color-preview { + width: 100%; + height: 100%; + } + + } + + .sketch-picker { + background: #323232; + + .flexbox-fit { + background: #323232; + } + } + + .btn-group { + display: grid; + grid-template-columns: auto auto; + /* Make the buttons appear below each other */ + } + + .btn2-group { + display: block; + background: #323232; + grid-template-columns: auto; + + /* Make the buttons appear below each other */ + .antimodeMenu-button { + background: #323232; + display: block; + + } + } +} diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index 5a27f74e5..46f7bc2e2 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -11,6 +11,8 @@ import { Utils } from "../../../../Utils"; import GestureOverlay from "../../GestureOverlay"; import { Doc } from "../../../../fields/Doc"; + + @observer export default class InkOptionsMenu extends AntimodeMenu { static Instance: InkOptionsMenu; @@ -23,6 +25,8 @@ export default class InkOptionsMenu extends AntimodeMenu { @observable _colorBtn = false; @observable _widthBtn = false; + + constructor(props: Readonly<{}>) { super(props); InkOptionsMenu.Instance = this; @@ -113,7 +117,7 @@ export default class InkOptionsMenu extends AntimodeMenu { title="Bezier changer" key="bezier" onPointerDown={e => this.changeBezier(e)} - style={ { backgroundColor:ActiveInkBezierApprox() ? "121212":"" } }> + style={{ backgroundColor: ActiveInkBezierApprox() ? "121212" : "" }}> B ; } @@ -126,7 +130,15 @@ export default class InkOptionsMenu extends AntimodeMenu { this.widthPicker, this.colorPicker, ]; - return this.getElement(buttons); + + const mobileButtons = [ + this.shapeButtons, + this.bezierButton, + this.widthPicker, + this.colorPicker, + ]; + + return (window.innerWidth < 1000 ? this.getElement(mobileButtons) : this.getElement(buttons)); } } Scripting.addGlobal(function activatePen(penBtn: any) { diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index ba52e3df9..3a7a1594b 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -1481,20 +1481,20 @@ export class MobileInterface extends React.Component { const button = document.getElementById("inkButton") as HTMLElement; // const color = InkingControl.Instance.selectedColor; const color = "lightpink"; - button.style.backgroundColor = this._ink ? "white" : color; + button.style.backgroundColor = this._ink ? "white" : "black"; button.style.color = this._ink ? "black" : "white"; if (!this._ink) { console.log("INK IS ACTIVE"); // InkingControl.Instance.switchTool(InkTool.Pen); Doc.SetSelectedTool(InkTool.Pen); - InkOptionsMenu.Instance.jumpTo(300, 300); + //InkOptionsMenu.Instance.jumpTo(300, 300); this._ink = true; } else { console.log("INK IS INACTIVE"); // InkingControl.Instance.switchTool(InkTool.None); Doc.SetSelectedTool(InkTool.None); - InkOptionsMenu.Instance.fadeOut(true); + //InkOptionsMenu.Instance.fadeOut(true); this._ink = false; } } @@ -1502,7 +1502,11 @@ export class MobileInterface extends React.Component { inkMenu = () => { if (this._activeDoc._viewType === "docking") { if (this._ink) { - return + console.log("here"); + return
+ +
+ } } } @@ -1794,9 +1798,8 @@ export class MobileInterface extends React.Component { {this.drawInk()} {this.uploadAudioButton()} {/* {this.colorTool()} */} - {this.inkMenu()} - + {this.inkMenu()} {this.displayWorkspaces()} {this.renderDefaultContent()} diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss index 6d450bc6d..54156a735 100644 --- a/src/mobile/MobileMenu.scss +++ b/src/mobile/MobileMenu.scss @@ -333,12 +333,17 @@ body { top: -450px; } -.toolbar .colorSelector { +.colorSelector { + position: absolute; + top: 550px; + left: 300px; + transform: translate(-50%, 0); + z-index: 100; display: inline-flex; width: max-content; - padding: 5px; height: max-content; pointer-events: all; + font-size: 90px; } .widthSelector { -- cgit v1.2.3-70-g09d2 From 87aa11c70be1ae0270c69adc0c1e0219f79ce820 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Tue, 16 Jun 2020 01:34:12 +0800 Subject: uploader + menu changes image upload w/ video and other files menu updates --- src/client/util/CurrentUserUtils.ts | 23 +-- src/client/views/GestureOverlay.scss | 2 +- .../views/collections/CollectionStackingView.scss | 10 +- .../collectionFreeForm/InkOptionsMenu.tsx | 4 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- .../views/presentationview/PresElementBox.tsx | 2 +- src/mobile/ImageUpload.scss | 1 + src/mobile/ImageUpload.tsx | 139 +++++++++--------- src/mobile/MobileInterface.tsx | 156 ++------------------- src/mobile/MobileMenu.scss | 8 +- 10 files changed, 109 insertions(+), 238 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 1b0622f6d..e1605473c 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -329,7 +329,8 @@ export class CurrentUserUtils { doc.emptyWebpage = Docs.Create.WebDocument("", { title: "New Webpage", _nativeWidth: 850, _nativeHeight: 962, _width: 600, UseCors: true }); } if (doc.activeMobile === undefined) { - doc.activeMobile = CurrentUserUtils.setupMobileMenu(); + console.log("phone setup"); + this.setupActiveMobile(doc); } return [ { title: "Drag a comparison box", label: "Comp", icon: "columns", ignoreClick: true, drag: 'Docs.Create.ComparisonDocument()' }, @@ -398,16 +399,18 @@ export class CurrentUserUtils { return doc.myItemCreators as Doc; } - // static setupActiveMobile(doc: Doc) { - // if (doc.activeMobile === undefined) { - // doc.activeMobile = CurrentUserUtils.setupMobileMenu(); - // } - // } + static setupActiveMobile(doc: Doc) { + if (doc.activeMobile === undefined) { + console.log("undefined"); + doc.activeMobile = this.setupMobileMenu(); + } + return doc.activeMobile as Doc; + } static setupMobileMenu() { - const menu = Cast(Docs.Create.StackingDocument(CurrentUserUtils.setupMobileButtons(), { - _width: 980, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "home", _yMargin: 100 - }), Doc) as Doc; + const menu = new PrefetchProxy(Docs.Create.StackingDocument(this.setupMobileButtons(), { + _width: 980, ignoreClick: true, lockedPosition: false, _chromeStatus: "disabled", title: "home", _yMargin: 100 + })); return menu; } @@ -740,7 +743,7 @@ export class CurrentUserUtils { this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon this.setupDocTemplates(doc); // sets up the template menu of templates this.setupRightSidebar(doc); // sets up the right sidebar collection for mobile upload documents and sharing - // this.setupActiveMobile(doc); + this.setupActiveMobile(doc); this.setupOverlays(doc); // documents in overlay layer this.setupDockedButtons(doc); // the bottom bar of font icons this.setupDefaultPresentation(doc); // presentation that's initially triggered diff --git a/src/client/views/GestureOverlay.scss b/src/client/views/GestureOverlay.scss index 107077792..f61f4a05e 100644 --- a/src/client/views/GestureOverlay.scss +++ b/src/client/views/GestureOverlay.scss @@ -1,7 +1,7 @@ .gestureOverlay-cont { width: 100vw; height: 100vh; - position: absolute; + position: fixed; top: 0; left: 0; touch-action: none; diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 714ff46a9..98efdfd23 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -428,11 +428,9 @@ .collectionStackingView .collectionStackingView-columnDragger, .collectionMasonryView .collectionStackingView-columnDragger { - width: 30; - transform: translate(0, -40px); - height: 30; - font-size: 40; - position: absolute; - margin-left: -5; + width: 0.1; + height: 0.1; + opacity: 0; + font-size: 0; } } \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index 5a27f74e5..9f5e217bf 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -101,7 +101,7 @@ export default class InkOptionsMenu extends AntimodeMenu { title={`Draw ${btn}`} key={btn} onPointerDown={action(e => GestureOverlay.Instance.InkShape = btn)} - style={{ backgroundColor: btn === GestureOverlay.Instance.InkShape ? "121212" : "" }}> + style={{ backgroundColor: btn === GestureOverlay.Instance?.InkShape ? "121212" : "" }}> {this._icons[i]} )}, ; @@ -113,7 +113,7 @@ export default class InkOptionsMenu extends AntimodeMenu { title="Bezier changer" key="bezier" onPointerDown={e => this.changeBezier(e)} - style={ { backgroundColor:ActiveInkBezierApprox() ? "121212":"" } }> + style={{ backgroundColor: ActiveInkBezierApprox() ? "121212" : "" }}> B ; } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 1fab54d7e..e034e07a0 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1213,7 +1213,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground; if (this.props.isSelected()) { - this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props); + this._editorView && RichTextMenu.Instance?.updateFromDash(this._editorView, undefined, this.props); } else if (FormattedTextBoxComment.textBox === this) { FormattedTextBoxComment.Hide(); } diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index caee06d8f..793d4068f 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -49,7 +49,7 @@ export class PresElementBox extends ViewBoxBaseComponent [this.rootDoc.presExpandInlineButton, this.collapsedHeight], - params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 100 : 0), { fireImmediately: true }); + params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 200 : 0), { fireImmediately: true }); } componentWillUnmount() { this._heightDisposer?.(); diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss index d5ab31469..95c0c2680 100644 --- a/src/mobile/ImageUpload.scss +++ b/src/mobile/ImageUpload.scss @@ -6,6 +6,7 @@ flex-direction: column; align-items: center; max-width: 400px; + min-width: 400px; .upload_label { font-size: 3em; diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx index 8f050aedd..3b4008e3f 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -14,6 +14,7 @@ import { listSpec } from '../fields/Schema'; import { List } from '../fields/List'; import { Scripting } from '../client/util/Scripting'; import MainViewModal from '../client/views/MainViewModal'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; export interface ImageUploadProps { Document: Doc; @@ -35,83 +36,80 @@ export class Uploader extends React.Component { @observable process: string = ""; onClick = async () => { - console.log("uploader click"); try { - this.status = "initializing protos"; + await Docs.Prototypes.initialize(); + const imgPrev = document.getElementById("img_preview"); const slab1 = document.getElementById("slab1"); if (slab1) { slab1.style.opacity = "1"; } - await Docs.Prototypes.initialize(); - const imgPrev = document.getElementById("img_preview"); - console.log("buddy"); if (imgPrev) { - console.log("hi"); 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 Image" - console.log(files[0]); - const name = files[0].name; - const res = await Networking.UploadFilesToServer(files[0]); - this.status = "uploading image"; - const slab2 = document.getElementById("slab2"); - if (slab2) { - slab2.style.opacity = "1"; - } - this.status = "upload image, getting json"; - const slab3 = document.getElementById("slab3"); - if (slab3) { - slab3.style.opacity = "1"; - } - res.map(async ({ result }) => { - if (result instanceof Error) { - return; - } - const path = Utils.prepend(result.accessPaths.agnostic.client); - const doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name }); - - this.status = "getting user document"; - const slab4 = document.getElementById("slab4"); - if (slab4) { - slab4.style.opacity = "1"; - } - this.status = "upload image, getting json"; - const slab5 = document.getElementById("slab5"); - if (slab5) { - slab5.style.opacity = "1"; + 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"; } - 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.rightSidebarCollection, Doc); - } - if (pending) { - this.status = "has pending docs"; - const slab6 = document.getElementById("slab6"); - if (slab6) { - slab6.style.opacity = "1"; + res.map(async ({ result }) => { + const name = file.name; + if (result instanceof Error) { + return; } - const data = await Cast(pending.data, listSpec(Doc)); - if (data) { - data.push(doc); + const path = Utils.prepend(result.accessPaths.agnostic.client); + let doc = null; + if (file.type === "video/mp4") { + doc = Docs.Create.VideoDocument(path, { _nativeWidth: 200, _width: 200, title: name }); } else { - pending.data = new List([doc]); + doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name }); } - this.status = "finished"; - - console.log("hi"); - const slab7 = document.getElementById("slab7"); - if (slab7) { - slab7.style.opacity = "1"; + 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.rightSidebarCollection, Doc); } - this.process = "Image Uploaded"; + 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"; + if (index === files.length) { + const slab6 = document.getElementById("slab6"); + if (slab6) { + slab6.style.opacity = "1"; + } + } + } + }); + this.process = "All Files Uploaded"; + const slab7 = document.getElementById("slab7"); + if (slab7) { + slab7.style.opacity = "1"; } - - }); + } } else { this.process = "No file selected"; } @@ -120,16 +118,18 @@ export class Uploader extends React.Component { } 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 !== 0) { + 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"; } } @@ -163,7 +163,7 @@ export class Uploader extends React.Component { if (slab7) { slab7.style.opacity = "0.4"; } - this.nm = "Choose an image"; + this.nm = "Choose files"; if (inputRef.current) { inputRef.current.value = ""; @@ -177,9 +177,12 @@ export class Uploader extends React.Component { private get uploadInterface() { return (
- + -
Upload Image
+
+ + Upload +
{/*
Upload
*/} {/*

{this.status}

diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index f2914eaae..211cc7a1a 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -52,10 +52,7 @@ export class MobileInterface extends React.Component { @observable static Instance: MobileInterface; @computed private get userDoc() { return Doc.UserDoc(); } @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; } - // @computed private get activeContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeMobile, Doc)) : CurrentUserUtils.GuestMobile; } - // Sets up new mobile menu only if activeMobile already exists - // @observable private mainDoc: any = this.userDoc.activeMobile === undefined ? CurrentUserUtils.setupMobileMenu() : this.userDoc.activeMobile; - @observable private mainDoc: any = CurrentUserUtils.setupMobileMenu(); + @observable private mainDoc: any = CurrentUserUtils.setupActiveMobile(this.userDoc); @observable private renderView?: () => JSX.Element; @observable private audioState: any; @observable private activeToolbar: boolean = false; @@ -86,13 +83,7 @@ export class MobileInterface extends React.Component { @action componentDidMount = () => { - library.add(...[faPenNib, faHighlighter, faEraser, faMousePointer, faThumbtack]); - if (this.userDoc.activeMobile) { - console.log(Doc.UserDoc().activeMobile); - } - if (this.userDoc && !this.mainContainer) { - this.userDoc.activeMobile = this._homeDoc; - } + Doc.UserDoc().activeMobile = this._homeDoc; this._homeDoc._viewType === "stacking" ? this.menuListView = true : this.menuListView = false; Doc.SetSelectedTool(InkTool.None); this.switchCurrentView((userDoc: Doc) => this._homeDoc); @@ -353,26 +344,6 @@ export class MobileInterface extends React.Component {
); } - // } - // } else { - - // return ( - //
- //
- //
- //
this.returnHome()}>Home - //
- //
- //
- //
- //
- // ); - // } - - // } } // Handles when user clicks on document in the pathbar @@ -393,16 +364,6 @@ export class MobileInterface extends React.Component { } renderDefaultContent = () => { - let menuButtons = DocListCast(this._homeDoc.data).map((doc: Doc, index: any) => { - if (doc.type !== "ink") { - return ( -
doc.onClick}>{doc.title} -
); - } - }); if (this._homeMenu === true) { return ( @@ -420,7 +381,10 @@ export class MobileInterface extends React.Component { {this.renderPathbar()}
@@ -429,7 +393,7 @@ export class MobileInterface extends React.Component { let workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc; if (this._child) { - workspaces = this._child + workspaces = this._child; } let buttons = DocListCast(workspaces.data).map((doc: Doc, index: any) => { @@ -468,6 +432,10 @@ export class MobileInterface extends React.Component { : <> {buttons} +
ScriptField.MakeScript("createNewWorkspace()")}>Create New Workspace +
}
@@ -627,100 +595,12 @@ export class MobileInterface extends React.Component { // this.recordAudio(); } - // renderActiveCollection = (userDoc: Doc) => { - // if (this.activeContainer) { - // const active = Cast(this.activeContainer.data, listSpec(Doc)); - // if (active) { - // return ( - //
HELLO!
- // ); - // } - // } - // } - - onBack = (e: React.MouseEvent) => { - this.switchCurrentView((userDoc: Doc) => this.mainDoc); - Doc.SetSelectedTool(InkTool.None); // TODO: switch to previous tool - - DocServer.Mobile.dispatchOverlayTrigger({ - enableOverlay: false, - width: window.innerWidth, - height: window.innerHeight - }); - - // this.inkDoc = undefined; - this.drawingInk = false; - } - - shiftLeft = (e: React.MouseEvent) => { - DocServer.Mobile.dispatchOverlayPositionUpdate({ - dx: -10 - }); - e.preventDefault(); - e.stopPropagation(); - } - - shiftRight = (e: React.MouseEvent) => { - DocServer.Mobile.dispatchOverlayPositionUpdate({ - dx: 10 - }); - e.preventDefault(); - e.stopPropagation(); - } - panelHeight = () => window.innerHeight; panelWidth = () => window.innerWidth; //WAS 3 //WAS 1 - upload = async (e: React.MouseEvent) => { - if (this.mainContainer) { - const data = Cast(this.mainContainer.data, listSpec(Doc)); - if (data) { - const collectionDoc = await data[1]; //this should be the collection doc since the positions should be locked - const children = DocListCast(collectionDoc.data); - const uploadDoc = children.length === 1 ? children[0] : Docs.Create.StackingDocument(children, { - title: "Mobile Upload Collection", backgroundColor: "white", lockedPosition: true, _width: 300, _height: 300 - }); - if (uploadDoc) { - DocServer.Mobile.dispatchMobileDocumentUpload({ - docId: uploadDoc[Id], - }); - } - } - } - e.stopPropagation(); - e.preventDefault(); - } - - addWebToCollection = async () => { - let url = "https://en.wikipedia.org/wiki/Hedgehog"; - if (this.mainContainer) { - const data = Cast(this.mainContainer.data, listSpec(Doc)); - if (data) { - const webDoc = await data[0]; - const urlField: FieldResult = Cast(webDoc.data, WebField); - url = urlField ? urlField.url.toString() : "https://en.wikipedia.org/wiki/Hedgehog"; - - } - } - Docs.Create.WebDocument(url, { _width: 300, _height: 300, title: "Mobile Upload Web Doc" }); - } - - clearUpload = async () => { - if (this.mainContainer) { - const data = Cast(this.mainContainer.data, listSpec(Doc)); - if (data) { - const collectionDoc = await data[1]; - const children = DocListCast(collectionDoc.data); - children.forEach(doc => { - }); - // collectionDoc[data] = new List(); - } - } - } - pinToPresentation = () => { // Only making button available if it is an image if (this._activeDoc.type === "image") { @@ -845,7 +725,6 @@ export class MobileInterface extends React.Component { {this.uploadAudioButton()} {/* {this.colorTool()} */} {this.inkMenu()} - {this.displayWorkspaces()} @@ -879,14 +758,6 @@ export class MobileInterface extends React.Component { this.imageUploadActive = false; } - // toggleUpload = () => { - // if (this.imageUploadActive === true) { - // this.imageUploadActive = false; - // } else { - // this.imageUploadActive = true; - // } - // } - uploadImage = () => { if (this.imageUploadActive) { console.log("active"); @@ -905,11 +776,6 @@ export class MobileInterface extends React.Component { } } - - -const inputRef = React.createRef(); - - Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); }); Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); }); Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); }); diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss index da1e9d951..44d3acb6f 100644 --- a/src/mobile/MobileMenu.scss +++ b/src/mobile/MobileMenu.scss @@ -96,7 +96,7 @@ body { } .sidebar { - position: absolute; + position: fixed; top: 120px; opacity: 0; right: -100%; @@ -212,7 +212,7 @@ body { } .pathbar { - position: absolute; + position: fixed; top: 118px; left: 0px; background: #1a1a1a; @@ -373,7 +373,7 @@ body { } .homeSwitch { - position: absolute; + position: fixed; top: 212; right: 36px; display: inline-flex; @@ -401,4 +401,4 @@ body { .list.active { color: darkred; border-color: darkred; -} +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 6d68abf588f7b6182a62b74882d1fdc09b2b0230 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Tue, 16 Jun 2020 09:50:22 -0700 Subject: bug fixes --- .../collectionFreeForm/InkOptionsMenu.tsx | 2 +- src/mobile/MobileInterface.tsx | 30 ++++------------------ src/mobile/MobileMenu.scss | 3 +++ 3 files changed, 9 insertions(+), 26 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index 8bebcd047..e7ef4cbd2 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -107,7 +107,7 @@ export default class InkOptionsMenu extends AntimodeMenu { onPointerDown={action(e => GestureOverlay.Instance.InkShape = btn)} style={{ backgroundColor: btn === GestureOverlay.Instance?.InkShape ? "121212" : "" }}> {this._icons[i]} - )}, + )} ; } diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 25dc9fd55..5d361f3ab 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -78,6 +78,11 @@ export class MobileInterface extends React.Component { 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(); @@ -94,31 +99,6 @@ export class MobileInterface extends React.Component { this.renderView = renderView; } - onSwitchUpload = async () => { - let width = 300; - let height = 300; - const res = await rp.get(Utils.prepend("/getUserDocumentId")); - - // get width and height of the collection doc - if (this.mainContainer) { - const data = Cast(this.mainContainer.data, listSpec(Doc)); - if (data) { - const collectionDoc = await data[1]; // this should be the collection doc since the positions should be locked - const docView = DocumentManager.Instance.getDocumentView(collectionDoc); - if (docView) { - width = docView.nativeWidth ? docView.nativeWidth : 300; - height = docView.nativeHeight ? docView.nativeHeight : 300; - } - } - } - DocServer.Mobile.dispatchOverlayTrigger({ - enableOverlay: true, - width: width, - height: height, - text: "Documents uploaded from mobile will show here", - }); - } - // For toggling the hamburger menu @action toggleSidebar = () => this.sidebarActive = !this.sidebarActive diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss index 8d996f779..cd531056e 100644 --- a/src/mobile/MobileMenu.scss +++ b/src/mobile/MobileMenu.scss @@ -20,6 +20,7 @@ body { height: $navbar-height; background-color: whitesmoke; border-bottom: 5px solid black; + z-index: 150; } .navbar .cover { @@ -192,8 +193,10 @@ body { .sidebar.active { + position: absolute; right: 0%; opacity: 1; + z-index: 101; } .back { -- cgit v1.2.3-70-g09d2 From 57d4c562b6f0ef39dcd68f2985a56c4a683fcf49 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Thu, 18 Jun 2020 04:38:08 +0800 Subject: pdf changes + radial menu + create new workspaces (bug with ink) --- src/client/views/GestureOverlay.tsx | 8 --- .../views/collections/CollectionStackingView.tsx | 2 +- .../collectionFreeForm/InkOptionsMenu.tsx | 4 +- src/client/views/nodes/DocumentView.tsx | 12 ++-- src/client/views/nodes/PDFBox.scss | 2 +- src/client/views/nodes/PDFBox.tsx | 7 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- src/client/views/pdf/PDFViewer.tsx | 4 +- src/mobile/ImageUpload.tsx | 6 +- src/mobile/MobileInterface.tsx | 80 +++++++++++++++++++--- src/server/ApiManagers/PDFManager.ts | 3 +- 11 files changed, 94 insertions(+), 36 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index e51e2d4e1..1c305ebeb 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -575,14 +575,6 @@ export default class GestureOverlay extends Touchable { const points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top })); //push first points to so interactionUtil knows pointer is up this._points.push({ X: this._points[0].X, Y: this._points[0].Y }); - if (MobileInterface.Instance && MobileInterface.Instance.drawingInk) { - DocServer.Mobile.dispatchGesturePoints({ - points: this._points, - bounds: B, - color: ActiveInkColor(), - width: ActiveInkWidth() - }); - } const initialPoint = this._points[0.]; const xInGlass = initialPoint.X > (this._thumbX ?? Number.MAX_SAFE_INTEGER) && initialPoint.X < (this._thumbX ?? Number.MAX_SAFE_INTEGER) + (this.height); diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 797aabf18..9f1b5d63c 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -476,7 +476,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) transformOrigin: "top left", }} onScroll={action(e => { - if (!this.props.isSelected() && this.props.renderDepth && window.innerWidth > 1000) e.currentTarget.scrollTop = this._scroll; + if (!this.props.isSelected() && this.props.renderDepth && window.screen.width > 600) e.currentTarget.scrollTop = this._scroll; else this._scroll = e.currentTarget.scrollTop; })} onDrop={this.onExternalDrop.bind(this)} diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index 647847b68..676dc10f4 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -130,13 +130,13 @@ export default class InkOptionsMenu extends AntimodeMenu { ]; const mobileButtons = [ - this.shapeButtons, + ...this.shapeButtons, this.bezierButton, this.widthPicker, this.colorPicker, ]; - return (window.innerWidth < 1000 ? this.getElement(mobileButtons) : this.getElement(buttons)); + return (window.screen.width < 600 ? this.getElement(mobileButtons) : this.getElement(buttons)); } } Scripting.addGlobal(function activatePen(penBtn: any) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 75627607b..e027b6a0f 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -31,7 +31,7 @@ import { SelectionManager } from "../../util/SelectionManager"; import SharingManager from '../../util/SharingManager'; import { Transform } from "../../util/Transform"; import { undoBatch, UndoManager } from "../../util/UndoManager"; -import { CollectionDockingView } from "../collections/CollectionDockingView"; +import { CollectionDockingView, DockedFrameRenderer } from "../collections/CollectionDockingView"; import { CollectionView, CollectionViewType } from '../collections/CollectionView'; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from '../ContextMenuItem'; @@ -43,6 +43,7 @@ import "./DocumentView.scss"; import { LinkAnchorBox } from './LinkAnchorBox'; import { RadialMenu } from './RadialMenu'; import React = require("react"); +import { MobileInterface } from '../../../mobile/MobileInterface'; 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, @@ -181,10 +182,11 @@ export class DocumentView extends DocComponent(Docu const pt = me.touchEvent.touches[me.touchEvent.touches.length - 1]; RadialMenu.Instance.openMenu(pt.pageX - 15, pt.pageY - 15); - RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "map-pin", selected: -1 }); - RadialMenu.Instance.addItem({ description: "Delete this document", event: () => { this.props.ContainingCollectionView?.removeDocument(this.props.Document), RadialMenu.Instance.closeMenu(); }, icon: "layer-group", selected: -1 }); - RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, "onRight"), icon: "trash", selected: -1 }); - RadialMenu.Instance.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.Document), icon: "folder", selected: -1 }); + // RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "map-pin", selected: -1 }); + RadialMenu.Instance.addItem({ description: "Delete", event: () => { this.props.ContainingCollectionView?.removeDocument(this.props.Document), RadialMenu.Instance.closeMenu(); }, icon: "external-link-square-alt", selected: -1 }); + // RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, "onRight"), icon: "trash", selected: -1 }); + RadialMenu.Instance.addItem({ description: "Pin", event: () => DockedFrameRenderer.PinDoc(this.props.Document), icon: "map-pin", selected: -1 }); + RadialMenu.Instance.addItem({ description: "Open", event: () => MobileInterface.Instance.handleClick(this.props.Document), icon: "trash", selected: -1 }); SelectionManager.DeselectAll(); } diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index 474587159..1a31d2916 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -224,7 +224,7 @@ } } -@media only screen and (max-width: 1000px) { +@media only screen and (max-width: 600px) { .pdfBox .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton, .pdfBox-interactive .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 78b7faeee..4b4348d3c 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -215,13 +215,14 @@ export class PDFBox extends ViewBoxAnnotatableComponent 1000)); + console.log("fitWidth ?: " + !(this.props.Document._fitWidth) && (window.screen.width > 600)); console.log("_nativeHeight: " + this.Document._nativeHeight); console.log("%: " + `${100 / this.contentScaling}%`); const classname = "pdfBox" + (this.active() ? "-interactive" : ""); return
1000) ? this.Document._nativeHeight || 0 : `${100 / this.contentScaling}%`, //Adjusted for mobile (!window.innerWidth < 1000) + //height adjusted for mobile (window.screen.width > 600) + height: !this.props.Document._fitWidth && (window.screen.width > 600) ? this.Document._nativeHeight || 0 : `${100 / this.contentScaling}%`, transform: `scale(${this.contentScaling})` }} >
@@ -233,7 +234,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent this._isChildActive; @computed get renderPdfView() { const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); - return
1000) ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}> + return
600) ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}> { - if (window.innerWidth < 1000) null; + if (window.screen.width < 600) null; else if (this._editorView && (this._editorView as any).docView) { const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight); const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true }); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 9cdbea2da..57b7bceca 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -709,8 +709,8 @@ export class PDFViewer extends ViewBoxAnnotatableComponent 1000) ? NumCast(this.props.Document._nativeWidth) : `${100 / this.contentScaling}%`, - height: !this.props.Document._fitWidth && (window.innerWidth > 1000) ? NumCast(this.props.Document._nativeHeight) : `${100 / this.contentScaling}%`, + width: !this.props.Document._fitWidth && (window.screen.width > 600) ? NumCast(this.props.Document._nativeWidth) : `${100 / this.contentScaling}%`, + height: !this.props.Document._fitWidth && (window.screen.width > 600) ? NumCast(this.props.Document._nativeHeight) : `${100 / this.contentScaling}%`, transform: `scale(${this.props.ContentScaling()})` }} > {this.pdfViewerDiv} diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx index d8b1913ee..b66f0461d 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -65,8 +65,11 @@ export class Uploader extends React.Component { } 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 }); } @@ -175,7 +178,7 @@ export class Uploader extends React.Component { private get uploadInterface() { return (
- +
@@ -217,4 +220,3 @@ export class Uploader extends React.Component { } -// DocServer.init(window.location.protocol, window.location.hostname, 4321, "image upload"); diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 5acdc1dea..644535179 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, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus, + faTasks, 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, @@ -17,7 +17,7 @@ import { FieldValue, Cast } from '../fields/Types'; import { CurrentUserUtils } from '../client/util/CurrentUserUtils'; import { emptyPath, emptyFunction, returnFalse, returnOne, returnTrue, returnZero, Utils } from '../Utils'; import { DocServer } from '../client/DocServer'; -import { Docs } from '../client/documents/Documents'; +import { Docs, DocumentOptions } from '../client/documents/Documents'; import { Scripting } from '../client/util/Scripting'; import { DocumentView } from '../client/views/nodes/DocumentView'; import { Transform } from '../client/util/Transform'; @@ -36,8 +36,11 @@ import GestureOverlay from "../client/views/GestureOverlay"; import { ScriptField } from "../fields/ScriptField"; import InkOptionsMenu from "../client/views/collections/collectionFreeForm/InkOptionsMenu"; import { RadialMenu } from "../client/views/nodes/RadialMenu"; +import { UndoManager } from "../client/util/UndoManager"; +import { MainView } from "../client/views/MainView"; +import { List } from "../fields/List"; -library.add(faTasks, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus, +library.add(faTasks, 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, @@ -149,7 +152,7 @@ export class MobileInterface extends React.Component { * Return 'Home", which implies returning to 'Home' buttons */ returnHome = () => { - if (this._homeMenu === false || this.sidebarActive === true) { + if (this._homeMenu || this.sidebarActive) { this._homeMenu = true; this._parents = []; this._activeDoc = this._homeDoc; @@ -220,7 +223,7 @@ export class MobileInterface extends React.Component { */ handleClick = async (doc: Doc) => { const children = DocListCast(doc.data); - if (doc.type !== "collection") { + if (doc.type !== "collection" && this.sidebarActive) { this._parents.push(this._activeDoc); this._activeDoc = doc; this.switchCurrentView((userDoc: Doc) => doc); @@ -333,7 +336,7 @@ export class MobileInterface extends React.Component { // Renders the contents of the menu and sidebar renderDefaultContent = () => { - if (this._homeMenu === true) { + if (this._homeMenu) { return (
@@ -351,7 +354,7 @@ export class MobileInterface extends React.Component {
ScriptField.MakeScript("createNewWorkspace()")}>Create New Workspace + onClick={() => MainView.Instance?.createNewWorkspace()}>Create New Workspace
@@ -403,7 +406,10 @@ export class MobileInterface extends React.Component { {buttons}
ScriptField.MakeScript("createNewWorkspace()")}>Create New Workspace + style={{ opacity: 0.7 }} + onClick={() => this.createNewWorkspace()}> + +
Create New Workspace
} @@ -413,6 +419,32 @@ export class MobileInterface extends React.Component { ); } + /** + * Handles the Create New Workspace button in the menu + */ + @action + createNewWorkspace = async (id?: string) => { + const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc; + const workspaceCount = DocListCast(workspaces.data).length + 1; + const freeformOptions: DocumentOptions = { + x: 0, + y: 400, + title: "Collection " + workspaceCount, + _LODdisable: true + }; + const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); + const workspaceDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().myCatalog as Doc] }], { title: `Workspace ${workspaceCount}` }, id, "row"); + + const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`); + const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); + const cloneWorkspace = ScriptField.MakeScript(`cloneWorkspace()`); + workspaceDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, cloneWorkspace!]); + workspaceDoc.contextMenuLabels = new List(["Toggle Theme Colors", "Toggle Comic Mode", "New Workspace Layout"]); + + Doc.AddDocToList(workspaces, "data", workspaceDoc); + // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container) + } + stop = (e: React.MouseEvent) => { e.stopPropagation(); } @@ -431,7 +463,7 @@ export class MobileInterface extends React.Component { } } - // Button for switching between pan and ink mode + // Button for switching between pen and ink mode @action onSwitchInking = () => { const button = document.getElementById("inkButton") as HTMLElement; @@ -465,6 +497,16 @@ export class MobileInterface extends React.Component { if (this._activeDoc._viewType === "docking") { return ( <> + {/*
{ + UndoManager.Undo(); + e.stopPropagation(); + }}> + +
*/}
+ {/*
{ + UndoManager.Redo(); + e.stopPropagation(); + }}> + +
*/} ); } } @@ -645,6 +697,12 @@ export class MobileInterface extends React.Component { ); } + displayRadialMenu = () => { + if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) { + return ; + } + } + onDragOver = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); @@ -669,12 +727,14 @@ export class MobileInterface extends React.Component { {this.displayWorkspaces()} {this.renderDefaultContent()} - + {this.displayRadialMenu()}
); } } + + Scripting.addGlobal(function switchMobileView(doc: (userDoc: Doc) => Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); }); Scripting.addGlobal(function openMobilePresentation() { return MobileInterface.Instance.setupDefaultPresentation(); }); Scripting.addGlobal(function toggleMobileSidebar() { return MobileInterface.Instance.toggleSidebar(); }); diff --git a/src/server/ApiManagers/PDFManager.ts b/src/server/ApiManagers/PDFManager.ts index d2a9e9cce..b0b5a484a 100644 --- a/src/server/ApiManagers/PDFManager.ts +++ b/src/server/ApiManagers/PDFManager.ts @@ -55,7 +55,8 @@ async function CreateThumbnail(coreFilename: string, pageNum: number, res: expre const documentProxy = await Pdfjs.getDocument(sourcePath).promise; const factory = new NodeCanvasFactory(); const page = await documentProxy.getPage(pageNum); - const viewport = page.getViewport(1 as any); + const scale = 1; + const viewport = page.getViewport(scale as any); const { canvas, context } = factory.create(viewport.width, viewport.height); const renderContext = { canvasContext: context, -- cgit v1.2.3-70-g09d2 From 738a56b3c18c06d8290346373eb60a125120caaf Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Thu, 18 Jun 2020 15:02:50 -0700 Subject: hopefully fixed new ink --- src/client/util/InteractionUtils.tsx | 4 +- src/client/views/InkingStroke.tsx | 4 +- .../views/collections/CollectionDockingView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 4 +- .../views/collections/CollectionViewChromes.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 6 +-- src/client/views/nodes/DocumentView.tsx | 44 +++++++++++----------- src/mobile/MobileInterface.tsx | 16 +++++--- src/pen-gestures/ndollar.ts | 2 +- 9 files changed, 44 insertions(+), 40 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index aeb0f670d..3b42fcaee 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -96,9 +96,9 @@ export namespace InteractionUtils { } else if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y === points[0].Y) { //pointer is up (first and last points are the same) - points.pop(); + //points.pop(); const newPoints = points.reduce((p, pts) => { p.push([pts.X, pts.Y]); return p; }, [] as number[][]); - + newPoints.pop(); const bezierCurves = fitCurve(newPoints, parseInt(bezier)); for (var i = 0; i < bezierCurves.length; i++) { for (var t = 0; t < 1; t += 0.01) { diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 7e3bd1c17..5129ef65d 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -68,8 +68,8 @@ export class InkingStroke extends ViewBoxBaseComponent { - ContextMenu.Instance.addItem({ description: "Analyze Stroke", event: this.analyzeStrokes, icon: "paint-brush" }); - ContextMenu.Instance.addItem({ description: "Make Mask", event: this.makeMask, icon: "paint-brush" }); + ContextMenu.Instance?.addItem({ description: "Analyze Stroke", event: this.analyzeStrokes, icon: "paint-brush" }); + ContextMenu.Instance?.addItem({ description: "Make Mask", event: this.makeMask, icon: "paint-brush" }); }} > diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index c2e297f61..657e2a08b 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -790,7 +790,7 @@ export class DockedFrameRenderer extends React.Component { if (this._mainCont && this._mainCont.children) { const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont.children[0].firstChild as HTMLElement); const scale = Utils.GetScreenTransform(this._mainCont).scale; - return CollectionDockingView.Instance.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.contentScaling() / scale); + return CollectionDockingView.Instance?.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.contentScaling() / scale); } return Transform.Identity(); } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index a700d0dfb..0a84e6f72 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -283,10 +283,10 @@ export class CollectionView extends Touchable ImageUtils.ExportHierarchyToFileSystem(this.props.Document) }); - !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); + !more && ContextMenu.Instance?.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); } } } diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 48810f1e9..ec908f034 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -300,7 +300,7 @@ export class CollectionViewBaseChrome extends React.Component { if (this.props.annotationsKey) return; - ContextMenu.Instance.addItem({ + ContextMenu.Instance?.addItem({ description: (this._timelineVisible ? "Close" : "Open") + " Animation Timeline", event: action(() => { this._timelineVisible = !this._timelineVisible; }), icon: this._timelineVisible ? faEyeSlash : faEye }); - const options = ContextMenu.Instance.findByDescription("Options..."); + const options = ContextMenu.Instance?.findByDescription("Options..."); const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; optionItems.push({ description: "reset view", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" }); @@ -1246,7 +1246,7 @@ export class CollectionFreeFormView extends CollectionSubView this.Document._LODdisable = !this.Document._LODdisable, icon: "table" }); - ContextMenu.Instance.addItem({ description: "Options...", subitems: optionItems, icon: "eye" }); + ContextMenu.Instance?.addItem({ description: "Options...", subitems: optionItems, icon: "eye" }); } @observable _timelineVisible = false; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e027b6a0f..2f868d558 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -708,40 +708,40 @@ export class DocumentView extends DocComponent(Docu onContextMenu = async (e: React.MouseEvent | Touch): Promise => { // the touch onContextMenu is button 0, the pointer onContextMenu is button 2 if (!(e instanceof Touch)) { - if (e.button === 0 && !e.ctrlKey) { - e.preventDefault(); + if (e?.button === 0 && !e.ctrlKey) { + e?.preventDefault(); return; } - e.persist(); + e?.persist(); e?.stopPropagation(); - if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3 || - e.isDefaultPrevented()) { - e.preventDefault(); + if (Math.abs(this._downX - e?.clientX) > 3 || Math.abs(this._downY - e?.clientY) > 3 || + e?.isDefaultPrevented()) { + e?.preventDefault(); return; } - e.preventDefault(); + e?.preventDefault(); } const cm = ContextMenu.Instance; const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []); Cast(this.props.Document.contextMenuLabels, listSpec("string"), []).forEach((label, i) => - cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); + cm?.addItem({ description: label, event: () => customScripts[i]?.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); this.props.contextMenuItems?.().forEach(item => - cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); + cm?.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); - let options = cm.findByDescription("Options..."); + let options = cm?.findByDescription("Options..."); const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null); optionItems.push({ description: "Open Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" }); 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); + cm?.addItem(options); } - const existingOnClick = cm.findByDescription("OnClick..."); + const existingOnClick = cm?.findByDescription("OnClick..."); const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" }); onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.props.Document.layoutKey}")`), icon: "window-restore" }); @@ -750,17 +750,17 @@ export class DocumentView extends DocComponent(Docu onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link on Right", event: this.toggleFollowOnRight, icon: "concierge-bell" }); onClicks.push({ description: this.Document.isLinkButton || this.Document.onClick ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" }); onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" }); - !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); + !existingOnClick && cm?.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); const funcs: ContextMenuProps[] = []; if (this.Document.onDragStart) { funcs.push({ description: "Drag an Alias", icon: "edit", event: () => this.Document.dragFactory && (this.Document.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) }); funcs.push({ description: "Drag a Copy", icon: "edit", event: () => this.Document.dragFactory && (this.Document.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) }); funcs.push({ description: "Drag Document", icon: "edit", event: () => this.Document.onDragStart = undefined }); - cm.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" }); + cm?.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" }); } - const more = cm.findByDescription("More..."); + const more = cm?.findByDescription("More..."); const moreItems = more && "subitems" in more ? more.subitems : []; if (!Doc.UserDoc().noviceMode) { moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); @@ -789,26 +789,26 @@ export class DocumentView extends DocComponent(Docu moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" }); moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "external-link-alt" }); - !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); - cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!); + !more && cm?.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); + cm?.moveAfter(cm?.findByDescription("More...")!, cm?.findByDescription("OnClick...")!); - const help = cm.findByDescription("Help..."); + const help = cm?.findByDescription("Help..."); const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : []; helpItems.push({ description: "Keyboard Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument("http://localhost:1050/assets/cheat-sheet.pdf", { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" }); - cm.addItem({ description: "Help...", subitems: helpItems, icon: "question" }); + cm?.addItem({ description: "Help...", subitems: helpItems, icon: "question" }); - const existingAcls = cm.findByDescription("Privacy..."); + const existingAcls = cm?.findByDescription("Privacy..."); const aclItems: ContextMenuProps[] = existingAcls && "subitems" in existingAcls ? existingAcls.subitems : []; aclItems.push({ description: "Make Add Only", event: () => this.setAcl("addOnly"), icon: "concierge-bell" }); aclItems.push({ description: "Make Read Only", event: () => this.setAcl("readOnly"), icon: "concierge-bell" }); aclItems.push({ description: "Make Private", event: () => this.setAcl("ownerOnly"), icon: "concierge-bell" }); aclItems.push({ description: "Test Private", event: () => this.testAcl("ownerOnly"), icon: "concierge-bell" }); aclItems.push({ description: "Test Readonly", event: () => this.testAcl("readOnly"), icon: "concierge-bell" }); - !existingAcls && cm.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" }); + !existingAcls && cm?.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" }); // const recommender_subitems: ContextMenuProps[] = []; @@ -869,7 +869,7 @@ export class DocumentView extends DocComponent(Docu // DocumentViews should stop propagation of this event e.stopPropagation(); } - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); + ContextMenu.Instance?.displayMenu(e.pageX - 15, e.pageY - 15); !SelectionManager.IsSelected(this, true) && SelectionManager.SelectDoc(this, false); }); const path = this.props.LibraryPath.reduce((p: string, d: Doc) => p + "/" + (Doc.AreProtosEqual(d, (Doc.UserDoc()["tabs-button-library"] as Doc).sourcePanel as Doc) ? "" : d.title), ""); diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 4000bee85..3a81e5de1 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -708,6 +708,10 @@ export class MobileInterface extends React.Component { e.stopPropagation(); } + uploadToCurrentCollection = (doc: Doc) => { + + } + render() { return (
@@ -717,13 +721,13 @@ export class MobileInterface extends React.Component {
{this.switchMenuView()} {this.inkMenu()} +
+ {this.pinToPresentation()} + {this.downloadDocument()} + {this.drawInk()} + {this.uploadAudioButton()} +
-
- {this.pinToPresentation()} - {this.downloadDocument()} - {this.drawInk()} - {this.uploadAudioButton()} -
{this.displayWorkspaces()} {this.renderDefaultContent()}
diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts index 9d42035d1..ecd8df3e7 100644 --- a/src/pen-gestures/ndollar.ts +++ b/src/pen-gestures/ndollar.ts @@ -552,7 +552,7 @@ function Distance(p1: any, p2: any) // distance between two points } function CalcStartUnitVector(points: any, index: any) // start angle from points[0] to points[index] normalized as a unit vector { - const v = new Point(points[index].X - points[0].X, points[index].Y - points[0].Y); + const v = new Point(points[index]?.X - points[0]?.X, points[index]?.Y - points[0]?.Y); const len = Math.sqrt(v.X * v.X + v.Y * v.Y); return new Point(v.X / len, v.Y / len); } -- cgit v1.2.3-70-g09d2 From 790d41009a678f560cd3b78e86069251e494cfd1 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Mon, 22 Jun 2020 14:55:00 +0800 Subject: updated css width property for mobile --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/util/SettingsManager.scss | 2 +- src/client/views/AntimodeMenu.scss | 16 ++-- .../views/collections/CollectionStackingView.scss | 2 +- .../views/collections/CollectionViewChromes.scss | 2 +- .../collectionFreeForm/InkOptionsMenu.scss | 18 ++-- src/client/views/nodes/AudioBox.scss | 2 +- src/client/views/nodes/PDFBox.scss | 2 +- src/client/views/nodes/PresBox.scss | 2 +- .../views/presentationview/PresElementBox.scss | 2 +- src/mobile/AudioUpload.scss | 95 ---------------------- src/mobile/MobileInterface.tsx | 10 +-- src/mobile/MobileMenu.scss | 24 ++++-- 13 files changed, 45 insertions(+), 134 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index b7da4ae2f..5edb2225f 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -465,7 +465,7 @@ export class CurrentUserUtils { static setupMobileButtons(doc?: Doc, buttons?: string[]) { const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [ - { title: "LIBRARY", icon: "bars", click: 'switchToLibrary()', backgroundColor: "#ffd6d6", info: "Navigate and access all of your documents within their respective collections." }, + { title: "WORKSPACES", icon: "folder-open", click: 'openWorkspaces()', backgroundColor: "#ffd6d6", info: "Access your Workspaces from your mobile, and navigate through all of your documents. " }, { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your phone to record and upload audio onto Dash Web." }, { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "#ff9e9e", info: "Upload images or videos from your mobile device so they can be accessed on Dash Web." }, { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." }, diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss index 1eac9303b..0116c5294 100644 --- a/src/client/util/SettingsManager.scss +++ b/src/client/util/SettingsManager.scss @@ -135,7 +135,7 @@ } } -@media only screen and (max-width: 1000px) { +@media only screen and (max-device-width: 480px) { .settings-interface { background-color: whitesmoke !important; color: grey; diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss index 170631422..43f45fb1c 100644 --- a/src/client/views/AntimodeMenu.scss +++ b/src/client/views/AntimodeMenu.scss @@ -41,7 +41,7 @@ } } -@media only screen and (max-width: 1000px) { +@media only screen and (max-device-width: 480px) { .antimodeMenu-cont { position: absolute; z-index: 10000; @@ -51,31 +51,31 @@ border-radius: 0px 6px 6px 6px; // overflow: hidden; display: flex; - + &.with-rows { flex-direction: column-reverse; } - + .antimodeMenu-row { display: flex; height: 100%; - width:100%; + width: 100%; } - + .antimodeMenu-button { background-color: transparent; width: 100px; height: 100px; - + &.active { background-color: #121212; } } - + .antimodeMenu-button:hover { background-color: #121212; } - + .antimodeMenu-dragger { height: 100%; transition: width .2s; diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 98efdfd23..342773db8 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -424,7 +424,7 @@ } } -@media only screen and (max-width: 1000px) { +@media only screen and (max-device-width: 480px) { .collectionStackingView .collectionStackingView-columnDragger, .collectionMasonryView .collectionStackingView-columnDragger { diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss index 54ee4ab3b..ec2d78735 100644 --- a/src/client/views/collections/CollectionViewChromes.scss +++ b/src/client/views/collections/CollectionViewChromes.scss @@ -80,7 +80,7 @@ // margin-top: 10px; } - @media only screen and (max-width: 1000) { + @media only screen and (max-device-width: 480px) { .collectionViewBaseChrome-collapse { display: none; } diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss index 72fdf5af9..4855dfea8 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss @@ -33,39 +33,39 @@ } } -@media only screen and (max-width: 1000px) { +@media only screen and (max-device-width: 480px) { .antimodeMenu-button { .color-preview { width: 100%; height: 100%; } - + } - + .sketch-picker { background: #323232; - + .flexbox-fit { background: #323232; } } - + .btn-group { display: grid; grid-template-columns: auto auto; /* Make the buttons appear below each other */ } - + .btn2-group { display: block; background: #323232; grid-template-columns: auto; - + /* Make the buttons appear below each other */ .antimodeMenu-button { background: #323232; display: block; - + } } -} +} \ No newline at end of file diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index 61ce4bd13..43dd698ad 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -174,7 +174,7 @@ } -@media only screen and (max-width: 1000px) { +@media only screen and (max-device-width: 480px) { .audiobox-container, .audiobox-container-interactive { diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index 1a31d2916..b19ddf1f5 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -224,7 +224,7 @@ } } -@media only screen and (max-width: 600px) { +@media only screen and (max-device-width: 480px) { .pdfBox .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton, .pdfBox-interactive .pdfBox-ui .pdfBox-settingsCont .pdfBox-settingsButton { diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index e62aa48fb..1261cbfdd 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -81,7 +81,7 @@ } } -@media only screen and (max-width: 1000px) { +@media only screen and (max-device-width: 480px) { .presBox-cont .presBox-buttons { position: absolute; top: 70%; diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss index 99fe2a3ba..79532995e 100644 --- a/src/client/views/presentationview/PresElementBox.scss +++ b/src/client/views/presentationview/PresElementBox.scss @@ -106,7 +106,7 @@ z-index: 2; } -@media only screen and (max-width: 1000px) { +@media only screen and (max-device-width: 480px) { .presElementBox-buttons { display: inline-flex; position: relative; diff --git a/src/mobile/AudioUpload.scss b/src/mobile/AudioUpload.scss index 5f0ba465a..9fe442e55 100644 --- a/src/mobile/AudioUpload.scss +++ b/src/mobile/AudioUpload.scss @@ -7,77 +7,6 @@ align-items: center; max-width: 400px; min-width: 400px; - - .upload_label { - font-size: 3em; - font-weight: 700; - color: white; - background-color: black; - display: inline-block; - margin: 10; - width: 100%; - border-radius: 10px; - } - - .file { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - direction: ltr; - } - - .upload_label:hover { - background-color: darkred; - } - - .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-size: 3em; - font-weight: 700; - color: white; - background-color: black; - display: inline-block; - margin: 10px; - width: 100%; - border-radius: 10px; - } - - .inputfile:focus+label, - .inputfile+label:hover { - background-color: darkred; - } - - .status { - font-size: 2em; - } - -} - -.backgroundUpload { - height: 100vh; - top: 0; - z-index: 999; - width: 100vw; - position: absolute; - background-color: lightgrey; - opacity: 0.4; } .audio-upload { @@ -92,28 +21,4 @@ height: 100vh; width: 100vw; opacity: 1; -} - -.uploadContainer { - top: 40; - position: absolute; - z-index: 1000; - height: 20vh; - width: 80vw; - opacity: 1; -} - -.loadingImage { - display: inline-flex; - width: max-content; -} - -.loadingSlab { - position: relative; - width: 30px; - height: 30px; - margin: 10; - border-radius: 20px; - opacity: 0.3; - background-color: black; } \ No newline at end of file diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 84a5975cb..ceda74da2 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -415,7 +415,7 @@ export class MobileInterface extends React.Component { onClick={this.returnMain} style={{ opacity: 0.7 }}> -
Return to library
+
Return to workspaces
: <> @@ -509,7 +509,7 @@ export class MobileInterface extends React.Component { } undo = () => { - if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) { + if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc.title !== "WORKSPACES") { return (<>
{ - if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc) { + if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc.title !== "WORKSPACES") { return (<>
{this.displayWorkspaces()} diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss index 87731655a..53bc48034 100644 --- a/src/mobile/MobileMenu.scss +++ b/src/mobile/MobileMenu.scss @@ -19,7 +19,6 @@ body { width: 100vw; height: $navbar-height; background-color: whitesmoke; - border-bottom: 5px solid black; z-index: 150; } @@ -221,14 +220,17 @@ body { .back { position: absolute; - top: 44%; left: 42px; - background-color: black; + top: 0; + background: #1a1a1a; width: 50px; - height: 50px; + height: 100%; + display: flex; + justify-content: center; text-align: center; + flex-direction: column; + align-items: center; border-radius: 10px; - transform: translate(0, -50%); font-size: 25px; user-select: none; z-index: 100; @@ -243,7 +245,7 @@ body { border-radius: 0px; width: 100%; height: 80px; - transition: all 400ms ease 50ms; + overflow: hidden; } .pathname { @@ -291,14 +293,19 @@ body { .scrollmenu { overflow: auto; + width: 100%; + height: 100%; white-space: nowrap; + display: inline-flex; } .pathbarItem { position: relative; - display: inline-flex; + display: flex; + align-items: center; color: whitesmoke; text-align: center; + justify-content: center; user-select: none; transform: translate(100px, 0px); font-size: 30px; @@ -311,7 +318,6 @@ body { text-align: center; height: 50px; padding: 10px; - background-color: rgb(48, 40, 40); font-size: 30px; border-radius: 10px; text-transform: uppercase; @@ -321,7 +327,7 @@ body { .pathIcon { - transform: translate(0px, 8px); + transform: translate(0px, 0px); position: relative; } -- cgit v1.2.3-70-g09d2 From 6d6475816cebfd9e2921fe817f359c49f22b70d6 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Tue, 23 Jun 2020 13:54:30 +0800 Subject: ink menu UI change --- src/client/views/AntimodeMenu.scss | 1 + src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss index 43f45fb1c..934d819cc 100644 --- a/src/client/views/AntimodeMenu.scss +++ b/src/client/views/AntimodeMenu.scss @@ -46,6 +46,7 @@ position: absolute; z-index: 10000; height: 100px; + width: 100vw; background: #323232; box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25); border-radius: 0px 6px 6px 6px; diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss index 4855dfea8..9ad4d5079 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss @@ -35,6 +35,8 @@ @media only screen and (max-device-width: 480px) { .antimodeMenu-button { + font-size: 50%; + .color-preview { width: 100%; height: 100%; @@ -65,7 +67,7 @@ .antimodeMenu-button { background: #323232; display: block; - + font-size: 50%; } } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From e7372931b9d28c141aaec9552041b5644c2f415a Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Fri, 26 Jun 2020 03:37:08 +0800 Subject: Merge branch 'master' into mobile_revision_direct And changes to UI of record and image upload --- src/client/util/CurrentUserUtils.ts | 12 +- src/client/util/DragManager.ts | 2 +- src/client/views/DocumentButtonBar.tsx | 63 +----- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/GlobalKeyHandler.ts | 2 + src/client/views/MainView.tsx | 11 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 4 +- src/client/views/globalCssVariables.scss | 1 + src/client/views/linking/LinkMenu.scss | 4 + src/client/views/linking/LinkMenu.tsx | 37 +-- src/client/views/nodes/AudioBox.scss | 71 +----- src/client/views/nodes/AudioBox.tsx | 2 +- src/client/views/nodes/DocumentLinksButton.scss | 38 ++++ src/client/views/nodes/DocumentLinksButton.tsx | 104 +++++++++ src/client/views/nodes/DocumentView.tsx | 28 ++- src/client/views/nodes/LinkAnchorBox.tsx | 8 + src/client/views/nodes/LinkDocPreview.tsx | 107 +++++++++ .../views/nodes/formattedText/RichTextMenu.tsx | 9 +- src/mobile/AudioUpload.scss | 41 +++- src/mobile/AudioUpload.tsx | 249 +++++++-------------- src/mobile/ImageUpload.scss | 61 ++--- src/mobile/ImageUpload.tsx | 66 +++--- src/mobile/MobileInterface.tsx | 29 ++- src/mobile/MobileMenu.scss | 1 + 24 files changed, 549 insertions(+), 403 deletions(-) create mode 100644 src/client/views/nodes/DocumentLinksButton.scss create mode 100644 src/client/views/nodes/DocumentLinksButton.tsx create mode 100644 src/client/views/nodes/LinkDocPreview.tsx (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index efdc943fa..823a99436 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -474,12 +474,12 @@ export class CurrentUserUtils { static setupMobileButtons(doc?: Doc, buttons?: string[]) { const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [ - { title: "WORKSPACES", icon: "folder-open", click: 'openWorkspaces()', backgroundColor: "#ffd6d6", info: "Access your Workspaces from your mobile, and navigate through all of your documents. " }, - { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "#ffbfbf", info: "Use your phone to record and upload audio onto Dash Web." }, - { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "#ff9e9e", info: "Upload images or videos from your mobile device so they can be accessed on Dash Web." }, - { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "#ff8080", info: "Use your phone as a remote for you presentation." }, - { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploads()', backgroundColor: "#ff7373", info: "Access the collection of your mobile uploads." }, - { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "#ff5e5e", info: "Change your password, log out, or manage your account security." } + { title: "WORKSPACES", icon: "bars", click: 'openMobileWorkspaces()', backgroundColor: "lightgrey", info: "Access your Workspaces from your mobile, and navigate through all of your documents. " }, + { title: "UPLOAD", icon: "upload", click: 'uploadImageMobile()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." }, + { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploads()', backgroundColor: "lightgrey", info: "Access the collection of your mobile uploads." }, + { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey", info: "Use your phone to record, dictate and then upload audio onto Dash Web." }, + { title: "PRESENTATION", icon: "desktop", click: 'openMobilePresentation()', backgroundColor: "lightgrey", info: "Use your phone as a remote for you presentation." }, + { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "lightgrey", info: "Change your password, log out, or manage your account security." } ]; return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => this.mobileButton({ diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 91bc51101..417ddf989 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -353,7 +353,7 @@ export namespace DragManager { const dragElement = ele.parentNode === dragDiv ? ele : ele.cloneNode(true) as HTMLElement; const rect = ele.getBoundingClientRect(); const scaleX = rect.width / ele.offsetWidth, - scaleY = rect.height / ele.offsetHeight; + scaleY = ele.offsetHeight ? rect.height / ele.offsetHeight : scaleX; elesCont.left = Math.min(rect.left, elesCont.left); elesCont.top = Math.min(rect.top, elesCont.top); elesCont.right = Math.max(rect.right, elesCont.right); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 62a95116f..fcaea0f0b 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -1,28 +1,28 @@ import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faArrowAltCircleDown, faPhotoVideo, faArrowAltCircleUp, faArrowAltCircleRight, faCheckCircle, faCloudUploadAlt, faLink, faShare, faStopCircle, faSyncAlt, faTag, faTimes } from '@fortawesome/free-solid-svg-icons'; +import { faArrowAltCircleDown, faArrowAltCircleRight, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faPhotoVideo, faShare, faStopCircle, faSyncAlt, faTag, faTimes } 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 { Doc, DocListCast } from "../../fields/Doc"; import { RichTextField } from '../../fields/RichTextField'; -import { NumCast, StrCast, Cast } from "../../fields/Types"; +import { Cast, NumCast } from "../../fields/Types"; import { emptyFunction, setupMoveUpEvents } from "../../Utils"; +import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager'; import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils'; +import { Docs, DocUtils } from '../documents/Documents'; +import { DragManager } from '../util/DragManager'; import { UndoManager } from "../util/UndoManager"; import { CollectionDockingView, DockedFrameRenderer } from './collections/CollectionDockingView'; import { ParentDocSelector } from './collections/ParentDocumentSelector'; import './collections/ParentDocumentSelector.scss'; import './DocumentButtonBar.scss'; -import { LinkMenu } from "./linking/LinkMenu"; +import { MetadataEntryMenu } from './MetadataEntryMenu'; import { DocumentView } from './nodes/DocumentView'; import { GoogleRef } from "./nodes/formattedText/FormattedTextBox"; import { TemplateMenu } from "./TemplateMenu"; import { Template, Templates } from "./Templates"; import React = require("react"); -import { DragManager } from '../util/DragManager'; -import { MetadataEntryMenu } from './MetadataEntryMenu'; -import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager'; -import { Docs } from '../documents/Documents'; +import { DocumentLinksButton } from './nodes/DocumentLinksButton'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -113,39 +113,6 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV get view0() { return this.props.views()?.[0]; } - @action - onLinkButtonMoved = (e: PointerEvent) => { - if (this._linkButton.current !== null) { - const linkDrag = UndoManager.StartBatch("Drag Link"); - this.view0 && DragManager.StartLinkDrag(this._linkButton.current, this.view0.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.view0 && 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.view0!._link = linkDoc); - setTimeout(action(() => this.view0!._link = undefined), 0); - } - linkDrag?.end(); - }, - hideSource: false - }); - return true; - } - return false; - } - - - onLinkButtonDown = (e: React.PointerEvent): void => { - setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, emptyFunction); - } - - @computed get considerGoogleDocsPush() { const targetDoc = this.view0?.props.Document; @@ -235,20 +202,6 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
; } - @computed - get linkButton() { - const view0 = this.view0; - const linkCount = view0 && DocListCast(view0.props.Document.links).length; - return !view0 ? (null) :
- }> -
- {linkCount ? linkCount : } -
-
-
; - } - @computed get metadataButton() { const view0 = this.view0; @@ -318,7 +271,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const considerPush = isText && this.considerGoogleDocsPush; return
- {this.linkButton} +
{this.templateButton} diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index beb6155ca..d7b0ab7a9 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -552,7 +552,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> onPointerDown={this.onRadiusDown} onContextMenu={(e) => e.preventDefault()}>
-
+
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 27755737e..7bc8cf6a7 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -19,6 +19,7 @@ import { MarqueeView } from "./collections/collectionFreeForm/MarqueeView"; import { DocumentDecorations } from "./DocumentDecorations"; import { MainView } from "./MainView"; import { DocumentView } from "./nodes/DocumentView"; +import { DocumentLinksButton } from "./nodes/DocumentLinksButton"; const modifiers = ["control", "meta", "shift", "alt"]; type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise; @@ -77,6 +78,7 @@ export default class KeyManager { // MarqueeView.DragMarquee = !MarqueeView.DragMarquee; // bcz: this needs a better disclosure UI break; case "escape": + DocumentLinksButton.StartLink = undefined; const main = MainView.Instance; Doc.SetSelectedTool(InkTool.None); if (main.isPointerDown) { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 97953452d..4e2c067ac 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -5,7 +5,7 @@ import { 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, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, - faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft + faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft, faSortAmountDown } from '@fortawesome/free-solid-svg-icons'; import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -55,6 +55,9 @@ import { TimelineMenu } from './animationtimeline/TimelineMenu'; import { SnappingManager } from '../util/SnappingManager'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { DocumentManager } from '../util/DocumentManager'; +import { DocumentLinksButton } from './nodes/DocumentLinksButton'; +import { LinkMenu } from './linking/LinkMenu'; +import { LinkDocPreview } from './nodes/LinkDocPreview'; @observer export class MainView extends React.Component { @@ -135,7 +138,7 @@ export class MainView extends React.Component { 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, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTrashAlt, faAngleRight, faBell, - faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft); + faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft, faSortAmountDown); this.initEventListeners(); this.initAuthenticationRouters(); } @@ -578,6 +581,10 @@ export class MainView extends React.Component { {this.mainContent} + {DocumentLinksButton.EditLink ? : (null)} + {LinkDocPreview.LinkInfo ? : (null)} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index dc62c48b7..42aa0f58e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -47,6 +47,7 @@ import { Timeline } from "../../animationtimeline/Timeline"; import { SnappingManager } from "../../../util/SnappingManager"; import { ActiveInkColor, ActiveInkWidth, ActiveInkBezierApprox } from "../../InkingStroke"; import { DocumentType } from "../../../documents/DocumentTypes"; +import { DocumentLinksButton } from "../../nodes/DocumentLinksButton"; library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload); @@ -245,7 +246,7 @@ export class CollectionFreeFormView extends CollectionSubView { if (this.layoutDoc.targetScale && (Math.abs(e.pageX - this._downX) < 3 && Math.abs(e.pageY - this._downY) < 3)) { if (Date.now() - this._lastTap < 300) { + runInAction(() => DocumentLinksButton.StartLink = undefined); const docpt = this.getTransform().transformPoint(e.clientX, e.clientY); this.scaleAtPt(docpt, 1); e.stopPropagation(); diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss index 4e85fe0ca..3e54d001b 100644 --- a/src/client/views/globalCssVariables.scss +++ b/src/client/views/globalCssVariables.scss @@ -12,6 +12,7 @@ $lighter-alt-accent: rgb(207, 220, 240); $darker-alt-accent: rgb(178, 206, 248); $intermediate-color: #9c9396; $dark-color: #121721; +$link-color: lightBlue; $antimodemenu-height: 35px; // fonts $sans-serif: "Noto Sans", diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss index 7dee22f66..c372e7098 100644 --- a/src/client/views/linking/LinkMenu.scss +++ b/src/client/views/linking/LinkMenu.scss @@ -8,6 +8,10 @@ .linkMenu-list { max-height: 200px; overflow-y: scroll; + position: absolute; + z-index: 10; + background: $link-color; + min-width: 150px } .linkMenu-group { diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index 56f40ad69..0fcc0f0b9 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -4,11 +4,12 @@ import { DocumentView } from "../nodes/DocumentView"; import { LinkEditor } from "./LinkEditor"; import './LinkMenu.scss'; import React = require("react"); -import { Doc } from "../../../fields/Doc"; +import { Doc, Opt } from "../../../fields/Doc"; import { LinkManager } from "../../util/LinkManager"; import { LinkMenuGroup } from "./LinkMenuGroup"; import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { library } from "@fortawesome/fontawesome-svg-core"; +import { DocumentLinksButton } from "../nodes/DocumentLinksButton"; library.add(faTrash); @@ -16,16 +17,29 @@ interface Props { docView: DocumentView; changeFlyout: () => void; addDocTab: (document: Doc, where: string) => boolean; + location: number[]; } @observer export class LinkMenu extends React.Component { @observable private _editingLink?: Doc; + @observable private _linkMenuRef: Opt; + @action + onClick = (e: PointerEvent) => { + if (!Array.from(this._linkMenuRef?.getElementsByTagName((e.target as HTMLElement).tagName) || []).includes(e.target as any)) { + DocumentLinksButton.EditLink = undefined; + } + } @action componentDidMount() { this._editingLink = undefined; + document.addEventListener("pointerdown", this.onClick); + } + + componentWillUnmount() { + document.removeEventListener("pointerdown", this.onClick); } clearAllLinks = () => { @@ -56,20 +70,11 @@ export class LinkMenu extends React.Component { render() { const sourceDoc = this.props.docView.props.Document; const groups: Map = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc); - if (this._editingLink === undefined) { - return ( -
- {/* */} - {/* */} -
- {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 From 992a65ec6f828dda0adcd3cd121896f07f64af87 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Mon, 29 Jun 2020 14:21:57 -0700 Subject: minor fixes --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 6 +++--- src/mobile/MobileInterface.tsx | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 42aa0f58e..a068e391e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1214,7 +1214,7 @@ export class CollectionFreeFormView extends CollectionSubView this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" }); appearanceItems.push({ description: `${this.Document.useClusters ? "Uncluster" : "Use Clusters"}`, event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" }); appearanceItems.push({ description: "Use Background Color as Default", event: () => Cast(Doc.UserDoc().emptyCollection, Doc, null)._backgroundColor = StrCast(this.layoutDoc._backgroundColor), icon: "palette" }); - !appearance && ContextMenu.Instance.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" }); + !appearance && ContextMenu.Instance?.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" }); const options = ContextMenu.Instance?.findByDescription("Options..."); const optionItems = options && "subitems" in options ? options.subitems : []; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index afd28534e..0f46be345 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -749,7 +749,7 @@ export class DocumentView extends DocComponent(Docu 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" }); 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" }); + !options && cm?.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); const existingOnClick = cm?.findByDescription("OnClick..."); const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; @@ -767,7 +767,7 @@ export class DocumentView extends DocComponent(Docu funcs.push({ description: "Drag an Alias", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) }); funcs.push({ description: "Drag a Copy", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) }); funcs.push({ description: "Drag Document", icon: "edit", event: () => this.layoutDoc.onDragStart = undefined }); - cm.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" }); + cm?.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" }); } const more = cm?.findByDescription("More..."); @@ -806,7 +806,7 @@ export class DocumentView extends DocComponent(Docu const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : []; helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument("http://localhost:1050/assets/cheat-sheet.pdf", { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" }); helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" }); - cm.addItem({ description: "Help...", subitems: helpItems, icon: "question" }); + cm?.addItem({ description: "Help...", subitems: helpItems, icon: "question" }); const existingAcls = cm?.findByDescription("Privacy..."); const aclItems: ContextMenuProps[] = existingAcls && "subitems" in existingAcls ? existingAcls.subitems : []; diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index e39349ff2..8cec03897 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -518,7 +518,6 @@ export class MobileInterface extends React.Component { inkMenu = () => { if (this._activeDoc._viewType === "docking") { if (this._ink) { - console.log("here"); return
; -- cgit v1.2.3-70-g09d2 From 56da30314c4d434c4b7bb8be94f3bcb5923790d8 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Mon, 29 Jun 2020 18:05:46 -0700 Subject: minor changes --- .../collectionFreeForm/InkOptionsMenu.tsx | 5 ++- src/mobile/MobileInterface.tsx | 37 +++++++++++++--------- 2 files changed, 26 insertions(+), 16 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index e5b7023a1..218cef183 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -320,10 +320,13 @@ export default class InkOptionsMenu extends AntimodeMenu { ]; const mobileButtons = [ - ...this.shapeButtons, + this.shapePicker, this.bezierButton, this.widthPicker, this.colorPicker, + this.fillPicker, + this.arrowPicker, + this.dashButton, ]; return (window.screen.width < 600 ? this.getElement(mobileButtons) : this.getElement(buttons)); diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index a49bfb9b1..cb7319e03 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -56,6 +56,8 @@ export class MobileInterface extends React.Component { @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 inkButton: boolean = false; + @observable private undoButton: boolean = false; public _activeDoc: Doc = this.mainDoc; // doc updated as the active mobile page is updated (initially home menu) public _homeDoc: Doc = this.mainDoc; // home menu as a document @@ -107,6 +109,10 @@ export class MobileInterface extends React.Component { this.renderView = renderView; // Ensures that switching to home is not registed UndoManager.undoStack.length = 0; + + if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") { + this.undoButton = true; + } } // For toggling the hamburger menu @@ -445,7 +451,7 @@ export class MobileInterface extends React.Component { const freeformOptions: DocumentOptions = { x: 0, y: 400, - title: "Collection " + workspaceCount + title: "Collection " + workspaceCount, }; const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); const workspaceDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().myCatalog as Doc] }], { title: `Workspace ${workspaceCount}` }, id, "row"); @@ -493,19 +499,21 @@ export class MobileInterface extends React.Component { // DocButton that uses UndoManager and handles the opacity change if CanUndo is true @computed get undo() { - if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") { - return (<> -
{ - UndoManager.Undo(); - e.stopPropagation(); - }}> - -
- ); + if (this.mainContainer) { + if (this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc && this._activeDoc !== this.userDoc.rightSidebarCollection && this._activeDoc.title !== "WORKSPACES") { + return (<> +
{ + UndoManager.Undo(); + e.stopPropagation(); + }}> + +
+ ); + } } } @@ -704,7 +712,6 @@ export class MobileInterface extends React.Component { } onDragOver = (e: React.DragEvent) => { - console.log("drag!"); e.preventDefault(); e.stopPropagation(); } -- cgit v1.2.3-70-g09d2 From 917098c107052f825e0f9b96bdb0706371862b90 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Mon, 29 Jun 2020 23:14:41 -0700 Subject: ink fixes --- .../views/collections/collectionFreeForm/InkOptionsMenu.tsx | 13 +------------ src/client/views/nodes/DocumentView.tsx | 1 + src/mobile/MobileInterface.scss | 5 +++-- src/mobile/MobileInterface.tsx | 8 +++++++- 4 files changed, 12 insertions(+), 15 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index 218cef183..f47fca6ac 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -318,18 +318,7 @@ export default class InkOptionsMenu extends AntimodeMenu { this.arrowPicker, this.dashButton, ]; - - const mobileButtons = [ - this.shapePicker, - this.bezierButton, - this.widthPicker, - this.colorPicker, - this.fillPicker, - this.arrowPicker, - this.dashButton, - ]; - - return (window.screen.width < 600 ? this.getElement(mobileButtons) : this.getElement(buttons)); + return this.getElement(buttons); } } Scripting.addGlobal(function activatePen(penBtn: any) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 3b785a200..0ec676379 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 { DocumentLinksButton } from './DocumentLinksButton'; +import { MobileInterface } from '../../../mobile/MobileInterface'; 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, diff --git a/src/mobile/MobileInterface.scss b/src/mobile/MobileInterface.scss index ee39d4f50..4b32c3da0 100644 --- a/src/mobile/MobileInterface.scss +++ b/src/mobile/MobileInterface.scss @@ -401,14 +401,15 @@ body { .colorSelector { position: absolute; top: 550px; - left: 300px; + left: 280px; transform: translate(-50%, 0); z-index: 100; display: inline-flex; width: max-content; height: max-content; pointer-events: all; - font-size: 90px; + font-size: 80px; + user-select: none; } // Menu buttons for toggling between list and icon view diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 7ff82ccc4..54461c4cc 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -107,12 +107,18 @@ export class MobileInterface extends React.Component { this.renderView = renderView; // 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 + toggleSidebar = () => { + this.sidebarActive = !this.sidebarActive; + if (this._ink) { + this.onSwitchInking(); + } + } /** * Method called when 'Library' button is pressed on the home screen */ -- cgit v1.2.3-70-g09d2 From 1daf0a496175267d86f495bb24aa5140b6a9eeab Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 2 Jul 2020 14:05:33 -0400 Subject: small clanup in Mobile related code --- src/client/views/GestureOverlay.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 21 ++++++++-------- .../collectionFreeForm/CollectionFreeFormView.tsx | 11 ++++---- src/client/views/nodes/DocumentView.tsx | 29 +++++++++++----------- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 5 files changed, 33 insertions(+), 32 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 839ab09c7..487467b2b 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -264,7 +264,7 @@ export default class GestureOverlay extends Touchable { handleHandDown = async (e: React.TouchEvent) => { this._holdTimer && clearTimeout(this._holdTimer); - // this chunk of code helps us keep track of which touch events ar e associated with a hand event + // this chunk of code helps us keep track of which touch events are associated with a hand event // so that if a hand is held down, but a second hand is interacting with dash, the second hand's events // won't interfere with the first hand's events. const fingers = new Array(); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 35196b634..300309882 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -231,12 +231,12 @@ export class CollectionView extends Touchable Doc, addExtras: boolean) { - const existingVm = ContextMenu.Instance?.findByDescription(category); + const existingVm = ContextMenu.Instance.findByDescription(category); const subItems = existingVm && "subitems" in existingVm ? existingVm.subitems : []; subItems.push({ description: "Freeform", event: () => func(CollectionViewType.Freeform), icon: "signature" }); if (addExtras && CollectionView._safeMode) { - ContextMenu.Instance?.addItem({ description: "Test Freeform", event: () => func(CollectionViewType.Invalid), icon: "project-diagram" }); + ContextMenu.Instance.addItem({ description: "Test Freeform", event: () => func(CollectionViewType.Invalid), icon: "project-diagram" }); } subItems.push({ description: "Schema", event: () => func(CollectionViewType.Schema), icon: "th-list" }); subItems.push({ description: "Tree", event: () => func(CollectionViewType.Tree), icon: "tree" }); @@ -255,11 +255,12 @@ export class CollectionView extends Touchable this._isLightboxOpen = true), icon: "eye" }); - !existingVm && ContextMenu.Instance?.addItem({ description: category, subitems: subItems, icon: "eye" }); + !existingVm && ContextMenu.Instance.addItem({ description: category, subitems: subItems, icon: "eye" }); } onContextMenu = (e: React.MouseEvent): void => { - if (!e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 + const cm = ContextMenu.Instance; + if (cm && !e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 this.setupViewTypes("Add a Perspective...", vtype => { const newRendition = Doc.MakeAlias(this.props.Document); newRendition._viewType = vtype; @@ -267,7 +268,7 @@ export class CollectionView extends Touchable this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }); if (this.props.Document.childLayout instanceof Doc) { @@ -278,9 +279,9 @@ export class CollectionView extends Touchable this.props.Document.isInPlaceContainer = !this.props.Document.isInPlaceContainer, icon: "project-diagram" }); - !existing && ContextMenu.Instance?.addItem({ description: "Options...", subitems: layoutItems, icon: "hand-point-right" }); + !existing && cm.addItem({ description: "Options...", subitems: layoutItems, icon: "hand-point-right" }); - const existingOnClick = ContextMenu.Instance?.findByDescription("OnClick..."); + const existingOnClick = cm.findByDescription("OnClick..."); const onClicks = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; const funcs = [ { key: "onChildClick", name: "On Child Clicked" }, @@ -296,13 +297,13 @@ export class CollectionView extends Touchable this.props.Document[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data)), })); - !existingOnClick && ContextMenu.Instance?.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); + !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); if (!Doc.UserDoc().noviceMode) { - const more = ContextMenu.Instance?.findByDescription("More..."); + const more = cm.findByDescription("More..."); const moreItems = more && "subitems" in more ? more.subitems : []; moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) }); - !more && ContextMenu.Instance?.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); + !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); } } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index ae7213d0b..21b0473c9 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -602,7 +602,6 @@ export class CollectionFreeFormView extends CollectionSubView { // bcz: theres should be a better way of doing these than referencing these static instances directly MarqueeOptionsMenu.Instance?.fadeOut(true);// I think it makes sense for the marquee menu to go away when panned. -syip2 - // PDFMenu.Instance.fadeOut(true); const [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY); this.setPan((this.Document._panX || 0) - dx, (this.Document._panY || 0) - dy, undefined, true); @@ -1204,17 +1203,17 @@ export class CollectionFreeFormView extends CollectionSubView { - if (this.props.annotationsKey) return; + if (this.props.annotationsKey || !ContextMenu.Instance) return; - const appearance = ContextMenu.Instance?.findByDescription("Appearance..."); + const appearance = ContextMenu.Instance.findByDescription("Appearance..."); const appearanceItems = appearance && "subitems" in appearance ? appearance.subitems : []; appearanceItems.push({ description: "reset view", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" }); appearanceItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" }); appearanceItems.push({ description: `${this.Document.useClusters ? "Uncluster" : "Use Clusters"}`, event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" }); appearanceItems.push({ description: "Use Background Color as Default", event: () => Cast(Doc.UserDoc().emptyCollection, Doc, null)._backgroundColor = StrCast(this.layoutDoc._backgroundColor), icon: "palette" }); - !appearance && ContextMenu.Instance?.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" }); + !appearance && ContextMenu.Instance.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" }); - const options = ContextMenu.Instance?.findByDescription("Options..."); + const options = ContextMenu.Instance.findByDescription("Options..."); const optionItems = options && "subitems" in options ? options.subitems : []; !this.props.isAnnotationOverlay && optionItems.push({ description: (this.showTimeline ? "Close" : "Open") + " Animation Timeline", event: action(() => this.showTimeline = !this.showTimeline), icon: faEye }); @@ -1254,7 +1253,7 @@ export class CollectionFreeFormView extends CollectionSubView(Docu } const cm = ContextMenu.Instance; + if (!cm) return; const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []); Cast(this.props.Document.contextMenuLabels, listSpec("string"), []).forEach((label, i) => - cm?.addItem({ description: label, event: () => customScripts[i]?.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); + cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); this.props.contextMenuItems?.().forEach(item => - cm?.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); + cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); const options = cm.findByDescription("Options..."); 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" }); 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" }); + !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); - const existingOnClick = cm?.findByDescription("OnClick..."); + const existingOnClick = cm.findByDescription("OnClick..."); const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" }); onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "window-restore" }); @@ -759,17 +760,17 @@ export class DocumentView extends DocComponent(Docu onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link on Right", event: this.toggleFollowOnRight, icon: "concierge-bell" }); onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" }); onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" }); - !existingOnClick && cm?.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); + !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); const funcs: ContextMenuProps[] = []; if (this.layoutDoc.onDragStart) { funcs.push({ description: "Drag an Alias", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) }); funcs.push({ description: "Drag a Copy", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) }); funcs.push({ description: "Drag Document", icon: "edit", event: () => this.layoutDoc.onDragStart = undefined }); - cm?.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" }); + cm.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" }); } - const more = cm?.findByDescription("More..."); + const more = cm.findByDescription("More..."); const moreItems = more && "subitems" in more ? more.subitems : []; if (!Doc.UserDoc().noviceMode) { moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); @@ -798,16 +799,16 @@ export class DocumentView extends DocComponent(Docu moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" }); moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "external-link-alt" }); - !more && cm?.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); - cm?.moveAfter(cm?.findByDescription("More...")!, cm?.findByDescription("OnClick...")!); + !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); + cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!); - const help = cm?.findByDescription("Help..."); + const help = cm.findByDescription("Help..."); const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : []; helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument("http://localhost:1050/assets/cheat-sheet.pdf", { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" }); helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" }); - cm?.addItem({ description: "Help...", subitems: helpItems, icon: "question" }); + cm.addItem({ description: "Help...", subitems: helpItems, icon: "question" }); - const existingAcls = cm?.findByDescription("Privacy..."); + const existingAcls = cm.findByDescription("Privacy..."); const aclItems: ContextMenuProps[] = existingAcls && "subitems" in existingAcls ? existingAcls.subitems : []; aclItems.push({ description: "Make Add Only", event: () => this.setAcl("addOnly"), icon: "concierge-bell" }); aclItems.push({ description: "Make Read Only", event: () => this.setAcl("readOnly"), icon: "concierge-bell" }); @@ -815,7 +816,7 @@ export class DocumentView extends DocComponent(Docu aclItems.push({ description: "Make Editable", event: () => this.setAcl("write"), icon: "concierge-bell" }); aclItems.push({ description: "Test Private", event: () => this.testAcl("ownerOnly"), icon: "concierge-bell" }); aclItems.push({ description: "Test Readonly", event: () => this.testAcl("readOnly"), icon: "concierge-bell" }); - !existingAcls && cm?.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" }); + !existingAcls && cm.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" }); // const recommender_subitems: ContextMenuProps[] = []; @@ -876,7 +877,7 @@ export class DocumentView extends DocComponent(Docu // DocumentViews should stop propagation of this event e.stopPropagation(); } - ContextMenu.Instance?.displayMenu(e.pageX - 15, e.pageY - 15); + cm.displayMenu(e.pageX - 15, e.pageY - 15); !SelectionManager.IsSelected(this, true) && SelectionManager.SelectDoc(this, false); }); const path = this.props.LibraryPath.reduce((p: string, d: Doc) => p + "/" + (Doc.AreProtosEqual(d, (Doc.UserDoc()["tabs-button-library"] as Doc).sourcePanel as Doc) ? "" : d.title), ""); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 270fcb01c..b127cd024 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -190,7 +190,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } const state = this._editorView.state.apply(tx); - this._editorView?.updateState(state); + this._editorView.updateState(state); (tx.storedMarks && !this._editorView.state.storedMarks) && (this._editorView.state.storedMarks = tx.storedMarks); const tsel = this._editorView.state.selection.$from; -- cgit v1.2.3-70-g09d2