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.tsx1253
1 files changed, 639 insertions, 614 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 7ee9f5b70..15e1dbe18 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -8,11 +8,9 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Doc, DocListCast, Opt } from '../../fields/Doc';
-import { List } from '../../fields/List';
import { PrefetchProxy } from '../../fields/Proxy';
import { ScriptField } from '../../fields/ScriptField';
import { PromiseValue, StrCast } from '../../fields/Types';
-import { TraceMobx } from '../../fields/util';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick, Utils } from '../../Utils';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
import { DocServer } from '../DocServer';
@@ -34,7 +32,8 @@ import { CollectionDockingView } from './collections/CollectionDockingView';
import { MarqueeOptionsMenu } from './collections/collectionFreeForm/MarqueeOptionsMenu';
import { CollectionLinearView } from './collections/collectionLinear';
import { CollectionMenu } from './collections/CollectionMenu';
-import { CollectionViewType } from './collections/CollectionView';
+import { TreeViewType } from './collections/CollectionTreeView';
+import { CollectionView, CollectionViewType } from './collections/CollectionView';
import "./collections/TreeView.scss";
import { ComponentDecorations } from './ComponentDecorations';
import { ContextMenu } from './ContextMenu';
@@ -44,6 +43,7 @@ import { GestureOverlay } from './GestureOverlay';
import { DASHBOARD_SELECTOR_HEIGHT, LEFT_MENU_WIDTH } from './global/globalCssVariables.scss';
import { Colors } from './global/globalEnums';
import { KeyManager } from './GlobalKeyHandler';
+import { InkTranscription } from './InkTranscription';
import { LightboxView } from './LightboxView';
import { LinkMenu } from './linking/LinkMenu';
import "./MainView.scss";
@@ -51,6 +51,7 @@ import { AudioBox } from './nodes/AudioBox';
import { ButtonType } from './nodes/button/FontIconBox';
import { DocumentLinksButton } from './nodes/DocumentLinksButton';
import { DocumentView } from './nodes/DocumentView';
+import { DashFieldViewMenu } from './nodes/formattedText/DashFieldView';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { RichTextMenu } from './nodes/formattedText/RichTextMenu';
import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
@@ -68,342 +69,342 @@ const _global = (window /* browser */ || global /* node */) as any;
@observer
export class MainView extends React.Component {
- public static Instance: MainView;
- public static Live: boolean = false;
- private _docBtnRef = React.createRef<HTMLDivElement>();
- @observable public LastButton: Opt<Doc>;
- @observable private _windowWidth: number = 0;
- @observable private _windowHeight: number = 0;
- @observable private _dashUIWidth: number = 0; // width of entire main dashboard region including left menu buttons and properties panel (but not including the dashboard selector button row)
- @observable private _dashUIHeight: number = 0; // height of entire main dashboard region including top menu buttons
- @observable private _panelContent: string = "none";
- @observable private _sidebarContent: any = this.userDoc?.sidebar;
- @observable private _leftMenuFlyoutWidth: number = 0;
-
- @computed private get dashboardTabHeight() { return 27; } // 27 comes form lm.config.defaultConfig.dimensions.headerHeight in goldenlayout.js
- @computed private get topOfDashUI() { return Number(DASHBOARD_SELECTOR_HEIGHT.replace("px", "")); }
- @computed private get topOfMainDoc() { return this.topOfDashUI + this.topMenuHeight(); }
- @computed private get topOfMainDocContent() { return this.topOfMainDoc + this.dashboardTabHeight; }
- @computed private get leftScreenOffsetOfMainDocView() { return this.leftMenuWidth() - 2; }
- @computed private get userDoc() { return Doc.UserDoc(); }
- @computed private get colorScheme() { return StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme); }
- @computed private get mainContainer() { return this.userDoc ? CurrentUserUtils.ActiveDashboard : CurrentUserUtils.GuestDashboard; }
- @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs?.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
-
- topMenuHeight = () => 35;
- topMenuWidth = returnZero; // value is ignored ...
- leftMenuWidth = () => Number(LEFT_MENU_WIDTH.replace("px", ""));
- leftMenuHeight = () => this._dashUIHeight;
- leftMenuFlyoutWidth = () => this._leftMenuFlyoutWidth;
- leftMenuFlyoutHeight = () => this._dashUIHeight;
- propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, CurrentUserUtils.propertiesWidth || 0));
- propertiesHeight = () => this._dashUIHeight;
- mainDocViewWidth = () => this._dashUIWidth - this.propertiesWidth() - this.leftMenuWidth();
- mainDocViewHeight = () => this._dashUIHeight;
-
- componentDidMount() {
- document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!));
- const ele = document.getElementById("loader");
- const prog = document.getElementById("dash-progress");
- if (ele && prog) {
- // remove from DOM
- setTimeout(() => {
- clearTimeout();
- prog.style.transition = "1s";
- prog.style.width = "100%";
- }, 0);
- setTimeout(() => ele.outerHTML = '', 1000);
+ public static Instance: MainView;
+ public static Live: boolean = false;
+ private _docBtnRef = React.createRef<HTMLDivElement>();
+ @observable public LastButton: Opt<Doc>;
+ @observable private _windowWidth: number = 0;
+ @observable private _windowHeight: number = 0;
+ @observable private _dashUIWidth: number = 0; // width of entire main dashboard region including left menu buttons and properties panel (but not including the dashboard selector button row)
+ @observable private _dashUIHeight: number = 0; // height of entire main dashboard region including top menu buttons
+ @observable private _panelContent: string = "none";
+ @observable private _sidebarContent: any = this.userDoc?.sidebar;
+ @observable private _leftMenuFlyoutWidth: number = 0;
+
+ @computed private get dashboardTabHeight() { return 27; } // 27 comes form lm.config.defaultConfig.dimensions.headerHeight in goldenlayout.js
+ @computed private get topOfDashUI() { return Number(DASHBOARD_SELECTOR_HEIGHT.replace("px", "")); }
+ @computed private get topOfHeaderBarDoc() { return this.topOfDashUI; }
+ @computed private get topOfSidebarDoc() { return this.topOfDashUI + this.topMenuHeight(); }
+ @computed private get topOfMainDoc() { return this.topOfDashUI + this.topMenuHeight() + this.headerBarDocHeight(); }
+ @computed private get topOfMainDocContent() { return this.topOfMainDoc + this.dashboardTabHeight; }
+ @computed private get leftScreenOffsetOfMainDocView() { return this.leftMenuWidth() - 2; }
+ @computed private get userDoc() { return Doc.UserDoc(); }
+ @computed private get colorScheme() { return StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme); }
+ @computed private get mainContainer() { return this.userDoc ? CurrentUserUtils.ActiveDashboard : CurrentUserUtils.GuestDashboard; }
+ @computed private get headerBarDoc() { return this.userDoc ? CurrentUserUtils.MyHeaderBarDoc : CurrentUserUtils.MyHeaderBarDoc; }
+ @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs?.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
+
+ headerBarDocWidth = () => this.mainDocViewWidth();
+ headerBarDocHeight = () => CurrentUserUtils.headerBarHeight ?? 0;
+ topMenuHeight = () => 35;
+ topMenuWidth = returnZero; // value is ignored ...
+ leftMenuWidth = () => Number(LEFT_MENU_WIDTH.replace("px", ""));
+ leftMenuHeight = () => this._dashUIHeight;
+ leftMenuFlyoutWidth = () => this._leftMenuFlyoutWidth;
+ leftMenuFlyoutHeight = () => this._dashUIHeight;
+ propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, CurrentUserUtils.propertiesWidth || 0));
+ propertiesHeight = () => this._dashUIHeight;
+ mainDocViewWidth = () => this._dashUIWidth - this.propertiesWidth() - this.leftMenuWidth() - this.leftMenuFlyoutWidth();
+ mainDocViewHeight = () => this._dashUIHeight - this.headerBarDocHeight();
+
+ componentDidMount() {
+ document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!));
+ const ele = document.getElementById("loader");
+ const prog = document.getElementById("dash-progress");
+ if (ele && prog) {
+ // remove from DOM
+ setTimeout(() => {
+ clearTimeout();
+ prog.style.transition = "1s";
+ prog.style.width = "100%";
+ }, 0);
+ setTimeout(() => ele.outerHTML = '', 1000);
+ }
+ this._sidebarContent.proto = undefined;
+ if (!MainView.Live) {
+ DocServer.setPlaygroundFields(["dataTransition", "treeViewOpen", "showSidebar", "sidebarWidthPercent", "viewTransition",
+ "panX", "panY", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height", "hideMinimap",
+ "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
+ }
+ DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
+
+ const tag = document.createElement('script');
+ tag.src = "https://www.youtube.com/iframe_api";
+ const firstScriptTag = document.getElementsByTagName('script')[0];
+ firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag);
+ window.removeEventListener("keydown", KeyManager.Instance.handle);
+ window.addEventListener("keydown", KeyManager.Instance.handle);
+ window.removeEventListener("keyup", KeyManager.Instance.unhandle);
+ window.addEventListener("keyup", KeyManager.Instance.unhandle);
+ window.addEventListener("paste", KeyManager.Instance.paste as any);
+ document.addEventListener("dash", (e: any) => { // event used by chrome plugin to tell Dash which document to focus on
+ const id = FormattedTextBox.GetDocFromUrl(e.detail);
+ DocServer.GetRefField(id).then(doc => (doc instanceof Doc) ? DocumentManager.Instance.jumpToDocument(doc, false, undefined, []) : (null));
+ });
+ document.addEventListener("linkAnnotationToDash", Hypothesis.linkListener);
+ this.initEventListeners();
+ }
+
+ componentWillUnMount() {
+ window.removeEventListener("keyup", KeyManager.Instance.unhandle);
+ window.removeEventListener("keydown", KeyManager.Instance.handle);
+ window.removeEventListener("pointerdown", this.globalPointerDown);
+ window.removeEventListener("paste", KeyManager.Instance.paste as any);
+ document.removeEventListener("linkAnnotationToDash", Hypothesis.linkListener);
+ }
+
+ constructor(props: Readonly<{}>) {
+ super(props);
+ MainView.Instance = this;
+ CurrentUserUtils._urlState = HistoryUtil.parseUrl(window.location) || {} as any;
+
+ // causes errors to be generated when modifying an observable outside of an action
+ configure({ enforceActions: "observed" });
+
+ if (window.location.pathname !== "/home") {
+ const pathname = window.location.pathname.substr(1).split("/");
+ if (pathname.length > 1 && pathname[0] === "doc") {
+ CurrentUserUtils.MainDocId = pathname[1];
+ !this.userDoc && DocServer.GetRefField(pathname[1]).then(action(field => field instanceof Doc && (CurrentUserUtils.GuestTarget = field)));
}
- this._sidebarContent.proto = undefined;
- if (!MainView.Live) {
- DocServer.setPlaygroundFields(["dataTransition", "treeViewOpen", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition",
- "panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height", "hideMinimap",
- "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
+ }
+
+ library.add(...[fa.faEdit, fa.faTrash, fa.faTrashAlt, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faCalendar,
+ fa.faSquare, far.faSquare as any, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faMapMarker, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock,
+ fa.faLock, fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointLeft, fa.faHandPointRight, fa.faCompass, fa.faSnowflake, fa.faMicrophone, fa.faKeyboard,
+ fa.faQuestion, fa.faTasks, fa.faPalette, fa.faAngleLeft, fa.faAngleRight, fa.faBell, fa.faCamera, fa.faExpand, fa.faCaretDown, fa.faCaretLeft, fa.faCaretRight,
+ fa.faCaretSquareDown, fa.faCaretSquareRight, fa.faArrowsAltH, fa.faPlus, fa.faMinus, fa.faTerminal, fa.faToggleOn, fa.faFile, fa.faLocationArrow,
+ fa.faSearch, fa.faFileDownload, fa.faFileUpload, fa.faStop, fa.faCalculator, fa.faWindowMaximize, fa.faAddressCard, fa.faQuestionCircle, fa.faArrowLeft,
+ fa.faArrowRight, fa.faArrowDown, fa.faArrowUp, fa.faBolt, fa.faBullseye, fa.faCaretUp, fa.faCat, fa.faCheck, fa.faChevronRight, fa.faChevronLeft, fa.faChevronDown, fa.faChevronUp,
+ fa.faClone, fa.faCloudUploadAlt, fa.faCommentAlt, fa.faCompressArrowsAlt, fa.faCut, fa.faEllipsisV, fa.faEraser, fa.faExclamation, fa.faFileAlt,
+ fa.faFileAudio, fa.faFileVideo, fa.faFilePdf, fa.faFilm, fa.faFilter, fa.faFont, fa.faGlobeAmericas, fa.faGlobeAsia, fa.faHighlighter, fa.faLongArrowAltRight, fa.faMousePointer,
+ fa.faMusic, fa.faObjectGroup, fa.faPause, fa.faPen, fa.faPenNib, fa.faPhone, fa.faPlay, fa.faPortrait, fa.faRedoAlt, fa.faStamp, fa.faStickyNote, fa.faArrowsAltV,
+ fa.faTimesCircle, fa.faThumbtack, fa.faTree, fa.faTv, fa.faUndoAlt, fa.faVideoSlash, fa.faVideo, fa.faAsterisk, fa.faBrain, fa.faImage, fa.faPaintBrush, fa.faTimes, fa.faFlag,
+ fa.faEye, fa.faArrowsAlt, fa.faQuoteLeft, fa.faSortAmountDown, fa.faAlignLeft, fa.faAlignCenter, fa.faAlignRight, fa.faHeading, fa.faRulerCombined,
+ fa.faFillDrip, fa.faLink, fa.faUnlink, fa.faBold, fa.faItalic, fa.faClipboard, fa.faUnderline, fa.faStrikethrough, fa.faSuperscript, fa.faSubscript,
+ fa.faIndent, fa.faEyeDropper, fa.faPaintRoller, fa.faBars, fa.faBrush, fa.faShapes, fa.faEllipsisH, fa.faHandPaper, fa.faMap, fa.faUser, faHireAHelper as any,
+ fa.faTrashRestore, fa.faUsers, fa.faWrench, fa.faCog, fa.faMap, fa.faBellSlash, fa.faExpandAlt, fa.faArchive, fa.faBezierCurve, fa.faCircle, far.faCircle as any,
+ fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, fa.faAngleDoubleDown, fa.faAngleDoubleLeft, fa.faAngleDoubleUp, faBuffer as any, fa.faExpand, fa.faUndo,
+ fa.faSlidersH, fa.faAngleUp, fa.faAngleDown, fa.faPlayCircle, fa.faClock, fa.faRocket, fa.faExchangeAlt, fa.faHashtag, fa.faAlignJustify, fa.faCheckSquare, fa.faListUl,
+ fa.faWindowMinimize, fa.faWindowRestore, fa.faTextWidth, fa.faTextHeight, fa.faClosedCaptioning, fa.faInfoCircle, fa.faTag, fa.faSyncAlt, fa.faPhotoVideo,
+ fa.faArrowAltCircleDown, fa.faArrowAltCircleUp, fa.faArrowAltCircleLeft, fa.faArrowAltCircleRight, fa.faStopCircle, fa.faCheckCircle, fa.faGripVertical,
+ fa.faSortUp, fa.faSortDown, fa.faTable, fa.faTh, fa.faThList, fa.faProjectDiagram, fa.faSignature, fa.faColumns, fa.faChevronCircleUp, fa.faUpload, fa.faBorderAll,
+ fa.faBraille, fa.faChalkboard, fa.faPencilAlt, fa.faEyeSlash, fa.faSmile, fa.faIndent, fa.faOutdent, fa.faChartBar, fa.faBan, fa.faPhoneSlash, fa.faGripLines,
+ fa.faSave, fa.faBookmark, fa.faList, fa.faListOl, fa.faFolderPlus, fa.faLightbulb, fa.faBookOpen, fa.faMapMarkerAlt, fa.faSearchPlus, fa.faVolumeUp, fa.faVolumeDown, fa.faSquareRootAlt]);
+ this.initAuthenticationRouters();
+ }
+
+ globalPointerDown = action((e: PointerEvent) => {
+ AudioBox.Enabled = true;
+ const targets = document.elementsFromPoint(e.x, e.y);
+ if (targets.length) {
+ const targClass = targets[0].className.toString();
+ !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
+ !["timeline-menu-desc", "timeline-menu-item", "timeline-menu-input"].includes(targClass) && TimelineMenu.Instance.closeMenu();
+ }
+ });
+
+ initEventListeners = () => {
+ 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("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined));
+ document.addEventListener("pointerdown", this.globalPointerDown);
+ document.addEventListener("click", (e: MouseEvent) => {
+ if (!e.cancelBubble) {
+ const pathstr = (e as any)?.path?.map((p: any) => p.classList?.toString()).join();
+ if (pathstr?.includes("libraryFlyout")) {
+ SelectionManager.DeselectAll();
+ }
}
- DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
-
- const tag = document.createElement('script');
- tag.src = "https://www.youtube.com/iframe_api";
- const firstScriptTag = document.getElementsByTagName('script')[0];
- firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag);
- window.removeEventListener("keydown", KeyManager.Instance.handle);
- window.addEventListener("keydown", KeyManager.Instance.handle);
- window.removeEventListener("keyup", KeyManager.Instance.unhandle);
- window.addEventListener("keyup", KeyManager.Instance.unhandle);
- window.addEventListener("paste", KeyManager.Instance.paste as any);
- document.addEventListener("dash", (e: any) => { // event used by chrome plugin to tell Dash which document to focus on
- const id = FormattedTextBox.GetDocFromUrl(e.detail);
- DocServer.GetRefField(id).then(doc => (doc instanceof Doc) ? DocumentManager.Instance.jumpToDocument(doc, false, undefined) : (null));
+ }, false);
+ document.oncontextmenu = () => false;
+ }
+
+ initAuthenticationRouters = async () => {
+ // Load the user's active dashboard, or create a new one if initial session after signup
+ const received = CurrentUserUtils.MainDocId;
+ if (received && !this.userDoc) {
+ reaction(() => CurrentUserUtils.GuestTarget, target => target && CurrentUserUtils.createNewDashboard(Doc.UserDoc()), { fireImmediately: true });
+ } else {
+ PromiseValue(this.userDoc.activeDashboard).then(dash => {
+ if (dash instanceof Doc) CurrentUserUtils.openDashboard(this.userDoc, dash);
+ else CurrentUserUtils.createNewDashboard(this.userDoc);
});
- document.addEventListener("linkAnnotationToDash", Hypothesis.linkListener);
- this.initEventListeners();
- }
-
- componentWillUnMount() {
- window.removeEventListener("keyup", KeyManager.Instance.unhandle);
- window.removeEventListener("keydown", KeyManager.Instance.handle);
- window.removeEventListener("pointerdown", this.globalPointerDown);
- window.removeEventListener("paste", KeyManager.Instance.paste as any);
- document.removeEventListener("linkAnnotationToDash", Hypothesis.linkListener);
- }
-
- constructor(props: Readonly<{}>) {
- super(props);
- MainView.Instance = this;
- CurrentUserUtils._urlState = HistoryUtil.parseUrl(window.location) || {} as any;
-
- // causes errors to be generated when modifying an observable outside of an action
- configure({ enforceActions: "observed" });
-
- if (window.location.pathname !== "/home") {
- const pathname = window.location.pathname.substr(1).split("/");
- if (pathname.length > 1 && pathname[0] === "doc") {
- CurrentUserUtils.MainDocId = pathname[1];
- !this.userDoc && DocServer.GetRefField(pathname[1]).then(action(field => field instanceof Doc && (CurrentUserUtils.GuestTarget = field)));
- }
- }
-
- library.add(...[fa.faEdit, fa.faTrash, fa.faTrashAlt, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faCalendar, fa.faVideoSlash, fa.faVideo,
- fa.faSquare, far.faSquare as any, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faMapMarker, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock,
- fa.faLock, fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointLeft, fa.faHandPointRight, fa.faCompass, fa.faSnowflake, fa.faMicrophone, fa.faKeyboard,
- fa.faQuestion, fa.faTasks, fa.faPalette, fa.faAngleLeft, fa.faAngleRight, fa.faBell, fa.faCamera, fa.faExpand, fa.faCaretDown, fa.faCaretLeft, fa.faCaretRight,
- fa.faCaretSquareDown, fa.faCaretSquareRight, fa.faArrowsAltH, fa.faPlus, fa.faMinus, fa.faTerminal, fa.faToggleOn, fa.faFile, fa.faLocationArrow,
- fa.faSearch, fa.faFileDownload, fa.faFileUpload, fa.faStop, fa.faCalculator, fa.faWindowMaximize, fa.faAddressCard, fa.faQuestionCircle, fa.faArrowLeft,
- fa.faArrowRight, fa.faArrowDown, fa.faArrowUp, fa.faBolt, fa.faBullseye, fa.faCaretUp, fa.faCat, fa.faCheck, fa.faChevronRight, fa.faChevronLeft, fa.faChevronDown, fa.faChevronUp,
- fa.faClone, fa.faCloudUploadAlt, fa.faCommentAlt, fa.faCompressArrowsAlt, fa.faCut, fa.faEllipsisV, fa.faEraser, fa.faExclamation, fa.faFileAlt,
- fa.faFileAudio, fa.faFileVideo, fa.faFilePdf, fa.faFilm, fa.faFilter, fa.faFont, fa.faGlobeAmericas, fa.faGlobeAsia, fa.faHighlighter, fa.faLongArrowAltRight, fa.faMousePointer,
- fa.faMusic, fa.faObjectGroup, fa.faPause, fa.faPen, fa.faPenNib, fa.faPhone, fa.faPlay, fa.faPortrait, fa.faRedoAlt, fa.faStamp, fa.faStickyNote, fa.faArrowsAltV,
- fa.faTimesCircle, fa.faThumbtack, fa.faTree, fa.faTv, fa.faUndoAlt, fa.faVideo, fa.faAsterisk, fa.faBrain, fa.faImage, fa.faPaintBrush, fa.faTimes,
- fa.faEye, fa.faArrowsAlt, fa.faQuoteLeft, fa.faSortAmountDown, fa.faAlignLeft, fa.faAlignCenter, fa.faAlignRight, fa.faHeading, fa.faRulerCombined,
- fa.faFillDrip, fa.faLink, fa.faUnlink, fa.faBold, fa.faItalic, fa.faClipboard, fa.faUnderline, fa.faStrikethrough, fa.faSuperscript, fa.faSubscript,
- fa.faIndent, fa.faEyeDropper, fa.faPaintRoller, fa.faBars, fa.faBrush, fa.faShapes, fa.faEllipsisH, fa.faHandPaper, fa.faMap, fa.faUser, faHireAHelper as any,
- fa.faTrashRestore, fa.faUsers, fa.faWrench, fa.faCog, fa.faMap, fa.faBellSlash, fa.faExpandAlt, fa.faArchive, fa.faBezierCurve, fa.faCircle, far.faCircle as any,
- fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer as any, fa.faExpand, fa.faUndo, fa.faSlidersH, fa.faAngleDoubleLeft, fa.faAngleUp,
- fa.faAngleDown, fa.faPlayCircle, fa.faClock, fa.faRocket, fa.faExchangeAlt, fa.faHashtag, fa.faAlignJustify, fa.faCheckSquare, fa.faListUl,
- fa.faWindowMinimize, fa.faWindowRestore, fa.faTextWidth, fa.faTextHeight, fa.faClosedCaptioning, fa.faInfoCircle, fa.faTag, fa.faSyncAlt, fa.faPhotoVideo,
- fa.faArrowAltCircleDown, fa.faArrowAltCircleUp, fa.faArrowAltCircleLeft, fa.faArrowAltCircleRight, fa.faStopCircle, fa.faCheckCircle, fa.faGripVertical,
- fa.faSortUp, fa.faSortDown, fa.faTable, fa.faTh, fa.faThList, fa.faProjectDiagram, fa.faSignature, fa.faColumns, fa.faChevronCircleUp, fa.faUpload, fa.faBorderAll,
- fa.faBraille, fa.faChalkboard, fa.faPencilAlt, fa.faEyeSlash, fa.faSmile, fa.faIndent, fa.faOutdent, fa.faChartBar, fa.faBan, fa.faPhoneSlash, fa.faGripLines,
- fa.faSave, fa.faBookmark, fa.faList, fa.faListOl, fa.faFolderPlus, fa.faLightbulb, fa.faBookOpen, fa.faMapMarkerAlt, fa.faSearchPlus, fa.faVolumeUp, fa.faVolumeDown]);
- this.initAuthenticationRouters();
- }
-
- globalPointerDown = action((e: PointerEvent) => {
- AudioBox.Enabled = true;
- const targets = document.elementsFromPoint(e.x, e.y);
- if (targets.length) {
- const targClass = targets[0].className.toString();
- !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
- !["timeline-menu-desc", "timeline-menu-item", "timeline-menu-input"].includes(targClass) && TimelineMenu.Instance.closeMenu();
- }
- });
-
- initEventListeners = () => {
- 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("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined));
- document.addEventListener("pointerdown", this.globalPointerDown);
- document.addEventListener("click", (e: MouseEvent) => {
- if (!e.cancelBubble) {
- const pathstr = (e as any)?.path?.map((p: any) => p.classList?.toString()).join();
- if (pathstr?.includes("libraryFlyout")) {
- SelectionManager.DeselectAll();
- }
- }
- }, false);
- document.oncontextmenu = () => false;
- }
-
- initAuthenticationRouters = async () => {
- // Load the user's active dashboard, or create a new one if initial session after signup
- const received = CurrentUserUtils.MainDocId;
- if (received && !this.userDoc) {
- reaction(() => CurrentUserUtils.GuestTarget, target => target && CurrentUserUtils.createNewDashboard(Doc.UserDoc()), { fireImmediately: true });
- } else {
- if (received && CurrentUserUtils._urlState.sharing) {
- reaction(() => CollectionDockingView.Instance && CollectionDockingView.Instance.initialized,
- initialized => initialized && received && DocServer.GetRefField(received).then(docField => {
- if (docField instanceof Doc && docField._viewType !== CollectionViewType.Docking) {
- CollectionDockingView.AddSplit(docField, "right");
- }
- }),
- );
- }
- const activeDash = PromiseValue(this.userDoc.activeDashboard);
- activeDash.then(dash => {
- if (dash instanceof Doc) CurrentUserUtils.openDashboard(this.userDoc, dash);
- else CurrentUserUtils.createNewDashboard(this.userDoc);
- });
- }
- }
-
- @action
- createNewPresentation = async () => {
- if (!await this.userDoc.myTrails) {
- this.userDoc.myTrails = new PrefetchProxy(Docs.Create.TreeDocument([], {
- title: "TRAILS", childDontRegisterViews: true, _height: 100, _forceActive: true, boxShadow: "0 0", _lockedPosition: true, treeViewOpen: true, system: true
- }));
- }
- const pres = Docs.Create.PresDocument(new List<Doc>(),
- { title: "Untitled Trail", _viewType: CollectionViewType.Stacking, _fitWidth: true, _width: 400, _height: 500, targetDropAction: "alias", _chromeHidden: true, boxShadow: "0 0" });
- CollectionDockingView.AddSplit(pres, "right");
- this.userDoc.activePresentation = pres;
- Doc.AddDocToList(this.userDoc.myTrails as Doc, "data", pres);
- }
-
- @action
- createNewFolder = async () => {
- if (!await this.userDoc.myFilesystem) {
- this.userDoc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true });
- const newFolder = ScriptField.MakeFunction(`createNewFolder()`, { scriptContext: "any" })!;
- const newFolderButton: Doc = Docs.Create.FontIconDocument({
- onClick: newFolder, _forceActive: true, toolTip: "New folder", _stayInCollection: true, _hideContextMenu: true, title: "New folder",
- btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New folder", icon: "folder-plus", system: true
- });
- this.userDoc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([this.userDoc.myFileOrphans as Doc], {
- title: "My Documents", _showTitle: "title", buttonMenu: true, buttonMenuDoc: newFolderButton, _height: 100,
- treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
- treeViewTruncateTitleWidth: 150, ignoreClick: true,
- isFolder: true, treeViewType: "fileSystem", childHideLinkButton: true,
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "proto", system: true,
- explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard."
- }));
- }
- const folder = Docs.Create.TreeDocument([], { title: "Untitled folder", _stayInCollection: true, isFolder: true });
- Doc.AddDocToList(this.userDoc.myFilesystem as Doc, "data", folder);
- }
-
- @computed get mainDocView() {
- return <DocumentView key="main"
- Document={this.mainContainer!}
- DataDoc={undefined}
- addDocument={undefined}
- addDocTab={this.addDocTabFunc}
- pinToPres={emptyFunction}
- docViewPath={returnEmptyDoclist}
- layerProvider={undefined}
- styleProvider={undefined}
- rootSelected={returnTrue}
- isContentActive={returnTrue}
- removeDocument={undefined}
- ScreenToLocalTransform={Transform.Identity}
- PanelWidth={this.mainDocViewWidth}
- PanelHeight={this.mainDocViewHeight}
- focus={DocUtils.DefaultFocus}
- whenChildContentsActiveChanged={emptyFunction}
- bringToFront={emptyFunction}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- suppressSetHeight={true}
- renderDepth={-1}
- />;
- }
-
- @computed get dockingContent() {
- return <div key="docking" className={`mainView-dockingContent${this._leftMenuFlyoutWidth ? "-flyout" : ""}`} onDrop={e => { e.stopPropagation(); e.preventDefault(); }}
- style={{
- minWidth: `calc(100% - ${this._leftMenuFlyoutWidth + this.leftMenuWidth() + this.propertiesWidth()}px)`,
- transform: LightboxView.LightboxDoc ? "scale(0.0001)" : undefined,
- }}>
- {!this.mainContainer ? (null) : this.mainDocView}
- </div>;
- }
-
- @action
- onPropertiesPointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e,
- action(e => (CurrentUserUtils.propertiesWidth = Math.max(0, this._dashUIWidth - e.clientX)) ? false : false),
- action(() => CurrentUserUtils.propertiesWidth < 5 && (CurrentUserUtils.propertiesWidth = 0)),
- action(() => CurrentUserUtils.propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._dashUIWidth - 50, 250) : 0), false);
- }
-
- @action
- onFlyoutPointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e,
- action(e => (this._leftMenuFlyoutWidth = Math.max(e.clientX - 58, 0)) ? false : false),
- () => this._leftMenuFlyoutWidth < 5 && this.closeFlyout(),
- this.closeFlyout);
- }
-
- sidebarScreenToLocal = () => new Transform(0, -this.topOfMainDoc, 1);
- mainContainerXf = () => this.sidebarScreenToLocal().translate(-this.leftScreenOffsetOfMainDocView, 0);
- addDocTabFunc = (doc: Doc, location: string): boolean => {
- const locationFields = doc._viewType === CollectionViewType.Docking ? ["dashboard"] : location.split(":");
- const locationParams = locationFields.length > 1 ? locationFields[1] : "";
- if (doc.dockingConfig) return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
- switch (locationFields[0]) {
- case "dashboard": return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
- case "close": return CollectionDockingView.CloseSplit(doc, locationParams);
- case "fullScreen": return CollectionDockingView.OpenFullScreen(doc);
- case "lightbox": return LightboxView.AddDocTab(doc, location);
- case "toggle": return CollectionDockingView.ToggleSplit(doc, locationParams);
- case "inPlace":
- case "add":
- default:
- return CollectionDockingView.AddSplit(doc, locationParams);
- }
- }
-
-
- @computed get flyout() {
- return !this._leftMenuFlyoutWidth ? <div key="flyout" className={`mainView-libraryFlyout-out`}>
- {this.docButtons}
- </div> :
- <div key="libFlyout" className="mainView-libraryFlyout" style={{ minWidth: this._leftMenuFlyoutWidth, width: this._leftMenuFlyoutWidth }} >
- <div className="mainView-contentArea" >
- <DocumentView
- Document={this._sidebarContent.proto || this._sidebarContent}
- DataDoc={undefined}
- addDocument={undefined}
- addDocTab={this.addDocTabFunc}
- pinToPres={emptyFunction}
- docViewPath={returnEmptyDoclist}
- layerProvider={undefined}
- styleProvider={this._sidebarContent.proto === Doc.UserDoc().myDashboards || this._sidebarContent.proto === Doc.UserDoc().myFilesystem ? DashboardStyleProvider : DefaultStyleProvider}
- rootSelected={returnTrue}
- removeDocument={returnFalse}
- ScreenToLocalTransform={this.mainContainerXf}
- PanelWidth={this.leftMenuFlyoutWidth}
- PanelHeight={this.leftMenuFlyoutHeight}
- renderDepth={0}
- isContentActive={returnTrue}
- scriptContext={CollectionDockingView.Instance?.props.Document}
- focus={DocUtils.DefaultFocus}
- whenChildContentsActiveChanged={emptyFunction}
- bringToFront={emptyFunction}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- />
- </div>
- {this.docButtons}
- </div>;
- }
-
- @computed get leftMenuPanel() {
- return <div key="menu" className="mainView-leftMenuPanel">
- <DocumentView
- Document={Doc.UserDoc().menuStack as Doc}
+ }
+ }
+
+ @action
+ createNewPresentation = async () => {
+ if (!await this.userDoc.myTrails) {
+ this.userDoc.myTrails = new PrefetchProxy(Docs.Create.TreeDocument([], {
+ title: "TRAILS", childDontRegisterViews: true, _height: 100, _forceActive: true, boxShadow: "0 0", _lockedPosition: true, treeViewOpen: true, system: true
+ }));
+ }
+ const pres = Docs.Create.PresDocument({ title: "Untitled Trail", _viewType: CollectionViewType.Stacking, _fitWidth: true, _width: 400, _height: 500, targetDropAction: "alias", _chromeHidden: true, boxShadow: "0 0" });
+ CollectionDockingView.AddSplit(pres, "left");
+ this.userDoc.activePresentation = pres;
+ Doc.AddDocToList(this.userDoc.myTrails as Doc, "data", pres);
+ }
+
+ @action
+ createNewFolder = async () => {
+ if (!await this.userDoc.myFilesystem) {
+ this.userDoc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true });
+ const newFolder = ScriptField.MakeFunction(`createNewFolder()`, { scriptContext: "any" })!;
+ const newFolderButton: Doc = Docs.Create.FontIconDocument({
+ onClick: newFolder, _forceActive: true, toolTip: "New folder", _stayInCollection: true, _hideContextMenu: true, title: "New folder",
+ btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New folder", icon: "folder-plus", system: true
+ });
+ this.userDoc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([this.userDoc.myFileOrphans as Doc], {
+ title: "My Documents", _showTitle: "title", buttonMenu: true, buttonMenuDoc: newFolderButton, _height: 100,
+ treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
+ treeViewTruncateTitleWidth: 150, ignoreClick: true,
+ isFolder: true, treeViewType: TreeViewType.fileSystem, childHideLinkButton: true,
+ _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "proto", system: true,
+ explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard."
+ }));
+ }
+ const folder = Docs.Create.TreeDocument([], { title: "Untitled folder", _stayInCollection: true, isFolder: true });
+ Doc.AddDocToList(this.userDoc.myFilesystem as Doc, "data", folder);
+ }
+
+ @observable _exploreMode = false;
+ @computed get exploreMode() {
+ 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);
+
+ @computed get headerBarDocView() {
+ return <div className="mainView-headerBar" style={{ height: this.headerBarDocHeight() }}>
+ <DocumentView key="headerBarDoc"
+ Document={this.headerBarDoc}
+ DataDoc={undefined}
+ addDocument={undefined}
+ addDocTab={this.addDocTabFunc}
+ pinToPres={emptyFunction}
+ docViewPath={returnEmptyDoclist}
+ styleProvider={DefaultStyleProvider}
+ rootSelected={returnTrue}
+ removeDocument={returnFalse}
+ fitContentsToDoc={returnTrue}
+ 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={returnTrue}
+ hideResizeHandles={true}
+ PanelWidth={this.headerBarDocWidth}
+ PanelHeight={this.headerBarDocHeight}
+ renderDepth={0}
+ focus={DocUtils.DefaultFocus}
+ whenChildContentsActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ /></div>;
+ }
+ @computed get mainDocView() {
+ return <>
+ {this.headerBarDocView}
+ <DocumentView key="main"
+ Document={this.mainContainer!}
+ DataDoc={undefined}
+ addDocument={undefined}
+ addDocTab={this.addDocTabFunc}
+ pinToPres={emptyFunction}
+ docViewPath={returnEmptyDoclist}
+ styleProvider={undefined}
+ rootSelected={returnTrue}
+ isContentActive={returnTrue}
+ removeDocument={undefined}
+ ScreenToLocalTransform={Transform.Identity}
+ PanelWidth={this.mainDocViewWidth}
+ PanelHeight={this.mainDocViewHeight}
+ focus={DocUtils.DefaultFocus}
+ whenChildContentsActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ suppressSetHeight={true}
+ renderDepth={-1}
+ /></>;
+ }
+
+ @computed get dockingContent() {
+ return <div key="docking" className={`mainView-dockingContent${this._leftMenuFlyoutWidth ? "-flyout" : ""}`} onDrop={e => { e.stopPropagation(); e.preventDefault(); }}
+ style={{
+ minWidth: `calc(100% - ${this._leftMenuFlyoutWidth + this.leftMenuWidth() + this.propertiesWidth()}px)`,
+ transform: LightboxView.LightboxDoc ? "scale(0.0001)" : undefined,
+ }}>
+ {!this.mainContainer ? (null) : this.mainDocView}
+ </div>;
+ }
+
+ @action
+ onPropertiesPointerDown = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e,
+ action(e => (CurrentUserUtils.propertiesWidth = Math.max(0, this._dashUIWidth - e.clientX)) ? false : false),
+ action(() => CurrentUserUtils.propertiesWidth < 5 && (CurrentUserUtils.propertiesWidth = 0)),
+ action(() => CurrentUserUtils.propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._dashUIWidth - 50, 250) : 0), false);
+ }
+
+ @action
+ onFlyoutPointerDown = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e,
+ action(e => (this._leftMenuFlyoutWidth = Math.max(e.clientX - 58, 0)) ? false : false),
+ () => this._leftMenuFlyoutWidth < 5 && this.closeFlyout(),
+ this.closeFlyout);
+ }
+
+ sidebarScreenToLocal = () => new Transform(0, -this.topOfSidebarDoc, 1);
+ mainContainerXf = () => this.sidebarScreenToLocal().translate(-this.leftScreenOffsetOfMainDocView, 0);
+ addDocTabFunc = (doc: Doc, location: string): boolean => {
+ const locationFields = doc._viewType === CollectionViewType.Docking ? ["dashboard"] : location.split(":");
+ const locationParams = locationFields.length > 1 ? locationFields[1] : "";
+ if (doc.dockingConfig) return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
+ switch (locationFields[0]) {
+ case "dashboard": return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
+ case "close": return CollectionDockingView.CloseSplit(doc, locationParams);
+ case "fullScreen": return CollectionDockingView.OpenFullScreen(doc);
+ case "lightbox": return LightboxView.AddDocTab(doc, location);
+ case "toggle": return CollectionDockingView.ToggleSplit(doc, locationParams);
+ case "inPlace":
+ case "add":
+ default:
+ return CollectionDockingView.AddSplit(doc, locationParams);
+ }
+ }
+
+
+ @computed get flyout() {
+ return !this._leftMenuFlyoutWidth ? <div key="flyout" className={`mainView-libraryFlyout-out`}>
+ {this.docButtons}
+ </div> :
+ <div key="libFlyout" className="mainView-libraryFlyout" style={{ minWidth: this._leftMenuFlyoutWidth, width: this._leftMenuFlyoutWidth }} >
+ <div className="mainView-contentArea" >
+ <DocumentView
+ Document={this._sidebarContent.proto || this._sidebarContent}
DataDoc={undefined}
addDocument={undefined}
addDocTab={this.addDocTabFunc}
pinToPres={emptyFunction}
+ docViewPath={returnEmptyDoclist}
+ styleProvider={this._sidebarContent.proto === Doc.UserDoc().myDashboards || this._sidebarContent.proto === Doc.UserDoc().myFilesystem ? DashboardStyleProvider : DefaultStyleProvider}
rootSelected={returnTrue}
removeDocument={returnFalse}
- ScreenToLocalTransform={this.sidebarScreenToLocal}
- PanelWidth={this.leftMenuWidth}
- PanelHeight={this.leftMenuHeight}
+ ScreenToLocalTransform={this.mainContainerXf}
+ PanelWidth={this.leftMenuFlyoutWidth}
+ PanelHeight={this.leftMenuFlyoutHeight}
renderDepth={0}
- docViewPath={returnEmptyDoclist}
- focus={DocUtils.DefaultFocus}
- styleProvider={DefaultStyleProvider}
- layerProvider={undefined}
isContentActive={returnTrue}
+ scriptContext={CollectionDockingView.Instance?.props.Document}
+ focus={DocUtils.DefaultFocus}
whenChildContentsActiveChanged={emptyFunction}
bringToFront={emptyFunction}
docFilters={returnEmptyFilter}
@@ -411,301 +412,325 @@ export class MainView extends React.Component {
searchFilterDocs={returnEmptyDoclist}
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined}
- scriptContext={this}
- />
+ />
+ </div>
+ {this.docButtons}
</div>;
- }
-
- @action
- selectMenu = (button: Doc) => {
- const title = StrCast(Doc.GetProto(button).title);
- const willOpen = !this._leftMenuFlyoutWidth || this._panelContent !== title;
- this.closeFlyout();
- if (willOpen) {
- switch (this._panelContent = title) {
- case "Settings":
- SettingsManager.Instance.open();
- break;
- case "Help":
- break;
- default:
- this.expandFlyout(button);
- }
+ }
+
+ @computed get leftMenuPanel() {
+ return <div key="menu" className="mainView-leftMenuPanel">
+ <DocumentView
+ Document={Doc.UserDoc().menuStack as Doc}
+ DataDoc={undefined}
+ addDocument={undefined}
+ addDocTab={this.addDocTabFunc}
+ pinToPres={emptyFunction}
+ rootSelected={returnTrue}
+ removeDocument={returnFalse}
+ ScreenToLocalTransform={this.sidebarScreenToLocal}
+ PanelWidth={this.leftMenuWidth}
+ PanelHeight={this.leftMenuHeight}
+ renderDepth={0}
+ docViewPath={returnEmptyDoclist}
+ focus={DocUtils.DefaultFocus}
+ styleProvider={DefaultStyleProvider}
+ isContentActive={returnTrue}
+ whenChildContentsActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ scriptContext={this}
+ />
+ </div>;
+ }
+
+ @action
+ selectMenu = (button: Doc) => {
+ const title = StrCast(Doc.GetProto(button).title);
+ const willOpen = !this._leftMenuFlyoutWidth || this._panelContent !== title;
+ this.closeFlyout();
+ if (willOpen) {
+ switch (this._panelContent = title) {
+ case "Settings":
+ SettingsManager.Instance.open();
+ break;
+ case "Help":
+ break;
+ default:
+ this.expandFlyout(button);
}
- return true;
- }
-
- @computed get mainInnerContent() {
- const leftMenuFlyoutWidth = this._leftMenuFlyoutWidth + this.leftMenuWidth();
- const width = this.propertiesWidth() + leftMenuFlyoutWidth;
- return <>
- {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} >
- <FontAwesomeIcon icon="chevron-left" color={this.colorScheme === ColorScheme.Dark ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
- </div>
- <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>
- <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>
- </div>
- </div>
- </>;
- }
-
- @computed get mainDashboardArea() {
- return !this.userDoc ? (null) :
- <div className="mainView-dashboardArea" ref={r => {
- r && new _global.ResizeObserver(action(() => {
- this._dashUIWidth = r.getBoundingClientRect().width;
- this._dashUIHeight = r.getBoundingClientRect().height;
- })).observe(r);
- }} style={{
- color: this.colorScheme === ColorScheme.Dark ? "rgb(205,205,205)" : "black",
- height: `calc(100% - ${this.topOfDashUI + this.topMenuHeight()}px)`,
- width: "100%",
- }} >
- {this.mainInnerContent}
- </div>;
- }
-
-
- expandFlyout = action((button: Doc) => {
- // bcz: What's going on here!?
- // Chrome(not firefox) seems to have a bug when the flyout expands and there's a zoomed freeform tab. All of the div below the CollectionFreeFormView's main div
- // 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), 0);
-
- this._sidebarContent.proto = button.target as any;
- this.LastButton = button;
- });
-
- closeFlyout = action(() => {
- this.LastButton = 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.RemoveDocFromList(Doc.UserDoc().dockedBtns as Doc, "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.UserDoc().dockedBtns as Doc, "data", doc), true);
-
- buttonBarXf = () => {
- if (!this._docBtnRef.current) return Transform.Identity();
- const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
- return new Transform(-translateX, -translateY, 1 / scale);
- }
-
- @computed get docButtons() {
- return !(this.userDoc.dockedBtns instanceof Doc) ? (null) :
- <div className="mainView-docButtons" ref={this._docBtnRef} style={{ height: !this.userDoc.dockedBtns.linearViewIsExpanded ? "42px" : undefined }} >
- <CollectionLinearView
- Document={this.userDoc.dockedBtns}
- DataDoc={undefined}
- fieldKey={"data"}
- dropAction={"alias"}
- setHeight={returnFalse}
- styleProvider={DefaultStyleProvider}
- layerProvider={undefined}
- rootSelected={returnTrue}
- bringToFront={emptyFunction}
- select={emptyFunction}
- isAnyChildContentActive={returnFalse}
- isContentActive={emptyFunction}
- isSelected={returnFalse}
- docViewPath={returnEmptyDoclist}
- moveDocument={this.moveButtonDoc}
- CollectionView={undefined}
- addDocument={this.addButtonDoc}
- addDocTab={this.addDocTabFunc}
- pinToPres={emptyFunction}
- removeDocument={this.remButtonDoc}
- ScreenToLocalTransform={this.buttonBarXf}
- PanelWidth={this.leftMenuFlyoutWidth}
- PanelHeight={this.leftMenuFlyoutHeight}
- renderDepth={0}
- focus={DocUtils.DefaultFocus}
- whenChildContentsActiveChanged={emptyFunction}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined} />
- {['watching', 'recording'].includes(String(this.userDoc?.presentationMode) ?? '') ? <div style={{ border: '.5rem solid green', padding: '5px' }}>{this.userDoc?.presentationMode}</div> : <></>}
- </div>;
- }
- @computed get snapLines() {
- return !this.userDoc.showSnapLines ? (null) : <div className="mainView-snapLines">
- <svg style={{ width: "100%", height: "100%" }}>
- {SnappingManager.horizSnapLines().map(l => <line x1="0" y1={l} x2="2000" y2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
- {SnappingManager.vertSnapLines().map(l => <line y1="0" x1={l} y2="2000" x2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
- </svg>
+ }
+ return true;
+ }
+
+ @computed get mainInnerContent() {
+ const leftMenuFlyoutWidth = this._leftMenuFlyoutWidth + this.leftMenuWidth();
+ const width = this.propertiesWidth() + leftMenuFlyoutWidth;
+ return <>
+ {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} >
+ <FontAwesomeIcon icon="chevron-left" color={this.colorScheme === ColorScheme.Dark ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
+ </div>
+ <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>
+ <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>
+ </div>
+ </div>
+ </>;
+ }
+
+
+ @computed get mainDashboardArea() {
+ return !this.userDoc ? (null) :
+ <div className="mainView-dashboardArea" ref={r => {
+ r && new _global.ResizeObserver(action(() => {
+ this._dashUIWidth = r.getBoundingClientRect().width;
+ this._dashUIHeight = r.getBoundingClientRect().height;
+ })).observe(r);
+ }} style={{
+ color: this.colorScheme === ColorScheme.Dark ? "rgb(205,205,205)" : "black",
+ height: `calc(100% - ${this.topOfDashUI + this.topMenuHeight()}px)`,
+ width: "100%",
+ }} >
+ {this.mainInnerContent}
+ </div>;
+ }
+
+
+ expandFlyout = action((button: Doc) => {
+ // bcz: What's going on here!?
+ // Chrome(not firefox) seems to have a bug when the flyout expands and there's a zoomed freeform tab. All of the div below the CollectionFreeFormView's main div
+ // 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), 0);
+
+ this._sidebarContent.proto = button.target as any;
+ this.LastButton = button;
+ });
+
+ closeFlyout = action(() => {
+ this.LastButton = 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.RemoveDocFromList(Doc.UserDoc().dockedBtns as Doc, "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.UserDoc().dockedBtns as Doc, "data", doc), true);
+
+ buttonBarXf = () => {
+ if (!this._docBtnRef.current) return Transform.Identity();
+ const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
+ return new Transform(-translateX, -translateY, 1 / scale);
+ }
+
+ @computed get docButtons() {
+ return !(this.userDoc.dockedBtns instanceof Doc) ? (null) :
+ <div className="mainView-docButtons" ref={this._docBtnRef} style={{ height: !this.userDoc.dockedBtns.linearViewIsExpanded ? "42px" : undefined }} >
+ <CollectionLinearView
+ Document={this.userDoc.dockedBtns}
+ DataDoc={undefined}
+ fieldKey={"data"}
+ dropAction={"alias"}
+ setHeight={returnFalse}
+ styleProvider={DefaultStyleProvider}
+ rootSelected={returnTrue}
+ bringToFront={emptyFunction}
+ select={emptyFunction}
+ isAnyChildContentActive={returnFalse}
+ isContentActive={emptyFunction}
+ isSelected={returnFalse}
+ docViewPath={returnEmptyDoclist}
+ moveDocument={this.moveButtonDoc}
+ CollectionView={undefined}
+ addDocument={this.addButtonDoc}
+ addDocTab={this.addDocTabFunc}
+ pinToPres={emptyFunction}
+ removeDocument={this.remButtonDoc}
+ ScreenToLocalTransform={this.buttonBarXf}
+ PanelWidth={this.leftMenuFlyoutWidth}
+ PanelHeight={this.leftMenuFlyoutHeight}
+ renderDepth={0}
+ focus={DocUtils.DefaultFocus}
+ whenChildContentsActiveChanged={emptyFunction}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined} />
+ {['watching', 'recording'].includes(String(this.userDoc?.presentationMode) ?? '') ? <div style={{ border: '.5rem solid green', padding: '5px' }}>{this.userDoc?.presentationMode}</div> : <></>}
</div>;
- }
-
- @computed get inkResources() {
- return <svg width={0} height={0}>
- <defs>
- <filter id="inkSelectionHalo">
- <feColorMatrix type="matrix"
- result="color"
- values="1 0 0 0 0
+ }
+ @computed get snapLines() {
+ return !this.userDoc.showSnapLines ? (null) : <div className="mainView-snapLines">
+ <svg style={{ width: "100%", height: "100%" }}>
+ {SnappingManager.horizSnapLines().map(l => <line x1="0" y1={l} x2="2000" y2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
+ {SnappingManager.vertSnapLines().map(l => <line y1="0" x1={l} y2="2000" x2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
+ </svg>
+ </div>;
+ }
+
+ @computed get inkResources() {
+ return <svg width={0} height={0}>
+ <defs>
+ <filter id="inkSelectionHalo">
+ <feColorMatrix type="matrix"
+ result="color"
+ 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>
- <feMerge>
- <feMergeNode in="bg"></feMergeNode>
- <feMergeNode in="offset"></feMergeNode>
- <feMergeNode in="SourceGraphic"></feMergeNode>
- </feMerge>
- </filter>
- </defs>
- </svg>;
- }
-
- @computed get topbar() {
- TraceMobx();
- return <div className="mainView-topbar">
- <TopBar />
+ </feColorMatrix>
+ <feGaussianBlur in="color" stdDeviation="4" result="blur"></feGaussianBlur>
+ <feOffset in="blur" dx="0" dy="0" result="offset"></feOffset>
+ <feMerge>
+ <feMergeNode in="bg"></feMergeNode>
+ <feMergeNode in="offset"></feMergeNode>
+ <feMergeNode in="SourceGraphic"></feMergeNode>
+ </feMerge>
+ </filter>
+ </defs>
+ </svg>;
+ }
+
+ @computed get invisibleWebBox() { // see note under the makeLink method in HypothesisUtils.ts
+ return !DocumentLinksButton.invisibleWebDoc ? null :
+ <div className="mainView-invisibleWebRef" ref={DocumentLinksButton.invisibleWebRef}>
+ <WebBox
+ fieldKey={"data"}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ Document={DocumentLinksButton.invisibleWebDoc}
+ dropAction={"move"}
+ styleProvider={undefined}
+ isSelected={returnFalse}
+ select={returnFalse}
+ setHeight={returnFalse}
+ rootSelected={returnFalse}
+ renderDepth={0}
+ addDocTab={returnFalse}
+ pinToPres={returnFalse}
+ ScreenToLocalTransform={Transform.Identity}
+ bringToFront={returnFalse}
+ isContentActive={emptyFunction}
+ whenChildContentsActiveChanged={returnFalse}
+ focus={returnFalse}
+ docViewPath={returnEmptyDoclist}
+ PanelWidth={() => 500}
+ PanelHeight={() => 800}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ />
</div>;
- }
-
- @computed get invisibleWebBox() { // see note under the makeLink method in HypothesisUtils.ts
- return !DocumentLinksButton.invisibleWebDoc ? null :
- <div className="mainView-invisibleWebRef" ref={DocumentLinksButton.invisibleWebRef}>
+ }
+
+ render() {
+ return (<div className={`mainView-container${this.colorScheme}`}
+ onScroll={() => ((ele) => ele.scrollTop = ele.scrollLeft = 0)(document.getElementById("root")!)}
+ ref={r => {
+ r && new _global.ResizeObserver(action(() => { this._windowWidth = r.getBoundingClientRect().width; this._windowHeight = r.getBoundingClientRect().height; })).observe(r);
+ }}>
+ {this.inkResources}
+ <DictationOverlay />
+ <SharingManager />
+ <SettingsManager />
+ <CaptureManager />
+ <GroupManager />
+ <GoogleAuthenticationManager />
+ <DocumentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfHeaderBarDoc} PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} />
+ <ComponentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDocContent} />
+ <TopBar />
+ {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
+ {DocumentLinksButton.LinkEditorDocView ? <LinkMenu clearLinkEditor={action(() => DocumentLinksButton.LinkEditorDocView = undefined)} docView={DocumentLinksButton.LinkEditorDocView} /> : (null)}
+ {LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : (null)}
+ <div style={{ position: "relative", display: LightboxView.LightboxDoc ? "none" : undefined, zIndex: 1999 }} >
+ <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
+ </div>
+ <GestureOverlay >
+ {this.mainDashboardArea}
+ </GestureOverlay>
+ <PreviewCursor />
+ <TaskCompletionBox />
+ <ContextMenu />
+ <RadialMenu />
+ <AnchorMenu />
+ <DashFieldViewMenu />
+ <MarqueeOptionsMenu />
+ <OverlayView />
+ <TimelineMenu />
+ <RichTextMenu />
+ <InkTranscription />
+ {this.snapLines}
+ <div className="mainView-webRef" ref={this.makeWebRef} />
+ <LightboxView PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} maxBorder={[200, 50]} />
+ </div >);
+ }
+
+ makeWebRef = (ele: HTMLDivElement) => {
+ reaction(() => DocumentLinksButton.invisibleWebDoc,
+ invisibleDoc => {
+ ReactDOM.unmountComponentAtNode(ele);
+ invisibleDoc && ReactDOM.render(<span title="Drag as document" className="invisible-webbox" >
+ <div className="mainView-webRef" ref={DocumentLinksButton.invisibleWebRef}>
<WebBox
- fieldKey={"data"}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- Document={DocumentLinksButton.invisibleWebDoc}
- dropAction={"move"}
- layerProvider={undefined}
- styleProvider={undefined}
- isSelected={returnFalse}
- select={returnFalse}
- setHeight={returnFalse}
- rootSelected={returnFalse}
- renderDepth={0}
- addDocTab={returnFalse}
- pinToPres={returnFalse}
- ScreenToLocalTransform={Transform.Identity}
- bringToFront={returnFalse}
- isContentActive={emptyFunction}
- whenChildContentsActiveChanged={returnFalse}
- focus={returnFalse}
- docViewPath={returnEmptyDoclist}
- PanelWidth={() => 500}
- PanelHeight={() => 800}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
+ fieldKey={"data"}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ Document={invisibleDoc}
+ dropAction={"move"}
+ isSelected={returnFalse}
+ docViewPath={returnEmptyDoclist}
+ select={returnFalse}
+ rootSelected={returnFalse}
+ renderDepth={0}
+ setHeight={returnFalse}
+ styleProvider={undefined}
+ addDocTab={returnFalse}
+ pinToPres={returnFalse}
+ ScreenToLocalTransform={Transform.Identity}
+ bringToFront={returnFalse}
+ isContentActive={emptyFunction}
+ whenChildContentsActiveChanged={returnFalse}
+ focus={returnFalse}
+ PanelWidth={() => 500}
+ PanelHeight={() => 800}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
/>
- </div>;
- }
-
- render() {
- return (<div className={`mainView-container${this.colorScheme}`}
- onScroll={() => ((ele) => ele.scrollTop = ele.scrollLeft = 0)(document.getElementById("root")!)}
- ref={r => {
- r && new _global.ResizeObserver(action(() => { this._windowWidth = r.getBoundingClientRect().width; this._windowHeight = r.getBoundingClientRect().height; })).observe(r);
- }}>
- {this.inkResources}
- <DictationOverlay />
- <SharingManager />
- <SettingsManager />
- <CaptureManager />
- <GroupManager />
- <GoogleAuthenticationManager />
- <DocumentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDoc} PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} />
- <ComponentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDocContent} />
- {this.topbar}
- {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
- {DocumentLinksButton.LinkEditorDocView ? <LinkMenu clearLinkEditor={action(() => DocumentLinksButton.LinkEditorDocView = undefined)} docView={DocumentLinksButton.LinkEditorDocView} /> : (null)}
- {LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : (null)}
- <div style={{ position: "relative", display: LightboxView.LightboxDoc ? "none" : undefined, zIndex: 2001 }} >
- <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
- </div>
- <GestureOverlay >
- {this.mainDashboardArea}
- </GestureOverlay>
- <PreviewCursor />
- <TaskCompletionBox />
- <ContextMenu />
- <RadialMenu />
- <AnchorMenu />
- <MarqueeOptionsMenu />
- <OverlayView />
- <TimelineMenu />
- <RichTextMenu />
- {this.snapLines}
- <div className="mainView-webRef" ref={this.makeWebRef} />
- <LightboxView PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} maxBorder={[200, 50]} />
- </div >);
- }
-
- makeWebRef = (ele: HTMLDivElement) => {
- reaction(() => DocumentLinksButton.invisibleWebDoc,
- invisibleDoc => {
- ReactDOM.unmountComponentAtNode(ele);
- invisibleDoc && ReactDOM.render(<span title="Drag as document" className="invisible-webbox" >
- <div className="mainView-webRef" ref={DocumentLinksButton.invisibleWebRef}>
- <WebBox
- fieldKey={"data"}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- Document={invisibleDoc}
- dropAction={"move"}
- isSelected={returnFalse}
- docViewPath={returnEmptyDoclist}
- select={returnFalse}
- rootSelected={returnFalse}
- renderDepth={0}
- setHeight={returnFalse}
- layerProvider={undefined}
- styleProvider={undefined}
- addDocTab={returnFalse}
- pinToPres={returnFalse}
- ScreenToLocalTransform={Transform.Identity}
- bringToFront={returnFalse}
- isContentActive={emptyFunction}
- whenChildContentsActiveChanged={returnFalse}
- focus={returnFalse}
- PanelWidth={() => 500}
- PanelHeight={() => 800}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- />
- </div>;
- </span>, ele);
-
- let success = false;
- const onSuccess = () => {
- success = true;
- clearTimeout(interval);
- document.removeEventListener("editSuccess", onSuccess);
- };
-
- // For some reason, Hypothes.is annotations don't load until a click is registered on the page,
- // so we keep simulating clicks until annotations have loaded and editing is successful
- const interval = setInterval(() => !success && simulateMouseClick(ele, 50, 50, 50, 50), 500);
- setTimeout(() => !success && clearInterval(interval), 10000); // give up if no success after 10s
- document.addEventListener("editSuccess", onSuccess);
- });
- }
+ </div>;
+ </span>, ele);
+
+ let success = false;
+ const onSuccess = () => {
+ success = true;
+ clearTimeout(interval);
+ document.removeEventListener("editSuccess", onSuccess);
+ };
+
+ // For some reason, Hypothes.is annotations don't load until a click is registered on the page,
+ // so we keep simulating clicks until annotations have loaded and editing is successful
+ const interval = setInterval(() => !success && simulateMouseClick(ele, 50, 50, 50, 50), 500);
+ setTimeout(() => !success && clearInterval(interval), 10000); // give up if no success after 10s
+ document.addEventListener("editSuccess", onSuccess);
+ });
+ }
}
ScriptingGlobals.add(function selectMainMenu(doc: Doc, title: string) { MainView.Instance.selectMenu(doc); }); \ No newline at end of file