aboutsummaryrefslogtreecommitdiff
path: root/src/client/views
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views')
-rw-r--r--src/client/views/ContextMenu.scss22
-rw-r--r--src/client/views/ContextMenuItem.tsx84
-rw-r--r--src/client/views/DashboardView.tsx2
-rw-r--r--src/client/views/GlobalKeyHandler.ts4
-rw-r--r--src/client/views/Main.tsx51
-rw-r--r--src/client/views/MainView.tsx53
-rw-r--r--src/client/views/PropertiesDocContextSelector.tsx2
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx70
-rw-r--r--src/client/views/collections/CollectionView.tsx2
-rw-r--r--src/client/views/collections/TabDocView.tsx15
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx48
-rw-r--r--src/client/views/nodes/PDFBox.tsx5
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx2
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx2
-rw-r--r--src/client/views/topbar/TopBar.tsx2
15 files changed, 203 insertions, 161 deletions
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index ea24dbf6d..1e6a377de 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -1,10 +1,10 @@
-@import "global/globalCssVariables";
+@import 'global/globalCssVariables';
.contextMenu-cont {
position: absolute;
display: flex;
z-index: 100000;
- box-shadow: 0px 3px 4px rgba(0,0,0,30%);
+ box-shadow: 0px 3px 4px rgba(0, 0, 0, 30%);
flex-direction: column;
background: whitesmoke;
border-radius: 3px;
@@ -28,9 +28,9 @@
position: absolute;
display: flex;
z-index: 1000;
- box-shadow: #AAAAAA .2vw .2vw .4vw;
+ box-shadow: #aaaaaa 0.2vw 0.2vw 0.4vw;
flex-direction: column;
- border: 1px solid #BBBBBBBB;
+ border: 1px solid #bbbbbbbb;
border-radius: 15px;
padding-top: 10px;
padding-bottom: 10px;
@@ -49,7 +49,7 @@
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
- transition: all .1s;
+ transition: all 0.1s;
border-style: none;
// padding: 10px 0px 10px 0px;
white-space: nowrap;
@@ -58,7 +58,7 @@
text-transform: uppercase;
padding-right: 30px;
- .icon-background {
+ .contextMenu-item-icon-background {
pointer-events: all;
background-color: transparent;
width: 35px;
@@ -78,7 +78,7 @@
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
- transition: all .1s;
+ transition: all 0.1s;
border-style: none;
// padding: 10px 0px 10px 0px;
white-space: nowrap;
@@ -89,7 +89,7 @@
}
.contextMenu-item:hover {
- border-width: .11px;
+ border-width: 0.11px;
border-style: none;
border-color: $medium-gray; // rgb(187, 186, 186);
border-bottom-style: solid;
@@ -116,8 +116,8 @@
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
- transition: all .1s;
- border-width: .11px;
+ transition: all 0.1s;
+ border-width: 0.11px;
border-style: none;
border-color: $medium-gray; // rgb(187, 186, 186);
// padding: 10px 0px 10px 0px;
@@ -152,4 +152,4 @@
padding-left: 10px;
border: solid black 1px;
border-radius: 5px;
-} \ No newline at end of file
+}
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 30073e21f..dc9c2eb6c 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -1,9 +1,9 @@
-import React = require("react");
-import { observable, action, runInAction } from "mobx";
-import { observer } from "mobx-react";
+import React = require('react');
+import { observable, action, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { UndoManager } from "../util/UndoManager";
+import { UndoManager } from '../util/UndoManager';
export interface OriginalMenuProps {
description: string;
@@ -37,7 +37,7 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
}
handleEvent = async (e: React.MouseEvent<HTMLDivElement>) => {
- if ("event" in this.props) {
+ if ('event' in this.props) {
this.props.closeMenu?.();
let batch: UndoManager.Batch | undefined;
if (this.props.undoable !== false) {
@@ -46,7 +46,7 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
await this.props.event({ x: e.clientX, y: e.clientY });
batch?.end();
}
- }
+ };
currentTimeout?: any;
static readonly timeout = 300;
@@ -62,8 +62,11 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
}
this._overPosY = e.clientY;
this._overPosX = e.clientX;
- this.currentTimeout = setTimeout(action(() => this.overItem = true), ContextMenuItem.timeout);
- }
+ this.currentTimeout = setTimeout(
+ action(() => (this.overItem = true)),
+ ContextMenuItem.timeout
+ );
+ };
onPointerLeave = () => {
if (this.currentTimeout) {
@@ -73,57 +76,68 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
if (!this.overItem) {
return;
}
- this.currentTimeout = setTimeout(action(() => this.overItem = false), ContextMenuItem.timeout);
- }
+ this.currentTimeout = setTimeout(
+ action(() => (this.overItem = false)),
+ ContextMenuItem.timeout
+ );
+ };
render() {
- if ("event" in this.props) {
+ if ('event' in this.props) {
return (
- <div className={"contextMenu-item" + (this.props.selected ? " contextMenu-itemSelected" : "")} onPointerDown={this.handleEvent}>
+ <div className={'contextMenu-item' + (this.props.selected ? ' contextMenu-itemSelected' : '')} onPointerDown={this.handleEvent}>
{this.props.icon ? (
- <span className="icon-background">
+ <span className="contextMenu-item-icon-background">
<FontAwesomeIcon icon={this.props.icon} size="sm" />
</span>
) : null}
- <div className="contextMenu-description">
- {this.props.description.replace(":", "")}
- </div>
+ <div className="contextMenu-description">{this.props.description.replace(':', '')}</div>
</div>
);
- } else if ("subitems" in this.props) {
- const where = !this.overItem ? "" : this._overPosY < window.innerHeight / 3 ? "flex-start" : this._overPosY > window.innerHeight * 2 / 3 ? "flex-end" : "center";
- const marginTop = !this.overItem ? "" : this._overPosY < window.innerHeight / 3 ? "20px" : this._overPosY > window.innerHeight * 2 / 3 ? "-20px" : "";
+ } else if ('subitems' in this.props) {
+ const where = !this.overItem ? '' : this._overPosY < window.innerHeight / 3 ? 'flex-start' : this._overPosY > (window.innerHeight * 2) / 3 ? 'flex-end' : 'center';
+ const marginTop = !this.overItem ? '' : this._overPosY < window.innerHeight / 3 ? '20px' : this._overPosY > (window.innerHeight * 2) / 3 ? '-20px' : '';
// here
- const submenu = !this.overItem ? (null) :
- <div className="contextMenu-subMenu-cont"
+ const submenu = !this.overItem ? null : (
+ <div
+ className="contextMenu-subMenu-cont"
style={{
- marginLeft: window.innerHeight - this._overPosX - 50 > 0 ? "90%" : "20%", marginTop
+ marginLeft: window.innerHeight - this._overPosX - 50 > 0 ? '90%' : '20%',
+ marginTop,
}}>
- {this._items.map(prop => <ContextMenuItem {...prop} key={prop.description} closeMenu={this.props.closeMenu} />)}
- </div>;
+ {this._items.map(prop => (
+ <ContextMenuItem {...prop} key={prop.description} closeMenu={this.props.closeMenu} />
+ ))}
+ </div>
+ );
if (!(this.props as SubmenuProps).noexpand) {
- return <div className="contextMenu-inlineMenu">
- {this._items.map(prop => <ContextMenuItem {...prop} key={prop.description} closeMenu={this.props.closeMenu} />)}
- </div>;
+ return (
+ <div className="contextMenu-inlineMenu">
+ {this._items.map(prop => (
+ <ContextMenuItem {...prop} key={prop.description} closeMenu={this.props.closeMenu} />
+ ))}
+ </div>
+ );
}
return (
- <div className={"contextMenu-item" + (this.props.selected ? " contextMenu-itemSelected" : "")}
- style={{ alignItems: where, borderTop: this.props.addDivider ? "solid 1px" : undefined }}
- onMouseLeave={this.onPointerLeave} onMouseEnter={this.onPointerEnter}>
+ <div
+ className={'contextMenu-item' + (this.props.selected ? ' contextMenu-itemSelected' : '')}
+ style={{ alignItems: where, borderTop: this.props.addDivider ? 'solid 1px' : undefined }}
+ onMouseLeave={this.onPointerLeave}
+ onMouseEnter={this.onPointerEnter}>
{this.props.icon ? (
- <span className="icon-background" onMouseEnter={this.onPointerLeave} style={{ alignItems: "center", alignSelf: "center" }}>
+ <span className="contextMenu-item-icon-background" onMouseEnter={this.onPointerLeave} style={{ alignItems: 'center', alignSelf: 'center' }}>
<FontAwesomeIcon icon={this.props.icon} size="sm" />
</span>
) : null}
- <div className="contextMenu-description" onMouseEnter={this.onPointerEnter}
- style={{ alignItems: "center", alignSelf: "center" }} >
+ <div className="contextMenu-description" onMouseEnter={this.onPointerEnter} style={{ alignItems: 'center', alignSelf: 'center' }}>
{this.props.description}
- <FontAwesomeIcon icon={"angle-right"} size="lg" style={{ position: "absolute", right: "10px" }} />
+ <FontAwesomeIcon icon={'angle-right'} size="lg" style={{ position: 'absolute', right: '10px' }} />
</div>
{submenu}
</div>
);
}
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 526a32f5a..9ea9128bd 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -238,7 +238,7 @@ export class DashboardView extends React.Component {
} else if (doc.readOnly) {
DocServer.Control.makeReadOnly();
} else {
- DocServer.Control.makeEditable();
+ Doc.CurrentUserEmail !== 'guest' && DocServer.Control.makeEditable();
}
}
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 73e0c9933..85f579975 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -116,8 +116,8 @@ export class KeyManager {
var doDeselect = true;
if (SnappingManager.GetIsDragging()) {
DragManager.AbortDrag();
- } else if (CollectionDockingView.Instance.HasFullScreen) {
- CollectionDockingView.Instance.CloseFullScreen();
+ } else if (CollectionDockingView.Instance?.HasFullScreen) {
+ CollectionDockingView.Instance?.CloseFullScreen();
} else if (CollectionStackedTimeline.SelectingRegion) {
CollectionStackedTimeline.SelectingRegion = undefined;
doDeselect = false;
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index e998f1fb9..4cb1183d0 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -5,6 +5,8 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { AssignAllExtensions } from '../../extensions/General/Extensions';
+import { Utils } from '../../Utils';
+import { DocServer } from '../DocServer';
import { Docs } from '../documents/Documents';
import { CurrentUserUtils } from '../util/CurrentUserUtils';
import { LinkManager } from '../util/LinkManager'; // this must come before importing Docs and CurrentUserUtils
@@ -19,31 +21,28 @@ AssignAllExtensions();
MainView.Live = window.location.search.includes('live');
window.location.search.includes('safe') && CollectionView.SetSafeMode(true);
const info = await CurrentUserUtils.loadCurrentUser();
- if (info.id !== '__guest__') {
- // a guest will not have an id registered
- await CurrentUserUtils.loadUserDocument(info.id);
- } else {
- await Docs.Prototypes.initialize();
+ if (info.email === 'guest') DocServer.Control.makeReadOnly();
+ await CurrentUserUtils.loadUserDocument(info.id);
+ setTimeout(() => {
+ document.getElementById('root')!.addEventListener(
+ 'wheel',
+ event => {
+ if (event.ctrlKey) {
+ event.preventDefault();
+ }
+ },
+ true
+ );
+ const startload = (document as any).startLoad;
+ const loading = Date.now() - (startload ? Number(startload) : Date.now() - 3000);
+ console.log('Loading Time = ' + loading);
+ const d = new Date();
+ d.setTime(d.getTime() + 100 * 24 * 60 * 60 * 1000);
+ const expires = 'expires=' + d.toUTCString();
+ document.cookie = `loadtime=${loading};${expires};path=/`;
new LinkManager();
- }
- document.getElementById('root')!.addEventListener(
- 'wheel',
- event => {
- if (event.ctrlKey) {
- event.preventDefault();
- }
- },
- true
- );
- const startload = (document as any).startLoad;
- const loading = Date.now() - (startload ? Number(startload) : Date.now() - 3000);
- console.log('Loading Time = ' + loading);
- const d = new Date();
- d.setTime(d.getTime() + 100 * 24 * 60 * 60 * 1000);
- const expires = 'expires=' + d.toUTCString();
- document.cookie = `loadtime=${loading};${expires};path=/`;
- new LinkManager();
- new TrackMovements();
- new ReplayMovements();
- ReactDOM.render(<MainView />, document.getElementById('root'));
+ new TrackMovements();
+ new ReplayMovements();
+ ReactDOM.render(<MainView />, document.getElementById('root'));
+ }, 0);
})();
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index b61cd3409..7e032af5e 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -3,7 +3,7 @@ import { faBuffer, faHireAHelper } from '@fortawesome/free-brands-svg-icons';
import * as far from '@fortawesome/free-regular-svg-icons';
import * as fa from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, configure, observable, reaction } from 'mobx';
+import { action, computed, configure, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
@@ -77,12 +77,15 @@ export class MainView extends React.Component {
@observable private _panelContent: string = 'none';
@observable private _sidebarContent: any = Doc.MyLeftSidebarPanel;
@observable private _leftMenuFlyoutWidth: number = 0;
+ @computed get _hideUI() {
+ return this.mainDoc && this.mainDoc._viewType !== CollectionViewType.Docking;
+ }
@computed private get dashboardTabHeight() {
- return 27;
+ return this._hideUI ? 0 : 27;
} // 27 comes form lm.config.defaultConfig.dimensions.headerHeight in goldenlayout.js
@computed private get topOfDashUI() {
- return Number(DASHBOARD_SELECTOR_HEIGHT.replace('px', ''));
+ return this._hideUI ? 0 : Number(DASHBOARD_SELECTOR_HEIGHT.replace('px', ''));
}
@computed private get topOfHeaderBarDoc() {
return this.topOfDashUI;
@@ -105,7 +108,12 @@ export class MainView extends React.Component {
@computed private get colorScheme() {
return StrCast(Doc.ActiveDashboard?.colorScheme);
}
+ @observable mainDoc: Opt<Doc>;
@computed private get mainContainer() {
+ if (window.location.pathname.startsWith('/doc/')) {
+ DocServer.GetRefField(window.location.pathname.substring('/doc/'.length)).then(main => runInAction(() => (this.mainDoc = main as Doc)));
+ return this.mainDoc;
+ }
return this.userDoc ? Doc.ActiveDashboard : Doc.GuestDashboard;
}
@computed private get headerBarDoc() {
@@ -116,10 +124,10 @@ export class MainView extends React.Component {
}
headerBarDocWidth = () => this.mainDocViewWidth();
- headerBarDocHeight = () => SettingsManager.headerBarHeight ?? 0;
- topMenuHeight = () => 35;
+ headerBarDocHeight = () => (this._hideUI ? 0 : SettingsManager.headerBarHeight ?? 0);
+ topMenuHeight = () => (this._hideUI ? 0 : 35);
topMenuWidth = returnZero; // value is ignored ...
- leftMenuWidth = () => Number(LEFT_MENU_WIDTH.replace('px', ''));
+ leftMenuWidth = () => (this._hideUI ? 0 : Number(LEFT_MENU_WIDTH.replace('px', '')));
leftMenuHeight = () => this._dashUIHeight;
leftMenuFlyoutWidth = () => this._leftMenuFlyoutWidth;
leftMenuFlyoutHeight = () => this._dashUIHeight;
@@ -212,7 +220,8 @@ export class MainView extends React.Component {
const pathname = window.location.pathname.substr(1).split('/');
if (pathname.length > 1 && pathname[0] === 'doc') {
Doc.MainDocId = pathname[1];
- !this.userDoc && DocServer.GetRefField(pathname[1]).then(action(field => field instanceof Doc && (Doc.GuestTarget = field)));
+ //!this.userDoc &&
+ DocServer.GetRefField(pathname[1]).then(action(field => field instanceof Doc && (Doc.GuestTarget = field)));
}
}
@@ -455,7 +464,11 @@ export class MainView extends React.Component {
AudioBox.Enabled = true;
const targets = document.elementsFromPoint(e.x, e.y);
if (targets.length) {
- const targClass = targets[0].className.toString();
+ let targClass = targets[0].className.toString();
+ for (let i = 0; i < targets.length - 1; i++) {
+ if (typeof targets[i].className === 'object') targClass = targets[i + 1].className.toString();
+ else break;
+ }
!targClass.includes('contextMenu') && ContextMenu.Instance.closeMenu();
!['timeline-menu-desc', 'timeline-menu-item', 'timeline-menu-input'].includes(targClass) && TimelineMenu.Instance.closeMenu();
}
@@ -517,7 +530,7 @@ export class MainView extends React.Component {
return () => (this._exploreMode ? ScriptField.MakeScript('CollectionBrowseClick(documentView, clientX, clientY)', { documentView: 'any', clientX: 'number', clientY: 'number' })! : undefined);
}
headerBarScreenXf = () => new Transform(-this.leftScreenOffsetOfMainDocView - this.leftMenuFlyoutWidth(), -this.headerBarDocHeight(), 1);
-
+ mainScreenToLocalXf = () => new Transform(-this.leftScreenOffsetOfMainDocView - this.leftMenuFlyoutWidth(), -this.topOfMainDocContent, 1);
@computed get headerBarDocView() {
return (
<div className="mainView-headerBar" style={{ height: this.headerBarDocHeight() }}>
@@ -557,7 +570,7 @@ export class MainView extends React.Component {
@computed get mainDocView() {
return (
<>
- {this.headerBarDocView}
+ {this._hideUI ? null : this.headerBarDocView}
<DocumentView
key="main"
Document={this.mainContainer!}
@@ -566,11 +579,11 @@ export class MainView extends React.Component {
addDocTab={this.addDocTabFunc}
pinToPres={emptyFunction}
docViewPath={returnEmptyDoclist}
- styleProvider={undefined}
+ styleProvider={this._hideUI ? DefaultStyleProvider : undefined}
rootSelected={returnTrue}
isContentActive={returnTrue}
removeDocument={undefined}
- ScreenToLocalTransform={Transform.Identity}
+ ScreenToLocalTransform={this._hideUI ? this.mainScreenToLocalXf : Transform.Identity}
PanelWidth={this.mainDocViewWidth}
PanelHeight={this.mainDocViewHeight}
focus={DocUtils.DefaultFocus}
@@ -582,7 +595,7 @@ export class MainView extends React.Component {
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined}
suppressSetHeight={true}
- renderDepth={-1}
+ renderDepth={this._hideUI ? 0 : -1}
/>
</>
);
@@ -750,7 +763,7 @@ export class MainView extends React.Component {
const width = this.propertiesWidth() + leftMenuFlyoutWidth;
return (
<>
- {this.leftMenuPanel}
+ {this._hideUI ? null : this.leftMenuPanel}
<div key="inner" className={`mainView-innerContent${this.colorScheme}`}>
{this.flyout}
<div className="mainView-libraryHandle" style={{ left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? 'none' : undefined }} onPointerDown={this.onFlyoutPointerDown}>
@@ -759,9 +772,11 @@ export class MainView extends React.Component {
<div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)` }}>
{this.dockingContent}
- <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1 }}>
- <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? 'chevron-left' : 'chevron-right'} color={this.colorScheme === ColorScheme.Dark ? Colors.WHITE : Colors.BLACK} size="sm" />
- </div>
+ {this._hideUI ? null : (
+ <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1 }}>
+ <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? 'chevron-left' : 'chevron-right'} color={this.colorScheme === ColorScheme.Dark ? Colors.WHITE : Colors.BLACK} size="sm" />
+ </div>
+ )}
<div className="properties-container" style={{ width: this.propertiesWidth() }}>
{this.propertiesWidth() < 10 ? null : <PropertiesView styleProvider={DefaultStyleProvider} addDocTab={this.addDocTabFunc} width={this.propertiesWidth()} height={this.propertiesHeight()} />}
</div>
@@ -962,7 +977,7 @@ export class MainView extends React.Component {
<GoogleAuthenticationManager />
<DocumentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfHeaderBarDoc} PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} />
<ComponentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDocContent} />
- <TopBar />
+ {this._hideUI ? null : <TopBar />}
{LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
{DocumentLinksButton.LinkEditorDocView ? <LinkMenu clearLinkEditor={action(() => (DocumentLinksButton.LinkEditorDocView = undefined))} docView={DocumentLinksButton.LinkEditorDocView} /> : null}
{LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : null}
@@ -973,7 +988,7 @@ export class MainView extends React.Component {
default:
return (
<>
- <div style={{ position: 'relative', display: LightboxView.LightboxDoc ? 'none' : undefined, zIndex: 1999 }}>
+ <div style={{ position: 'relative', display: this._hideUI || LightboxView.LightboxDoc ? 'none' : undefined, zIndex: 1999 }}>
<CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
</div>
{this.mainDashboardArea}
diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx
index 0f63ebc1d..9d89ee036 100644
--- a/src/client/views/PropertiesDocContextSelector.tsx
+++ b/src/client/views/PropertiesDocContextSelector.tsx
@@ -40,7 +40,7 @@ export class PropertiesDocContextSelector extends React.Component<PropertiesDocC
.keys()
);
return doclayouts
- .filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document))
+ .filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance?.props.Document))
.filter(doc => !Doc.IsSystem(doc))
.map(doc => ({ col: doc, target }));
}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 42f9bb981..ed9054107 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -29,7 +29,7 @@ const _global = (window /* browser */ || global) /* node */ as any;
@observer
export class CollectionDockingView extends CollectionSubView() {
- @observable public static Instance: CollectionDockingView;
+ @observable public static Instance: CollectionDockingView | undefined;
public static makeDocumentConfig(document: Doc, panelName?: string, width?: number) {
return {
type: 'react-component',
@@ -103,12 +103,14 @@ export class CollectionDockingView extends CollectionSubView() {
@undoBatch
public static CloseSplit(document: Opt<Doc>, panelName?: string): boolean {
- const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find(tab => (panelName ? tab.contentItem.config.props.panelName === panelName : tab.DashDoc === document));
- if (tab) {
- const j = tab.header.parent.contentItems.indexOf(tab.contentItem);
- if (j !== -1) {
- tab.header.parent.contentItems[j].remove();
- return CollectionDockingView.Instance.layoutChanged();
+ if (CollectionDockingView.Instance) {
+ const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find(tab => (panelName ? tab.contentItem.config.props.panelName === panelName : tab.DashDoc === document));
+ if (tab) {
+ const j = tab.header.parent.contentItems.indexOf(tab.contentItem);
+ if (j !== -1) {
+ tab.header.parent.contentItems[j].remove();
+ return CollectionDockingView.Instance.layoutChanged();
+ }
}
}
@@ -119,19 +121,21 @@ export class CollectionDockingView extends CollectionSubView() {
public static OpenFullScreen(doc: Doc) {
SelectionManager.DeselectAll();
const instance = CollectionDockingView.Instance;
- if (doc._viewType === CollectionViewType.Docking && doc.layoutKey === 'layout') {
- return DashboardView.openDashboard(doc);
+ if (instance) {
+ if (doc._viewType === CollectionViewType.Docking && doc.layoutKey === 'layout') {
+ return DashboardView.openDashboard(doc);
+ }
+ const newItemStackConfig = {
+ type: 'stack',
+ content: [CollectionDockingView.makeDocumentConfig(Doc.MakeAlias(doc))],
+ };
+ const docconfig = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout);
+ instance._goldenLayout.root.contentItems[0].addChild(docconfig);
+ docconfig.callDownwards('_$init');
+ instance._goldenLayout._$maximiseItem(docconfig);
+ instance._goldenLayout.emit('stateChanged');
+ instance.stateChanged();
}
- const newItemStackConfig = {
- type: 'stack',
- content: [CollectionDockingView.makeDocumentConfig(Doc.MakeAlias(doc))],
- };
- const docconfig = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout);
- instance._goldenLayout.root.contentItems[0].addChild(docconfig);
- docconfig.callDownwards('_$init');
- instance._goldenLayout._$maximiseItem(docconfig);
- instance._goldenLayout.emit('stateChanged');
- instance.stateChanged();
return true;
}
@@ -146,21 +150,23 @@ export class CollectionDockingView extends CollectionSubView() {
const newContentItem = stack.layoutManager.createContentItem(newConfig, instance._goldenLayout);
stack.addChild(newContentItem.contentItems[0], undefined);
stack.contentItems[activeContentItemIndex].remove();
- return CollectionDockingView.Instance.layoutChanged();
+ return instance.layoutChanged();
}
- const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find(tab => tab.contentItem.config.props.panelName === panelName);
+ const tab = Array.from(instance.tabMap.keys()).find(tab => tab.contentItem.config.props.panelName === panelName);
if (tab) {
tab.header.parent.addChild(newConfig, undefined);
const j = tab.header.parent.contentItems.indexOf(tab.contentItem);
!addToSplit && j !== -1 && tab.header.parent.contentItems[j].remove();
- return CollectionDockingView.Instance.layoutChanged();
+ return instance.layoutChanged();
}
return CollectionDockingView.AddSplit(document, panelName, stack, panelName);
}
@undoBatch
public static ToggleSplit(doc: Doc, location: string, stack?: any, panelName?: string) {
- return Array.from(CollectionDockingView.Instance.tabMap.keys()).findIndex(tab => tab.DashDoc === doc) !== -1 ? CollectionDockingView.CloseSplit(doc) : CollectionDockingView.AddSplit(doc, location, stack, panelName);
+ return CollectionDockingView.Instance && Array.from(CollectionDockingView.Instance.tabMap.keys()).findIndex(tab => tab.DashDoc === doc) !== -1
+ ? CollectionDockingView.CloseSplit(doc)
+ : CollectionDockingView.AddSplit(doc, location, stack, panelName);
}
//
@@ -170,7 +176,7 @@ export class CollectionDockingView extends CollectionSubView() {
@action
public static AddSplit(document: Doc, pullSide: string, stack?: any, panelName?: string) {
if (document._viewType === CollectionViewType.Docking) return DashboardView.openDashboard(document);
-
+ if (!CollectionDockingView.Instance) return false;
const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tab => tab.DashDoc === document);
if (tab) {
tab.header.parent.setActiveContentItem(tab.contentItem);
@@ -453,13 +459,15 @@ export class CollectionDockingView extends CollectionSubView() {
Doc.AddDocToList(Doc.MyHeaderBar, 'data', tab.DashDoc);
Doc.AddDocToList(Doc.MyRecentlyClosed, 'data', tab.DashDoc, undefined, true, true);
}
- const dview = CollectionDockingView.Instance.props.Document;
- const fieldKey = CollectionDockingView.Instance.props.fieldKey;
- Doc.RemoveDocFromList(dview, fieldKey, tab.DashDoc);
- this.tabMap.delete(tab);
- tab._disposers && Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
- tab.reactComponents?.forEach((ele: any) => ReactDOM.unmountComponentAtNode(ele));
- this.stateChanged();
+ if (CollectionDockingView.Instance) {
+ const dview = CollectionDockingView.Instance.props.Document;
+ const fieldKey = CollectionDockingView.Instance.props.fieldKey;
+ Doc.RemoveDocFromList(dview, fieldKey, tab.DashDoc);
+ this.tabMap.delete(tab);
+ tab._disposers && Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
+ tab.reactComponents?.forEach((ele: any) => ReactDOM.unmountComponentAtNode(ele));
+ this.stateChanged();
+ }
};
tabCreated = (tab: any) => {
this.tabMap.add(tab);
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 2ab5f6247..f0cb23eab 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -225,7 +225,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
},
})
);
- DocListCast(Cast(Doc.UserDoc()['clickFuncs-child'], Doc, null).data).forEach(childClick =>
+ DocListCast(Cast(Doc.UserDoc()['clickFuncs-child'], Doc, null)?.data).forEach(childClick =>
onClicks.push({
description: `Set child ${childClick.title}`,
icon: 'edit',
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index b8aaea622..2d08b1c09 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -302,6 +302,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array
});
if (
+ CollectionDockingView.Instance &&
!Array.from(CollectionDockingView.Instance.tabMap)
.map(d => d.DashDoc)
.includes(curPres)
@@ -420,7 +421,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
ScreenToLocalTransform = () => {
this._forceInvalidateScreenToLocal;
const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont?.children?.[0] as HTMLElement);
- return CollectionDockingView.Instance?.props.ScreenToLocalTransform().translate(-translateX, -translateY);
+ return CollectionDockingView.Instance?.props.ScreenToLocalTransform().translate(-translateX, -translateY) ?? Transform.Identity();
};
PanelWidth = () => this._panelWidth;
PanelHeight = () => this._panelHeight;
@@ -449,9 +450,9 @@ export class TabDocView extends React.Component<TabDocViewProps> {
PanelWidth={this.PanelWidth}
PanelHeight={this.PanelHeight}
styleProvider={DefaultStyleProvider}
- docFilters={CollectionDockingView.Instance.childDocFilters}
- docRangeFilters={CollectionDockingView.Instance.childDocRangeFilters}
- searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs}
+ docFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
+ docRangeFilters={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
+ searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
addDocument={undefined}
removeDocument={this.remDocTab}
addDocTab={this.addDocTab}
@@ -624,9 +625,9 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
styleProvider={TabMinimapView.miniStyleProvider}
addDocTab={this.props.addDocTab}
pinToPres={TabDocView.PinDoc}
- docFilters={CollectionDockingView.Instance.childDocFilters}
- docRangeFilters={CollectionDockingView.Instance.childDocRangeFilters}
- searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs}
+ docFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
+ docRangeFilters={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
+ searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
fitContentsToBox={returnTrue}
/>
<div className="miniOverlay" onPointerDown={this.miniDown}>
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index bf4c029b2..c4b42301e 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -1,6 +1,6 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Autocomplete, GoogleMap, GoogleMapProps, Marker } from '@react-google-maps/api';
-import { action, computed, IReactionDisposer, observable, ObservableMap } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableMap, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, Opt, WidthSym } from '../../../../fields/Doc';
@@ -12,6 +12,7 @@ import { emptyFunction, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, Uti
import { Docs } from '../../../documents/Documents';
import { DragManager } from '../../../util/DragManager';
import { SnappingManager } from '../../../util/SnappingManager';
+import { UndoManager } from '../../../util/UndoManager';
import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
@@ -368,23 +369,27 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
setupMoveUpEvents(
this,
e,
- (e, down, delta) => {
- const localDelta = this.props
- .ScreenToLocalTransform()
- .scale(this.props.scaling?.() || 1)
- .transformDirection(delta[0], delta[1]);
- const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
- const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
- const ratio = (curNativeWidth + localDelta[0] / (this.props.scaling?.() || 1)) / nativeWidth;
- if (ratio >= 1) {
- this.layoutDoc.nativeWidth = nativeWidth * ratio;
- this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0];
- this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
- }
- return false;
- },
+ (e, down, delta) =>
+ runInAction(() => {
+ const localDelta = this.props
+ .ScreenToLocalTransform()
+ .scale(this.props.scaling?.() || 1)
+ .transformDirection(delta[0], delta[1]);
+ const fullWidth = this.layoutDoc[WidthSym]();
+ const mapWidth = fullWidth - this.sidebarWidth();
+ if (this.sidebarWidth() + localDelta[0] > 0) {
+ this._showSidebar = true;
+ this.layoutDoc._width = fullWidth + localDelta[0];
+ this.layoutDoc._sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%';
+ } else {
+ this._showSidebar = false;
+ this.layoutDoc._width = mapWidth;
+ this.layoutDoc._sidebarWidthPercent = '0%';
+ }
+ return false;
+ }),
emptyFunction,
- this.toggleSidebar
+ () => UndoManager.RunInBatch(this.toggleSidebar, 'toggle sidebar map')
);
};
@@ -470,13 +475,14 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
// TODO: Adding highlight box layer to Maps
@action
toggleSidebar = () => {
+ //1.2 * w * ? = .2 * w .2/1.2
const prevWidth = this.sidebarWidth();
- this.layoutDoc._showSidebar = (this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, '0%') === '0%' ? '50%' : '0%') !== '0%';
- this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
+ this.layoutDoc._showSidebar = (this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, '0%') === '0%' ? `${(100 * 0.2) / 1.2}%` : '0%') !== '0%';
+ this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
};
sidebarDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), false);
+ setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), true);
};
sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => {
const bounds = this._ref.current!.getBoundingClientRect();
@@ -605,7 +611,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
{this.annotationLayer}
<GoogleMap mapContainerStyle={mapContainerStyle} onZoomChanged={this.zoomChanged} onCenterChanged={this.centered} onLoad={this.loadHandler} options={mapOptions}>
<Autocomplete onLoad={this.setSearchBox} onPlaceChanged={this.handlePlaceChanged}>
- <input className="mapBox-input" ref={this.inputRef} type="text" placeholder="Enter location" />
+ <input className="mapBox-input" ref={this.inputRef} type="text" onKeyDown={e => e.stopPropagation()} placeholder="Enter location" />
</Autocomplete>
{this.renderMarkers()}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 5b9d90780..f41f6a1ad 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -13,20 +13,19 @@ import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
import { KeyCodes } from '../../util/KeyCodes';
import { undoBatch, UndoManager } from '../../util/UndoManager';
+import { CollectionFreeFormView } from '../collections/collectionFreeForm';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
import { Colors } from '../global/globalEnums';
import { CreateImage } from '../nodes/WebBoxRenderer';
-import { AnchorMenu } from '../pdf/AnchorMenu';
import { PDFViewer } from '../pdf/PDFViewer';
import { SidebarAnnos } from '../SidebarAnnos';
import { FieldView, FieldViewProps } from './FieldView';
import { ImageBox } from './ImageBox';
-import './PDFBox.scss';
import { VideoBox } from './VideoBox';
+import './PDFBox.scss';
import React = require('react');
-import { CollectionFreeFormView } from '../collections/collectionFreeForm';
@observer
export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps>() {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index cfaa428f9..e945920da 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -640,7 +640,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this.layoutDoc._width = !preview && this.SidebarShown ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
};
sidebarDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), false);
+ setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), true);
};
sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => {
const bounds = this._ref.current!.getBoundingClientRect();
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 292c187e4..6e5eb3300 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -399,7 +399,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined;
const includesDoc: boolean = DocListCast(presCollection?.data).includes(targetDoc);
- const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tab => tab.DashDoc === srcContext);
+ const tab = CollectionDockingView.Instance && Array.from(CollectionDockingView.Instance.tabMap).find(tab => tab.DashDoc === srcContext);
this.turnOffEdit();
// Handles the setting of presCollection
if (includesDoc) {
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 0bf1575fb..3fc0a237e 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -26,7 +26,7 @@ import './TopBar.scss';
@observer
export class TopBar extends React.Component {
navigateToHome = () => {
- CollectionDockingView.Instance.CaptureThumbnail()?.then(() => {
+ CollectionDockingView.Instance?.CaptureThumbnail()?.then(() => {
Doc.ActivePage = 'home';
DashboardView.closeActiveDashboard(); // bcz: if we do this, we need some other way to keep track, for user convenience, of the last dashboard in use
});