aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/MainView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/MainView.tsx')
-rw-r--r--src/client/views/MainView.tsx170
1 files changed, 110 insertions, 60 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 58b8d255a..10d423c05 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable node/no-unpublished-import */
import { library } from '@fortawesome/fontawesome-svg-core';
import { faBuffer, faHireAHelper } from '@fortawesome/free-brands-svg-icons';
import * as far from '@fortawesome/free-regular-svg-icons';
@@ -6,8 +7,10 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, configure, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+// eslint-disable-next-line import/no-relative-packages
import '../../../node_modules/browndash-components/dist/styles/global.min.css';
-import { Utils, emptyFunction, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../Utils';
+import { ClientUtils, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../ClientUtils';
+import { emptyFunction } from '../../Utils';
import { Doc, DocListCast, Opt } from '../../fields/Doc';
import { DocData } from '../../fields/DocSymbols';
import { DocCast, StrCast } from '../../fields/Types';
@@ -18,10 +21,12 @@ import { Docs } from '../documents/Documents';
import { CalendarManager } from '../util/CalendarManager';
import { CaptureManager } from '../util/CaptureManager';
import { DocumentManager } from '../util/DocumentManager';
-import { DragManager, dropActionType } from '../util/DragManager';
+import { DragManager } from '../util/DragManager';
+import { dropActionType } from '../util/DropActionTypes';
import { GroupManager } from '../util/GroupManager';
import { HistoryUtil } from '../util/History';
import { Hypothesis } from '../util/HypothesisUtils';
+import { UPDATE_SERVER_CACHE } from '../util/LinkManager';
import { RTFMarkup } from '../util/RTFMarkup';
import { ScriptingGlobals } from '../util/ScriptingGlobals';
import { SelectionManager } from '../util/SelectionManager';
@@ -57,7 +62,7 @@ import { AudioBox } from './nodes/AudioBox';
import { SchemaCSVPopUp } from './nodes/DataVizBox/SchemaCSVPopUp';
import { DocButtonState } from './nodes/DocumentLinksButton';
import { DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod, returnEmptyDocViewList } from './nodes/DocumentView';
-import { ImageBox, ImageEditorData as ImageEditor } from './nodes/ImageBox';
+import { ImageEditorData as ImageEditor } from './nodes/ImageBox';
import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
import { LinkDocPreview, LinkInfo } from './nodes/LinkDocPreview';
import { DirectionsAnchorMenu } from './nodes/MapBox/DirectionsAnchorMenu';
@@ -71,11 +76,13 @@ import { PresBox } from './nodes/trails';
import { AnchorMenu } from './pdf/AnchorMenu';
import { GPTPopup } from './pdf/GPTPopup/GPTPopup';
import { TopBar } from './topbar/TopBar';
-const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
+
const _global = (window /* browser */ || global) /* node */ as any;
+const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
@observer
export class MainView extends ObservableReactComponent<{}> {
+ // eslint-disable-next-line no-use-before-define
public static Instance: MainView;
public static Live: boolean = false;
private _docBtnRef = React.createRef<HTMLDivElement>();
@@ -117,8 +124,12 @@ export class MainView extends ObservableReactComponent<{}> {
}
@observable mainDoc: Opt<Doc> = undefined;
@computed private get mainContainer() {
- if (window.location.pathname.startsWith('/doc/') && Doc.CurrentUserEmail === 'guest') {
- DocServer.GetRefField(window.location.pathname.substring('/doc/'.length)).then(main => runInAction(() => (this.mainDoc = main as Doc)));
+ if (window.location.pathname.startsWith('/doc/') && ClientUtils.CurrentUserEmail() === 'guest') {
+ 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;
@@ -154,6 +165,7 @@ export class MainView extends ObservableReactComponent<{}> {
mainDocViewHeight = () => this._dashUIHeight - this.headerBarDocHeight();
componentDidMount() {
+ // Utils.TraceConsoleLog();
reaction(
// when a multi-selection occurs, remove focus from all active elements to allow keyboad input to go only to global key manager to act upon selection
() => SelectionManager.Views.slice(),
@@ -165,7 +177,11 @@ export class MainView extends ObservableReactComponent<{}> {
scriptTag.async = true;
scriptTag.defer = true;
document.body.appendChild(scriptTag);
- document.getElementById('root')?.addEventListener('scroll', e => (ele => (ele.scrollLeft = ele.scrollTop = 0))(document.getElementById('root')!));
+ document.getElementById('root')?.addEventListener('scroll', () =>
+ (ele => {
+ ele.scrollLeft = ele.scrollTop = 0;
+ })(document.getElementById('root')!)
+ );
const ele = document.getElementById('loader');
const prog = document.getElementById('dash-progress');
if (ele && prog) {
@@ -174,7 +190,9 @@ export class MainView extends ObservableReactComponent<{}> {
prog.style.transition = '1s';
prog.style.width = '100%';
}, 0);
- setTimeout(() => (ele.outerHTML = ''), 1000);
+ setTimeout(() => {
+ ele.outerHTML = '';
+ }, 1000);
}
this._sidebarContent.proto = undefined;
if (!MainView.Live) {
@@ -202,7 +220,7 @@ export class MainView extends ObservableReactComponent<{}> {
'text_scrollHeight',
'text_height',
'hidden',
- //'type_collection',
+ // 'type_collection',
'chromeHidden',
'currentFrame',
]); // can play with these fields on someone else's
@@ -530,7 +548,7 @@ export class MainView extends ObservableReactComponent<{}> {
}
private longPressTimer: NodeJS.Timeout | undefined;
- globalPointerClick = action((e: any) => {
+ globalPointerClick = action(() => {
this.longPressTimer && clearTimeout(this.longPressTimer);
DocumentView.LongPress = false;
});
@@ -540,7 +558,9 @@ export class MainView extends ObservableReactComponent<{}> {
globalPointerDown = action((e: PointerEvent) => {
DocumentView.LongPress = false;
this.longPressTimer = setTimeout(
- action(() => (DocumentView.LongPress = true)),
+ action(() => {
+ DocumentView.LongPress = true;
+ }),
1000
);
DocumentManager.removeOverlayViews();
@@ -559,7 +579,7 @@ export class MainView extends ObservableReactComponent<{}> {
});
initEventListeners = () => {
- window.addEventListener('beforeunload', DocServer.UPDATE_SERVER_CACHE);
+ window.addEventListener('beforeunload', UPDATE_SERVER_CACHE);
window.addEventListener('drop', e => e.preventDefault(), false); // prevent default behavior of navigating to a new web page
window.addEventListener('dragover', e => e.preventDefault(), false);
document.addEventListener('pointerdown', this.globalPointerDown, true);
@@ -607,8 +627,8 @@ export class MainView extends ObservableReactComponent<{}> {
waitForDoubleClick = () => (SnappingManager.ExploreMode ? 'never' : undefined);
headerBarScreenXf = () => new Transform(-this.leftScreenOffsetOfMainDocView - this.leftMenuFlyoutWidth(), -this.headerBarDocHeight(), 1);
mainScreenToLocalXf = () => new Transform(-this.leftScreenOffsetOfMainDocView - this.leftMenuFlyoutWidth(), -this.topOfMainDocContent, 1);
- addHeaderDoc = (doc: Doc | Doc[], annotationKey?: string) => (doc instanceof Doc ? [doc] : doc).reduce((done, doc) => Doc.AddDocToList(this.headerBarDoc, 'data', doc), true);
- removeHeaderDoc = (doc: Doc | Doc[], annotationKey?: string) => (doc instanceof Doc ? [doc] : doc).reduce((done, doc) => Doc.RemoveDocFromList(this.headerBarDoc, 'data', doc), true);
+ addHeaderDoc = (docs: Doc | Doc[]) => (docs instanceof Doc ? [docs] : docs).reduce((done, doc) => Doc.AddDocToList(this.headerBarDoc, 'data', doc), true);
+ removeHeaderDoc = (docs: Doc | Doc[]) => (docs instanceof Doc ? [docs] : docs).reduce((done, doc) => Doc.RemoveDocFromList(this.headerBarDoc, 'data', doc), true);
@computed get headerBarDocView() {
return (
<div className="mainView-headerBar" style={{ height: this.headerBarDocHeight() }}>
@@ -625,10 +645,10 @@ export class MainView extends ObservableReactComponent<{}> {
isDocumentActive={returnTrue} // headerBar is always documentActive (ie, the docView gets pointer events)
isContentActive={returnTrue} // headerBar is awlays contentActive which means its items are always documentActive
ScreenToLocalTransform={this.headerBarScreenXf}
- childHideResizeHandles={true}
+ childHideResizeHandles
childDragAction={dropActionType.move}
- dontRegisterView={true}
- hideResizeHandles={true}
+ dontRegisterView
+ hideResizeHandles
PanelWidth={this.headerBarDocWidth}
PanelHeight={this.headerBarDocHeight}
renderDepth={0}
@@ -664,7 +684,7 @@ export class MainView extends ObservableReactComponent<{}> {
childFilters={returnEmptyFilter}
childFiltersByRanges={returnEmptyFilter}
searchFilterDocs={returnEmptyDoclist}
- suppressSetHeight={true}
+ suppressSetHeight
renderDepth={this._hideUI ? 0 : -1}
/>
</>
@@ -673,7 +693,7 @@ export class MainView extends ObservableReactComponent<{}> {
@computed get dockingContent() {
return (
- <GestureOverlay isActive={LightboxView.LightboxDoc ? false : true}>
+ <GestureOverlay isActive={!LightboxView.LightboxDoc}>
<div
key="docking"
className={`mainView-dockingContent${this._leftMenuFlyoutWidth ? '-flyout' : ''}`}
@@ -697,9 +717,16 @@ export class MainView extends ObservableReactComponent<{}> {
setupMoveUpEvents(
this,
e,
- action(e => ((SettingsManager.Instance.propertiesWidth = Math.max(0, this._dashUIWidth - e.clientX)) ? false : false)),
- action(() => SettingsManager.Instance.propertiesWidth < 5 && (SettingsManager.Instance.propertiesWidth = 0)),
- action(() => (SettingsManager.Instance.propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._dashUIWidth - 50, 250) : 0)),
+ action(() => {
+ SettingsManager.Instance.propertiesWidth = Math.max(0, this._dashUIWidth - e.clientX);
+ return !SettingsManager.Instance.propertiesWidth;
+ }),
+ action(() => {
+ SettingsManager.Instance.propertiesWidth < 5 && (SettingsManager.Instance.propertiesWidth = 0);
+ }),
+ action(() => {
+ SettingsManager.Instance.propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._dashUIWidth - 50, 250) : 0;
+ }),
false
);
};
@@ -709,7 +736,10 @@ export class MainView extends ObservableReactComponent<{}> {
setupMoveUpEvents(
this,
e,
- action(e => ((this._leftMenuFlyoutWidth = Math.max(e.clientX - 58, 0)) ? false : false)),
+ action(ev => {
+ this._leftMenuFlyoutWidth = Math.max(ev.clientX - 58, 0);
+ return false;
+ }),
() => this._leftMenuFlyoutWidth < 5 && this.closeFlyout(),
this.closeFlyout
);
@@ -717,7 +747,8 @@ export class MainView extends ObservableReactComponent<{}> {
sidebarScreenToLocal = () => new Transform(0, -this.topOfSidebarDoc, 1);
mainContainerXf = () => this.sidebarScreenToLocal().translate(-this.leftScreenOffsetOfMainDocView, 0);
- static addDocTabFunc_impl = (doc: Doc, location: OpenWhere): boolean => {
+ static addDocTabFunc_impl = (docs: Doc | Doc[], location: OpenWhere): boolean => {
+ const doc = (docs instanceof Doc ? [docs] : docs).lastElement();
const whereFields = location.split(':');
const keyValue = whereFields.includes(OpenWhereMod.keyvalue);
const whereMods = whereFields.length > 1 ? (whereFields[1] as OpenWhereMod) : OpenWhereMod.none;
@@ -734,7 +765,7 @@ export class MainView extends ObservableReactComponent<{}> {
@computed get flyout() {
return !this._leftMenuFlyoutWidth ? (
- <div key="flyout" className={`mainView-libraryFlyout-out`}>
+ <div key="flyout" className="mainView-libraryFlyout-out">
{this.docButtons}
</div>
) : (
@@ -799,7 +830,7 @@ export class MainView extends ObservableReactComponent<{}> {
if (willOpen) {
switch ((this._panelContent = title)) {
case 'Settings':
- SettingsManager.Instance.open();
+ SettingsManager.Instance.openMgr();
break;
case 'Help':
break;
@@ -837,11 +868,9 @@ export class MainView extends ObservableReactComponent<{}> {
</div>
)}
<div className="properties-container" style={{ width: this.propertiesWidth(), color: SettingsManager.userColor }}>
- {
- <div style={{ display: this.propertiesWidth() < 10 ? 'none' : undefined }}>
- <PropertiesView styleProvider={DefaultStyleProvider} addDocTab={DocumentViewInternal.addDocTabFunc} width={this.propertiesWidth()} height={this.propertiesHeight()} />
- </div>
- }
+ <div style={{ display: this.propertiesWidth() < 10 ? 'none' : undefined }}>
+ <PropertiesView styleProvider={DefaultStyleProvider} addDocTab={DocumentViewInternal.addDocTabFunc} width={this.propertiesWidth()} height={this.propertiesHeight()} />
+ </div>
</div>
</div>
</div>
@@ -878,26 +907,26 @@ export class MainView extends ObservableReactComponent<{}> {
// generate the wrong value from getClientRectangle() -- specifically they return an 'x' that is the flyout's width greater than it should be.
// interactively adjusting the flyout fixes the problem. So does programmatically changing the value after a timeout to something *fractionally* different (ie, 1.5, not 1);)
this._leftMenuFlyoutWidth = this._leftMenuFlyoutWidth || 250;
- //setTimeout(action(() => (this._leftMenuFlyoutWidth += 0.5)));
+ // setTimeout(action(() => (this._leftMenuFlyoutWidth += 0.5)));
this._sidebarContent.proto = DocCast(button.target);
- SettingsManager.Instance.SetLastPressedBtn(button);
+ SettingsManager.Instance.LastPressedBtn = button;
});
closeFlyout = action(() => {
- SettingsManager.Instance.SetLastPressedBtn(undefined);
+ SettingsManager.Instance.LastPressedBtn = undefined;
this._panelContent = 'none';
this._sidebarContent.proto = undefined;
this._leftMenuFlyoutWidth = 0;
});
- remButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && !doc.dragOnlyWithinContainer && Doc.RemoveDocFromList(Doc.MyDockedBtns, 'data', doc), true);
- moveButtonDoc = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => this.remButtonDoc(doc) && addDocument(doc);
- addButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && Doc.AddDocToList(Doc.MyDockedBtns, 'data', doc), true);
+ remButtonDoc = (docs: Doc | Doc[]) => (docs instanceof Doc ? [docs] : docs).reduce((flg: boolean, doc) => flg && !doc.dragOnlyWithinContainer && Doc.RemoveDocFromList(Doc.MyDockedBtns, 'data', doc), true);
+ moveButtonDoc = (docs: Doc | Doc[], targetCol: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => this.remButtonDoc(docs) && addDocument(docs);
+ addButtonDoc = (docs: Doc | Doc[]) => (docs instanceof Doc ? [docs] : docs).reduce((flg: boolean, doc) => flg && Doc.AddDocToList(Doc.MyDockedBtns, 'data', doc), true);
buttonBarXf = () => {
if (!this._docBtnRef.current) return Transform.Identity();
- const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
+ const { scale, translateX, translateY } = ClientUtils.GetScreenTransform(this._docBtnRef.current);
return new Transform(-translateX, -translateY, 1 / scale);
};
@@ -929,7 +958,7 @@ export class MainView extends ObservableReactComponent<{}> {
childFiltersByRanges={returnEmptyFilter}
searchFilterDocs={returnEmptyDoclist}
/>
- {['watching', 'recording'].includes(StrCast(this.userDoc?.presentationMode)) ? <div style={{ border: '.5rem solid green', padding: '5px' }}>{StrCast(this.userDoc?.presentationMode)}</div> : <></>}
+ {['watching', 'recording'].includes(StrCast(this.userDoc?.presentationMode)) ? <div style={{ border: '.5rem solid green', padding: '5px' }}>{StrCast(this.userDoc?.presentationMode)}</div> : null}
</div>
);
}
@@ -939,12 +968,16 @@ export class MainView extends ObservableReactComponent<{}> {
return !dragPar?.layoutDoc.freeform_snapLines ? null : (
<div className="mainView-snapLines">
<svg style={{ width: '100%', height: '100%' }}>
- {SnappingManager.HorizSnapLines.map((l, i) => (
- <line key={i} x1="0" y1={l} x2="2000" y2={l} stroke={lightOrDark(dragPar.layoutDoc.backgroundColor ?? 'gray')} opacity={0.3} strokeWidth={1} strokeDasharray={'2 2'} />
- ))}
- {SnappingManager.VertSnapLines.map((l, i) => (
- <line key={i} y1={this.topOfMainDocContent.toString()} x1={l} y2="2000" x2={l} stroke={lightOrDark(dragPar.layoutDoc.backgroundColor ?? 'gray')} opacity={0.3} strokeWidth={1} strokeDasharray={'2 2'} />
- ))}
+ {[
+ ...SnappingManager.HorizSnapLines.map((l, i) => (
+ // eslint-disable-next-line react/no-array-index-key
+ <line key={'horiz' + i} x1="0" y1={l} x2="2000" y2={l} stroke={lightOrDark(dragPar.layoutDoc.backgroundColor ?? 'gray')} opacity={0.3} strokeWidth={1} strokeDasharray="2 2" />
+ )),
+ ...SnappingManager.VertSnapLines.map((l, i) => (
+ // eslint-disable-next-line react/no-array-index-key
+ <line key={'vert' + i} y1={this.topOfMainDocContent.toString()} x1={l} y2="2000" x2={l} stroke={lightOrDark(dragPar.layoutDoc.backgroundColor ?? 'gray')} opacity={0.3} strokeWidth={1} strokeDasharray="2 2" />
+ )),
+ ]}
</svg>
</div>
);
@@ -961,13 +994,14 @@ export class MainView extends ObservableReactComponent<{}> {
values="1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
- 0 0 0 1 0"></feColorMatrix>
- <feGaussianBlur in="color" stdDeviation="4" result="blur"></feGaussianBlur>
- <feOffset in="blur" dx="0" dy="0" result="offset"></feOffset>
+ 0 0 0 1 0"
+ />
+ <feGaussianBlur in="color" stdDeviation="4" result="blur" />
+ <feOffset in="blur" dx="0" dy="0" result="offset" />
<feMerge>
- <feMergeNode in="bg"></feMergeNode>
- <feMergeNode in="offset"></feMergeNode>
- <feMergeNode in="SourceGraphic"></feMergeNode>
+ <feMergeNode in="bg" />
+ <feMergeNode in="offset" />
+ <feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
@@ -984,7 +1018,11 @@ export class MainView extends ObservableReactComponent<{}> {
color: SettingsManager.userColor,
background: SettingsManager.userBackgroundColor,
}}
- onScroll={() => (ele => (ele.scrollTop = ele.scrollLeft = 0))(document.getElementById('root')!)}
+ onScroll={() =>
+ (ele => {
+ ele.scrollTop = ele.scrollLeft = 0;
+ })(document.getElementById('root')!)
+ }
ref={r => {
r &&
new _global.ResizeObserver(
@@ -1009,23 +1047,31 @@ export class MainView extends ObservableReactComponent<{}> {
<ComponentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDocContent} />
{this._hideUI ? null : <TopBar />}
<LinkDescriptionPopup />
- {DocButtonState.Instance.LinkEditorDocView ? <LinkMenu clearLinkEditor={action(() => (DocButtonState.Instance.LinkEditorDocView = undefined))} docView={DocButtonState.Instance.LinkEditorDocView} /> : null}
- {LinkInfo.Instance?.LinkInfo ? <LinkDocPreview {...LinkInfo.Instance.LinkInfo} /> : null}
-
+ {DocButtonState.Instance.LinkEditorDocView ? (
+ <LinkMenu
+ clearLinkEditor={action(() => {
+ DocButtonState.Instance.LinkEditorDocView = undefined;
+ })}
+ docView={DocButtonState.Instance.LinkEditorDocView}
+ />
+ ) : null}
+ {LinkInfo.Instance?.LinkInfo ? (
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ <LinkDocPreview {...LinkInfo.Instance.LinkInfo} />
+ ) : null}
{((page: string) => {
// prettier-ignore
switch (page) {
- default:
- case 'dashboard': return (<>
+ case 'home': return <DashboardView />;
+ case 'dashboard':
+ default: return (<>
<div key="dashdiv" style={{ position: 'relative', display: this._hideUI || LightboxView.LightboxDoc ? 'none' : undefined, zIndex: 2001 }}>
<CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} toggleTopBar={this.toggleTopBar} topBarHeight={this.headerBarHeightFunc}/>
</div>
{this.mainDashboardArea}
</> );
- case 'home': return <DashboardView />;
}
})(Doc.ActivePage)}
-
<PreviewCursor />
<TaskCompletionBox />
<ContextMenu />
@@ -1049,15 +1095,19 @@ export class MainView extends ObservableReactComponent<{}> {
}
}
-ScriptingGlobals.add(function selectMainMenu(doc: Doc, title: string) {
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(function selectMainMenu(doc: Doc) {
MainView.Instance.selectMenu(doc);
});
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function createNewPresentation() {
return MainView.Instance.createNewPresentation();
}, 'creates a new presentation when called');
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function openPresentation(pres: Doc) {
return MainView.Instance.openPresentation(pres);
}, 'creates a new presentation when called');
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function createNewFolder() {
return MainView.Instance.createNewFolder();
}, 'creates a new folder in myFiles when called');