(@wiki:phrase)
{` display wikipedia page for entered text (terminate with carriage return)`}
@@ -122,24 +126,14 @@ export class RTFMarkup extends React.Component<{}> {
);
}
- @action
- public open = () => {
- this.isOpen = true;
- };
-
- @action
- public close = () => {
- this.isOpen = false;
- };
-
render() {
return (
this.setOpen(false)}
/>
);
}
diff --git a/src/client/util/ReplayMovements.ts b/src/client/util/ReplayMovements.ts
index 2c8fdf483..dcc6aabab 100644
--- a/src/client/util/ReplayMovements.ts
+++ b/src/client/util/ReplayMovements.ts
@@ -2,7 +2,7 @@ import { IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { Doc, IdToDoc } from '../../fields/Doc';
import { CollectionDockingView } from '../views/collections/CollectionDockingView';
import { CollectionFreeFormView } from '../views/collections/collectionFreeForm';
-import { OpenWhereMod } from '../views/nodes/DocumentView';
+import { OpenWhereMod } from '../views/nodes/OpenWhere';
import { VideoBox } from '../views/nodes/VideoBox';
import { DocumentManager } from './DocumentManager';
import { Movement, Presentation } from './TrackMovements';
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 8347844f7..8cb97fe50 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -14,9 +14,7 @@ import { BoolCast, Cast, NumCast, StrCast } from '../../fields/Types';
import { DocServer } from '../DocServer';
import { Networking } from '../Network';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
-import { GestureOverlay } from '../views/GestureOverlay';
import { MainViewModal } from '../views/MainViewModal';
-import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
import { GroupManager } from './GroupManager';
import './SettingsManager.scss';
import { SnappingManager } from './SnappingManager';
@@ -256,25 +254,14 @@ export class SettingsManager extends React.Component<{}> {
size={Size.XSMALL}
color={SettingsManager.userColor}
/>
- {
- FontIconBox.ShowIconLabels = !FontIconBox.ShowIconLabels;
- }}
- toggleStatus={FontIconBox.ShowIconLabels}
- size={Size.XSMALL}
- color={SettingsManager.userColor}
- />
{
- GestureOverlay.RecognizeGestures = !GestureOverlay.RecognizeGestures;
+ Doc.UserDoc().recognizeGestures = !Doc.UserDoc().recognizeGestures;
}}
- toggleStatus={GestureOverlay.RecognizeGestures}
+ toggleStatus={BoolCast(Doc.UserDoc().recognizeGestures)}
size={Size.XSMALL}
color={SettingsManager.userColor}
/>
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 19a7948e6..b0140b73c 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -18,7 +18,6 @@ import { Id } from '../../fields/FieldSymbols';
import { StrCast } from '../../fields/Types';
import { GetEffectiveAcl, SharingPermissions, TraceMobx, distributeAcls, normalizeEmail } from '../../fields/util';
import { DocServer } from '../DocServer';
-import { DictationOverlay } from '../views/DictationOverlay';
import { MainViewModal } from '../views/MainViewModal';
import { DocumentView } from '../views/nodes/DocumentView';
import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
@@ -27,8 +26,8 @@ import { GroupManager, UserOptions } from './GroupManager';
import { GroupMemberView } from './GroupMemberView';
import { SearchUtil } from './SearchUtil';
import { SelectionManager } from './SelectionManager';
-import { SettingsManager } from './SettingsManager';
import './SharingManager.scss';
+import { SnappingManager } from './SnappingManager';
import { undoable } from './UndoManager';
export interface User {
@@ -238,14 +237,14 @@ export class SharingManager extends React.Component<{}> {
const permissions = uniform ? StrCast(targetDoc?.[groupKey]) : '-multiple-';
return !permissions ? null : (
-
+
{StrCast(group.title)}
{group instanceof Doc ? (
}
size={Size.XSMALL}
- color={SettingsManager.userColor}
+ color={SnappingManager.userColor}
onClick={action(() => {
GroupManager.Instance.currentGroup = group;
})}
@@ -279,10 +278,10 @@ export class SharingManager extends React.Component<{}> {
-
+
window.open('https://brown-dash.github.io/Dash-Documentation/features/collaboration/', '_blank')}>
window.open('https://brown-dash.github.io/Dash-Documentation/features/collaboration/', '_blank')} />
@@ -290,10 +289,10 @@ export class SharingManager extends React.Component<{}> {
{this.focusOn(docs.length < 2 ? StrCast(targetDoc?.title, 'this document') : '-multiple-')}
- } iconPlacement="left" text="Copy Guest URL" onClick={this.copyURL} />
+ } iconPlacement="left" text="Copy Guest URL" onClick={this.copyURL} />
- } onClick={this.close} color={SettingsManager.userColor} />
+ } onClick={this.close} color={SnappingManager.userColor} />
{admin ? (
@@ -335,7 +334,7 @@ export class SharingManager extends React.Component<{}> {
-
+
@@ -514,7 +513,6 @@ export class SharingManager extends React.Component<{}> {
setTimeout(
action(() => {
// this.copied = false;
- DictationOverlay.Instance.hasActiveModal = false;
this.targetDoc = undefined;
}),
500
@@ -528,7 +526,6 @@ export class SharingManager extends React.Component<{}> {
runInAction(() => {
this.targetDocView = target;
this.targetDoc = targetDoc || target?.Document;
- DictationOverlay.Instance.hasActiveModal = true;
this.isOpen = this.targetDoc !== undefined;
this.permissions = SharingPermissions.Augment;
this.upgradeNested = true;
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index c4855d2e7..d92a73b63 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -15,9 +15,10 @@ import { PrefetchProxy } from '../../fields/Proxy';
import { listSpec } from '../../fields/Schema';
import { ScriptField } from '../../fields/ScriptField';
import { Cast, ImageCast, StrCast } from '../../fields/Types';
-import { normalizeEmail } from '../../fields/util';
+import { SharingPermissions, inheritParentAcls, normalizeEmail } from '../../fields/util';
import { DocServer } from '../DocServer';
-import { DocUtils, Docs, DocumentOptions } from '../documents/Documents';
+import { DocUtils } from '../documents/DocUtils';
+import { Docs, DocumentOptions } from '../documents/Documents';
import { dropActionType } from '../util/DropActionTypes';
import { HistoryUtil } from '../util/History';
import { ScriptingGlobals } from '../util/ScriptingGlobals';
@@ -36,11 +37,51 @@ enum DashboardGroup {
SharedDashboards,
}
+export type DocConfig = {
+ doc: Doc;
+ initialWidth?: number;
+ path?: Doc[];
+};
+
// DashboardView is the view with the dashboard previews, rendered when the app first loads
@observer
export class DashboardView extends ObservableReactComponent<{}> {
public static _urlState: HistoryUtil.DocUrl;
+ public static makeDocumentConfig(document: Doc, panelName?: string, width?: number, keyValue?: boolean) {
+ return {
+ type: 'react-component',
+ component: 'DocumentFrameRenderer',
+ title: document.title,
+ width: width,
+ props: {
+ documentId: document[Id],
+ keyValue,
+ panelName, // name of tab that can be used to close or replace its contents
+ },
+ };
+ }
+ static StandardCollectionDockingDocument(configs: Array
, options: DocumentOptions, id?: string, type: string = 'row') {
+ const layoutConfig = {
+ content: [
+ {
+ type: type,
+ content: [...configs.map(config => DashboardView.makeDocumentConfig(config.doc, undefined, config.initialWidth))],
+ },
+ ],
+ };
+ const doc = Docs.Create.DockDocument(
+ configs.map(c => c.doc),
+ JSON.stringify(layoutConfig),
+ ClientUtils.CurrentUserEmail() === 'guest' ? options : { acl_Guest: SharingPermissions.View, ...options },
+ id
+ );
+ configs.forEach(c => {
+ Doc.SetContainer(c.doc, doc);
+ inheritParentAcls(doc, c.doc, false);
+ });
+ return doc;
+ }
constructor(props: any) {
super(props);
makeObservable(this);
@@ -389,7 +430,7 @@ export class DashboardView extends ObservableReactComponent<{}> {
const title = name || `Dashboard ${dashboardCount}`;
const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
- const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row');
+ const dashboardDoc = DashboardView.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row');
Doc.AddDocToList(Doc.MyHeaderBar, 'data', freeformDoc, undefined, undefined, true);
dashboardDoc.pane_count = 1;
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 391c2f694..a0e3d2ddd 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -12,8 +12,10 @@ import { DocumentType } from '../documents/DocumentTypes';
import { DragManager } from '../util/DragManager';
import { ObservableReactComponent } from './ObservableReactComponent';
import { PinProps } from './PinFuncs';
-import { DocumentView, OpenWhere } from './nodes/DocumentView';
-import { FieldViewProps, FocusViewOptions } from './nodes/FieldView';
+import { DocumentView } from './nodes/DocumentView';
+import { FocusViewOptions } from './nodes/FocusViewOptions';
+import { FieldViewProps } from './nodes/FieldView';
+import { OpenWhere } from './nodes/OpenWhere';
// import { DocUtils } from '../documents/Documents';
/**
@@ -41,6 +43,7 @@ export interface ViewBoxInterface {
onClickScriptDisable?: () => 'never' | 'always'; // disable click scripts : never, always, or undefined = only when selected
getKeyFrameEditing?: () => boolean; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown)
setKeyFrameEditing?: (set: boolean) => void; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown)
+ playTrail?: (docs: Doc[]) => void;
playFrom?: (time: number, endTime?: number) => void;
Pause?: () => void; // pause a media document (eg, audio/video)
IsPlaying?: () => boolean; // is a media document playing
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index c5358dffe..dd744f272 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -14,7 +14,7 @@ import { returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '
import { emptyFunction } from '../../Utils';
import { Doc } from '../../fields/Doc';
import { Cast, DocCast } from '../../fields/Types';
-import { DocUtils } from '../documents/Documents';
+import { DocUtils } from '../documents/DocUtils';
import { CalendarManager } from '../util/CalendarManager';
import { DragManager } from '../util/DragManager';
import { dropActionType } from '../util/DropActionTypes';
@@ -22,15 +22,16 @@ import { IsFollowLinkScript } from '../util/LinkFollower';
import { SelectionManager } from '../util/SelectionManager';
import { SharingManager } from '../util/SharingManager';
import { UndoManager, undoBatch } from '../util/UndoManager';
-import { PinProps } from './DocComponent';
import './DocumentButtonBar.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
+import { PinProps } from './PinFuncs';
import { TemplateMenu } from './TemplateMenu';
import { TabDocView } from './collections/TabDocView';
import { Colors } from './global/globalEnums';
import { LinkPopup } from './linking/LinkPopup';
import { DocumentLinksButton } from './nodes/DocumentLinksButton';
-import { DocumentView, DocumentViewInternal, OpenWhere } from './nodes/DocumentView';
+import { DocumentView, DocumentViewInternal } from './nodes/DocumentView';
+import { OpenWhere } from './nodes/OpenWhere';
import { DashFieldView } from './nodes/formattedText/DashFieldView';
@observer
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 1e6eb1aeb..ef493fb69 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -33,9 +33,10 @@ import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { Colors } from './global/globalEnums';
import { CollectionFreeFormDocumentView } from './nodes/CollectionFreeFormDocumentView';
-import { DocumentView, OpenWhereMod } from './nodes/DocumentView';
+import { DocumentView } from './nodes/DocumentView';
import { ImageBox } from './nodes/ImageBox';
import { KeyValueBox } from './nodes/KeyValueBox';
+import { OpenWhereMod } from './nodes/OpenWhere';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
interface DocumentDecorationsProps {
@@ -448,7 +449,7 @@ export class DocumentDecorations extends ObservableReactComponent CollectionFreeFormDocumentView.from(docView)?.CollectionFreeFormView?.dragStarting(false, false));
+ SelectionManager.Views.forEach(docView => CollectionFreeFormView.from(docView)?.dragStarting(false, false));
};
projectDragToAspect = (e: PointerEvent, docView: DocumentView, fixedAspect: number) => {
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index bf5b51a2d..0d1573ea3 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -4,17 +4,6 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../ClientUtils';
import { emptyFunction } from '../../Utils';
-import { Doc, Opt } from '../../fields/Doc';
-import { InkData, InkTool } from '../../fields/InkField';
-import { BoolCast, NumCast } from '../../fields/Types';
-import MobileInkOverlay from '../../mobile/MobileInkOverlay';
-import { Gestures } from '../../pen-gestures/GestureTypes';
-import { GestureUtils } from '../../pen-gestures/GestureUtils';
-import { MobileInkOverlayContent } from '../../server/Message';
-import { InteractionUtils } from '../util/InteractionUtils';
-import { ScriptingGlobals } from '../util/ScriptingGlobals';
-import { Transform } from '../util/Transform';
-import './GestureOverlay.scss';
import {
ActiveArrowEnd,
ActiveArrowScale,
@@ -24,12 +13,24 @@ import {
ActiveInkBezierApprox,
ActiveInkColor,
ActiveInkWidth,
+ Doc,
+ Opt,
SetActiveArrowStart,
SetActiveDash,
SetActiveFillColor,
SetActiveInkColor,
SetActiveInkWidth,
-} from './InkingStroke';
+} from '../../fields/Doc';
+import { InkData, InkTool } from '../../fields/InkField';
+import { NumCast } from '../../fields/Types';
+// import MobileInkOverlay from '../../mobile/MobileInkOverlay';
+import { Gestures } from '../../pen-gestures/GestureTypes';
+import { GestureUtils } from '../../pen-gestures/GestureUtils';
+// import { MobileInkOverlayContent } from '../../server/Message';
+import { InteractionUtils } from '../util/InteractionUtils';
+import { ScriptingGlobals } from '../util/ScriptingGlobals';
+import { Transform } from '../util/Transform';
+import './GestureOverlay.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
import { DocumentView } from './nodes/DocumentView';
@@ -49,13 +50,6 @@ export class GestureOverlay extends ObservableReactComponent = undefined;
@observable public SavedColor?: string = undefined;
@observable public SavedWidth?: number = undefined;
@@ -80,7 +74,7 @@ export class GestureOverlay extends ObservableReactComponent();
private _d1: Doc | undefined;
@@ -158,7 +152,7 @@ export class GestureOverlay extends ObservableReactComponent 2 && GestureUtils.GestureRecognizer.Recognize([points]);
let actionPerformed = false;
- if (GestureOverlay.RecognizeGestures && result && result.Score > 0.7) {
+ if (Doc.UserDoc().recognizeGestures && result && result.Score > 0.7) {
switch (result.Name) {
case Gestures.Line:
case Gestures.Triangle:
@@ -502,15 +496,10 @@ export class GestureOverlay extends ObservableReactComponent {
- this.showMobileInkOverlay = content.enableOverlay;
- };
-
render() {
return (
- {this.showMobileInkOverlay ?
: null}
+ {/* {this.showMobileInkOverlay ?
: null} */}
{this.elements}
{});
nudge = (x: number, y: number, label: string) => {
- const nudgeable = SelectionManager.Views.some(dv => dv.CollectionFreeFormDocumentView?.nudge);
- nudgeable && UndoManager.RunInBatch(() => SelectionManager.Views.map(dv => dv.CollectionFreeFormDocumentView?.nudge(x, y)), label);
+ const nudgeable = SelectionManager.Views.some(dv => CollectionFreeFormDocumentView.from(dv)?.nudge);
+ nudgeable && UndoManager.RunInBatch(() => SelectionManager.Views.map(dv => CollectionFreeFormDocumentView.from(dv)?.nudge(x, y)), label);
return { stopPropagation: nudgeable, preventDefault: nudgeable };
};
@@ -105,7 +106,7 @@ export class KeyManager {
case 'g':
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
const selected = SelectionManager.Views;
- const cv = selected.reduce((col, dv) => (!col || dv.CollectionFreeFormView === col ? dv.CollectionFreeFormView : undefined), undefined as undefined | CollectionFreeFormView);
+ const cv = selected.reduce((col, dv) => (!col || CollectionFreeFormView.from(dv) === col ? CollectionFreeFormView.from(dv) : undefined), undefined as undefined | CollectionFreeFormView);
cv && undoable(() => cv._marqueeViewRef.current?.collection(e, true, SelectionManager.Docs), 'grouping');
}
break;
@@ -205,7 +206,7 @@ export class KeyManager {
switch (keyname) {
case 'Æ’':
case 'f':
- UndoManager.RunInBatch(() => SelectionManager.Views?.[0]?.CollectionFreeFormDocumentView?.float(), 'float');
+ UndoManager.RunInBatch(() => CollectionFreeFormDocumentView.from(SelectionManager.Views?.[0])?.float(), 'float');
break;
default:
}
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts
index 98cf33c41..109a9cad4 100644
--- a/src/client/views/InkStrokeProperties.ts
+++ b/src/client/views/InkStrokeProperties.ts
@@ -13,6 +13,7 @@ import { DocumentManager } from '../util/DocumentManager';
import { undoBatch } from '../util/UndoManager';
import { FitOneCurve } from '../util/bezierFit';
import { InkingStroke } from './InkingStroke';
+import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { DocumentView } from './nodes/DocumentView';
export class InkStrokeProperties {
@@ -380,7 +381,7 @@ export class InkStrokeProperties {
};
snapToAllCurves = (screenDragPt: { X: number; Y: number }, inkView: DocumentView, snapData: { nearestPt: { X: number; Y: number }; distance: number }, ink: InkData, controlIndex: number) => {
- const containingCollection = inkView.CollectionFreeFormView;
+ const containingCollection = CollectionFreeFormView.from(inkView);
const containingDocView = containingCollection?.DocumentView?.();
containingCollection?.childDocs
.filter(doc => doc.type === DocumentType.INK)
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index cf609d8f9..884512539 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -30,6 +30,7 @@ import { BoolCast, Cast, NumCast, RTFCast, StrCast } from '../../fields/Types';
import { TraceMobx } from '../../fields/util';
import { CognitiveServices } from '../cognitive_services/CognitiveServices';
import { Docs } from '../documents/Documents';
+import { DocumentType } from '../documents/DocumentTypes';
import { InteractionUtils } from '../util/InteractionUtils';
import { SnappingManager } from '../util/SnappingManager';
import { UndoManager } from '../util/UndoManager';
@@ -491,67 +492,17 @@ export class InkingStroke extends ViewBoxAnnotatableComponent
()
);
}
}
-export function ActiveInkPen(): Doc {
- return Doc.UserDoc();
-}
-export function ActiveInkColor(): string {
- return StrCast(ActiveInkPen()?.activeInkColor, 'black');
-}
-export function ActiveFillColor(): string {
- return StrCast(ActiveInkPen()?.activeFillColor, '');
-}
-export function ActiveIsInkMask(): boolean {
- return BoolCast(ActiveInkPen()?.activeIsInkMask, false);
-}
-export function ActiveInkHideTextLabels(): boolean {
- return BoolCast(ActiveInkPen().activeInkHideTextLabels, false);
-}
-export function ActiveArrowStart(): string {
- return StrCast(ActiveInkPen()?.activeArrowStart, '');
-}
-export function ActiveArrowEnd(): string {
- return StrCast(ActiveInkPen()?.activeArrowEnd, '');
-}
-export function ActiveArrowScale(): number {
- return NumCast(ActiveInkPen()?.activeArrowScale, 1);
-}
-export function ActiveDash(): string {
- return StrCast(ActiveInkPen()?.activeDash, '0');
-}
-export function ActiveInkWidth(): number {
- return Number(ActiveInkPen()?.activeInkWidth);
-}
-export function ActiveInkBezierApprox(): string {
- return StrCast(ActiveInkPen()?.activeInkBezier);
-}
-
-export function SetActiveInkWidth(width: string): void {
- !isNaN(parseInt(width)) && ActiveInkPen() && (ActiveInkPen().activeInkWidth = width);
-}
-export function SetActiveBezierApprox(bezier: string): void {
- ActiveInkPen() && (ActiveInkPen().activeInkBezier = isNaN(parseInt(bezier)) ? '' : bezier);
-}
-export function SetActiveInkColor(value: string) {
- ActiveInkPen() && (ActiveInkPen().activeInkColor = value);
-}
-export function SetActiveIsInkMask(value: boolean) {
- ActiveInkPen() && (ActiveInkPen().activeIsInkMask = value);
-}
-export function SetActiveInkHideTextLabels(value: boolean) {
- ActiveInkPen() && (ActiveInkPen().activeInkHideTextLabels = value);
-}
-export function SetActiveFillColor(value: string) {
- ActiveInkPen() && (ActiveInkPen().activeFillColor = value);
-}
-export function SetActiveArrowStart(value: string) {
- ActiveInkPen() && (ActiveInkPen().activeArrowStart = value);
-}
-export function SetActiveArrowEnd(value: string) {
- ActiveInkPen() && (ActiveInkPen().activeArrowEnd = value);
-}
-export function SetActiveArrowScale(value: number) {
- ActiveInkPen() && (ActiveInkPen().activeArrowScale = value);
-}
-export function SetActiveDash(dash: string): void {
- !isNaN(parseInt(dash)) && ActiveInkPen() && (ActiveInkPen().activeDash = dash);
-}
+Docs.Prototypes.TemplateMap.set(DocumentType.INK, {
+ // NOTE: this is unused!! ink fields are filled in directly within the InkDocument() method
+ layout: { view: InkingStroke, dataField: 'stroke' },
+ options: {
+ acl: '',
+ systemIcon: 'BsFillPencilFill', //
+ _layout_nativeDimEditable: true,
+ _layout_reflowVertical: true,
+ _layout_reflowHorizontal: true,
+ layout_hideDecorationTitle: true, // don't show title when selected
+ _layout_fitWidth: false,
+ layout_isSvg: true,
+ },
+});
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 7bf6bb9e5..020525ef8 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -9,11 +9,10 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { ClientUtils, returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../ClientUtils';
import { emptyFunction } from '../../Utils';
-import { Doc, DocListCast, FieldResult, Opt } from '../../fields/Doc';
+import { CreateLinkToActiveAudio, Doc, DocListCast, FieldResult, Opt } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { InkTool } from '../../fields/InkField';
import { Cast, NumCast, toList } from '../../fields/Types';
-import { DocUtils } from '../documents/Documents';
import { DocumentManager } from '../util/DocumentManager';
import { LinkManager } from '../util/LinkManager';
import { SelectionManager } from '../util/SelectionManager';
@@ -27,7 +26,8 @@ import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
import { TabDocView } from './collections/TabDocView';
-import { DocumentView, OpenWhere, OpenWhereMod } from './nodes/DocumentView';
+import { DocumentView } from './nodes/DocumentView';
+import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere';
interface LightboxViewProps {
PanelWidth: number;
@@ -88,7 +88,7 @@ export class LightboxView extends ObservableReactComponent {
savedKeys.forEach(key => {
this._savedState[key] = Doc.Get(doc, key, true);
});
- const l = DocUtils.MakeLinkToActiveAudio(() => doc).lastElement();
+ const l = CreateLinkToActiveAudio(() => doc).lastElement();
l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
CollectionStackedTimeline.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.());
this._history.push({ doc, target });
@@ -136,7 +136,7 @@ export class LightboxView extends ObservableReactComponent {
const target = (this._docTarget = this._future.pop());
const targetDocView = target && DocumentManager.Instance.getLightboxDocumentView(target);
if (targetDocView && target) {
- const l = DocUtils.MakeLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.(true) || target).lastElement();
+ const l = CreateLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.(true) || target).lastElement();
l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
DocumentManager.Instance.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
if (this._history.lastElement().target !== target) this._history.push({ doc: lightDoc, target });
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index d3dd51ac6..aec553baa 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -11,7 +11,7 @@ import * as React from 'react';
import '../../../node_modules/browndash-components/dist/styles/global.min.css';
import { ClientUtils, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../ClientUtils';
import { emptyFunction } from '../../Utils';
-import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { Doc, DocListCast, GetDocFromUrl, Opt } from '../../fields/Doc';
import { DocData } from '../../fields/DocSymbols';
import { DocCast, StrCast, toList } from '../../fields/Types';
import { DocServer } from '../DocServer';
@@ -55,28 +55,28 @@ import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionMenu } from './collections/CollectionMenu';
import { TabDocView } from './collections/TabDocView';
import './collections/TreeView.scss';
+import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { MarqueeOptionsMenu } from './collections/collectionFreeForm/MarqueeOptionsMenu';
import { CollectionLinearView } from './collections/collectionLinear';
import { LinkMenu } from './linking/LinkMenu';
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 { DocumentView, DocumentViewInternal, returnEmptyDocViewList } from './nodes/DocumentView';
import { ImageEditorData as ImageEditor } from './nodes/ImageBox';
import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
import { LinkDocPreview, LinkInfo } from './nodes/LinkDocPreview';
import { DirectionsAnchorMenu } from './nodes/MapBox/DirectionsAnchorMenu';
import { MapAnchorMenu } from './nodes/MapBox/MapAnchorMenu';
+import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere';
import { TaskCompletionBox } from './nodes/TaskCompletedBox';
import { DashFieldViewMenu } from './nodes/formattedText/DashFieldView';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { RichTextMenu } from './nodes/formattedText/RichTextMenu';
import GenerativeFill from './nodes/generativeFill/GenerativeFill';
import { PresBox } from './nodes/trails';
import { AnchorMenu } from './pdf/AnchorMenu';
import { GPTPopup } from './pdf/GPTPopup/GPTPopup';
import { TopBar } from './topbar/TopBar';
-import { CollectionFreeFormView } from './collections/collectionFreeForm';
const _global = (window /* browser */ || global) /* node */ as any;
const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
@@ -242,7 +242,7 @@ export class MainView extends ObservableReactComponent<{}> {
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);
+ const id = GetDocFromUrl(e.detail);
DocServer.GetRefField(id).then(doc => (doc instanceof Doc ? DocumentManager.Instance.showDocument(doc, { willPan: false }) : null));
});
document.addEventListener('linkAnnotationToDash', Hypothesis.linkListener);
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index ea73a53a9..06cae6d04 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -4,16 +4,16 @@ import * as React from 'react';
import { Doc, Opt } from '../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocData } from '../../fields/DocSymbols';
import { List } from '../../fields/List';
+import { FollowLinkScript } from '../../fields/ScriptField';
import { NumCast } from '../../fields/Types';
import { GetEffectiveAcl } from '../../fields/util';
import { unimplementedFunction, Utils } from '../../Utils';
-import { Docs, DocUtils } from '../documents/Documents';
+import { Docs } from '../documents/Documents';
+import { DocUtils } from '../documents/DocUtils';
import { DragManager } from '../util/DragManager';
-import { FollowLinkScript } from '../util/LinkFollower';
import { undoable, undoBatch, UndoManager } from '../util/UndoManager';
import './MarqueeAnnotator.scss';
import { DocumentView } from './nodes/DocumentView';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { ObservableReactComponent } from './ObservableReactComponent';
import { AnchorMenu } from './pdf/AnchorMenu';
@@ -197,7 +197,7 @@ export class MarqueeAnnotator extends ObservableReactComponent {
const target = DocUtils.GetNewTextDoc('Note linked to ' + this.props.Document.title, 0, 0, 100, 100, annotationOn, 'yellow');
- FormattedTextBox.SetSelectOnLoad(target);
+ Doc.SetSelectOnLoad(target);
return target;
};
DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.docView(), sourceAnchorCreator, targetCreator), e.pageX, e.pageY, {
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index fddb40624..034ade50b 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -3,7 +3,8 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { lightOrDark, returnFalse } from '../../ClientUtils';
import { Doc, Opt } from '../../fields/Doc';
-import { DocUtils, Docs, DocumentOptions } from '../documents/Documents';
+import { Docs, DocumentOptions } from '../documents/Documents';
+import { DocUtils } from '../documents/DocUtils';
import { ImageUtils } from '../util/Import & Export/ImageUtils';
import { Transform } from '../util/Transform';
import { UndoManager, undoBatch } from '../util/UndoManager';
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index d83fea2a5..cbbf48c75 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -20,8 +20,8 @@ import { DocData } from '../../fields/DocSymbols';
import { ScriptField } from '../../fields/ScriptField';
import { BoolCast, ScriptCast } from '../../fields/Types';
import { ImageField } from '../../fields/URLField';
+import { DocUtils } from '../documents/DocUtils';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
-import { DocUtils } from '../documents/Documents';
import { IsFollowLinkScript } from '../util/LinkFollower';
import { LinkManager } from '../util/LinkManager';
import { SelectionManager } from '../util/SelectionManager';
@@ -30,7 +30,8 @@ import { undoBatch, undoable } from '../util/UndoManager';
import { InkingStroke } from './InkingStroke';
import './PropertiesButtons.scss';
import { Colors } from './global/globalEnums';
-import { DocumentView, OpenWhere } from './nodes/DocumentView';
+import { DocumentView } from './nodes/DocumentView';
+import { OpenWhere } from './nodes/OpenWhere';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
@observer
diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx
index e079b5cde..a806995f2 100644
--- a/src/client/views/PropertiesDocBacklinksSelector.tsx
+++ b/src/client/views/PropertiesDocBacklinksSelector.tsx
@@ -12,7 +12,7 @@ import { SettingsManager } from '../util/SettingsManager';
import './PropertiesDocBacklinksSelector.scss';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { LinkMenu } from './linking/LinkMenu';
-import { OpenWhere } from './nodes/DocumentView';
+import { OpenWhere } from './nodes/OpenWhere';
type PropertiesDocBacklinksSelectorProps = {
Document: Doc;
diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx
index 2d04f2fe3..722b1f90a 100644
--- a/src/client/views/PropertiesDocContextSelector.tsx
+++ b/src/client/views/PropertiesDocContextSelector.tsx
@@ -11,7 +11,8 @@ import { DocFocusOrOpen } from '../util/DocumentManager';
import { ObservableReactComponent } from './ObservableReactComponent';
import './PropertiesDocContextSelector.scss';
import { CollectionDockingView } from './collections/CollectionDockingView';
-import { DocumentView, OpenWhere } from './nodes/DocumentView';
+import { DocumentView } from './nodes/DocumentView';
+import { OpenWhere } from './nodes/OpenWhere';
type PropertiesDocContextSelectorProps = {
DocView?: DocumentView;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index f4ded8367..ff5dcd1b8 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -14,7 +14,7 @@ import { ColorResult, SketchPicker } from 'react-color';
import * as Icons from 'react-icons/bs'; // {BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs"
import { ClientUtils, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../ClientUtils';
import { emptyFunction } from '../../Utils';
-import { Doc, Field, FieldType, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc';
+import { Doc, Field, FieldResult, FieldType, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc';
import { AclAdmin, DocAcl, DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { InkField } from '../../fields/InkField';
@@ -41,9 +41,10 @@ import { PropertiesDocContextSelector } from './PropertiesDocContextSelector';
import { PropertiesSection } from './PropertiesSection';
import './PropertiesView.scss';
import { DefaultStyleProvider } from './StyleProvider';
-import { DocumentView, OpenWhere } from './nodes/DocumentView';
+import { DocumentView } from './nodes/DocumentView';
import { StyleProviderFuncType } from './nodes/FieldView';
import { KeyValueBox } from './nodes/KeyValueBox';
+import { OpenWhere } from './nodes/OpenWhere';
import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails';
const _global = (window /* browser */ || global) /* node */ as any;
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 6195dcde8..3648e613d 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -12,7 +12,8 @@ import { List } from '../../fields/List';
import { RichTextField } from '../../fields/RichTextField';
import { DocCast, NumCast, StrCast } from '../../fields/Types';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
-import { DocUtils, Docs } from '../documents/Documents';
+import { Docs } from '../documents/Documents';
+import { DocUtils } from '../documents/DocUtils';
import { LinkManager } from '../util/LinkManager';
import { SearchUtil } from '../util/SearchUtil';
import { Transform } from '../util/Transform';
@@ -83,7 +84,7 @@ export class SidebarAnnos extends ObservableReactComponent void) => {
this._flush = this._flush ?? UndoManager.StartBatch('golden layout drag');
- const config = dragDocs.length === 1 ? CollectionDockingView.makeDocumentConfig(dragDocs[0]) : { type: 'row', content: dragDocs.map(doc => CollectionDockingView.makeDocumentConfig(doc)) };
+ const config = dragDocs.length === 1 ? DashboardView.makeDocumentConfig(dragDocs[0]) : { type: 'row', content: dragDocs.map(doc => DashboardView.makeDocumentConfig(doc)) };
const dragSource = CollectionDockingView.Instance?._goldenLayout.createDragSource(document.createElement('div'), config);
this.tabDragStart(dragSource, finishDrag);
dragSource._dragListener.onMouseDown({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, button: 0 });
@@ -139,7 +125,7 @@ export class CollectionDockingView extends CollectionSubView() {
public static ReplaceTab(document: Doc, mods: OpenWhereMod, stack: any, panelName: string, addToSplit?: boolean, keyValue?: boolean): boolean {
const instance = CollectionDockingView.Instance;
if (!instance) return false;
- const newConfig = CollectionDockingView.makeDocumentConfig(document, panelName, undefined, keyValue);
+ const newConfig = DashboardView.makeDocumentConfig(document, panelName, undefined, keyValue);
if (!panelName && stack) {
const activeContentItemIndex = stack.contentItems.findIndex((item: any) => item.config === stack._activeContentItem.config);
const newContentItem = stack.layoutManager.createContentItem(newConfig, instance._goldenLayout);
@@ -180,7 +166,7 @@ export class CollectionDockingView extends CollectionSubView() {
const instance = CollectionDockingView.Instance;
const glayRoot = instance._goldenLayout.root;
if (!instance) return false;
- const docContentConfig = CollectionDockingView.makeDocumentConfig(document, panelName, undefined, keyValue);
+ const docContentConfig = DashboardView.makeDocumentConfig(document, panelName, undefined, keyValue);
CollectionDockingView.Instance._flush = CollectionDockingView.Instance._flush ?? UndoManager.StartBatch('Add Split');
setTimeout(CollectionDockingView.Instance.endUndoBatch, 100);
@@ -461,7 +447,7 @@ export class CollectionDockingView extends CollectionSubView() {
if (content) {
const _width = DivWidth(content);
const _height = DivHeight(content);
- return CollectionFreeFormView.UpdateIcon(this.layoutDoc[Id] + '-icon' + new Date().getTime(), content, _width, _height, _width, _height, 0, 1, true, this.layoutDoc[Id] + '-icon', iconFile => {
+ return UpdateIcon(this.layoutDoc[Id] + '-icon' + new Date().getTime(), content, _width, _height, _width, _height, 0, 1, true, this.layoutDoc[Id] + '-icon', iconFile => {
const proto = this.dataDoc; // Cast(img.proto, Doc, null)!;
proto.thumb_nativeWidth = _width;
proto.thumb_nativeHeight = _height;
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 8803f6f79..9a6f1e2eb 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -166,7 +166,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent {
const key = this._props.pivotField;
doc[key] = this.getValue(this._props.heading);
- FormattedTextBox.SetSelectOnLoad(doc);
+ Doc.SetSelectOnLoad(doc);
return this._props.addDocument?.(doc);
},
this._props.addDocument,
@@ -195,7 +197,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent {
- const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document));
+ const created = DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document));
if (created) {
if (this._props.Document.isTemplateDoc) {
Doc.MakeMetadataFieldTemplate(created, this._props.Document);
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index 6ccbd6208..e02570d3e 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -8,11 +8,11 @@ import { Doc, DocListCast } from '../../../fields/Doc';
import { ScriptField } from '../../../fields/ScriptField';
import { NumCast, StrCast, toList } from '../../../fields/Types';
import { emptyFunction } from '../../../Utils';
-import { DocUtils } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
import { dropActionType } from '../../util/DropActionTypes';
import { SelectionManager } from '../../util/SelectionManager';
import { undoBatch, UndoManager } from '../../util/UndoManager';
-import { OpenWhere } from '../nodes/DocumentView';
+import { OpenWhere } from '../nodes/OpenWhere';
import { computePassLayout, computeStarburstLayout } from './collectionFreeForm';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
import './CollectionPileView.scss';
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 7adf44a5c..50a66aa41 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -13,7 +13,7 @@ import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
-import { ComputedField, ScriptField } from '../../../fields/ScriptField';
+import { ComputedField, FollowLinkScript, ScriptField } from '../../../fields/ScriptField';
import { Cast, NumCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { emptyFunction, formatTime } from '../../../Utils';
@@ -21,21 +21,23 @@ import { Docs } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager } from '../../util/DragManager';
-import { FollowLinkScript, IsFollowLinkScript, LinkFollower } from '../../util/LinkFollower';
+import { IsFollowLinkScript, LinkFollower } from '../../util/LinkFollower';
import { LinkManager } from '../../util/LinkManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { undoBatch, UndoManager } from '../../util/UndoManager';
-import { CollectionSubView } from './CollectionSubView';
import { LightboxView } from '../LightboxView';
import { AudioWaveform } from '../nodes/audio/AudioWaveform';
-import { DocumentView, OpenWhere } from '../nodes/DocumentView';
-import { FocusFuncType, FocusViewOptions, StyleProviderFuncType } from '../nodes/FieldView';
+import { DocumentView } from '../nodes/DocumentView';
+import { FocusFuncType, StyleProviderFuncType } from '../nodes/FieldView';
+import { FocusViewOptions } from '../nodes/FocusViewOptions';
import { LabelBox } from '../nodes/LabelBox';
+import { OpenWhere } from '../nodes/OpenWhere';
import { VideoBox } from '../nodes/VideoBox';
import { ObservableReactComponent } from '../ObservableReactComponent';
import './CollectionStackedTimeline.scss';
+import { CollectionSubView } from './CollectionSubView';
export type CollectionStackedTimelineProps = {
Play: () => void;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index ad9960989..8ae0f2832 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -15,8 +15,9 @@ import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
import { emptyFunction } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
import { CollectionViewType } from '../../documents/DocumentTypes';
+import { DocUtils } from '../../documents/DocUtils';
import { DragManager } from '../../util/DragManager';
import { dropActionType } from '../../util/DropActionTypes';
import { SettingsManager } from '../../util/SettingsManager';
@@ -28,8 +29,8 @@ import { EditableView } from '../EditableView';
import { LightboxView } from '../LightboxView';
import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
import { DocumentView } from '../nodes/DocumentView';
-import { FieldViewProps, FocusViewOptions } from '../nodes/FieldView';
-import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
+import { FieldViewProps } from '../nodes/FieldView';
+import { FocusViewOptions } from '../nodes/FocusViewOptions';
import { StyleProp } from '../StyleProvider';
import { CollectionMasonryViewFieldRow } from './CollectionMasonryViewFieldRow';
import './CollectionStackingView.scss';
@@ -296,7 +297,7 @@ export class CollectionStackingView extends CollectionSubView (NumCast(doc.heading) > prevHeading ? NumCast(doc.heading) : prevHeading), 0);
const heading = maxHeading === 0 || this._props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3;
newDoc.heading = heading;
- FormattedTextBox.SetSelectOnLoad(newDoc);
+ Doc.SetSelectOnLoad(newDoc);
FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
return this._props.addDocument?.(newDoc) || false;
};
@@ -240,7 +242,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
const height = this._ele ? DivHeight(this._ele) : 0;
DocUtils.addDocumentCreatorMenuItems(
doc => {
- FormattedTextBox.SetSelectOnLoad(doc);
+ Doc.SetSelectOnLoad(doc);
return this._props.addDocument?.(doc);
},
this._props.addDocument,
@@ -255,7 +257,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
docItems.push({
description: ':' + fieldKey,
event: () => {
- const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document));
+ const created = DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document));
if (created) {
if (this._props.Document.isTemplateDoc) {
Doc.MakeMetadataFieldTemplate(created, this._props.Document);
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index f3dedaedf..7c08aedb1 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -3,7 +3,7 @@ import * as React from 'react';
import * as rp from 'request-promise';
import { ClientUtils, returnFalse } from '../../../ClientUtils';
import CursorField from '../../../fields/CursorField';
-import { Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc';
+import { Doc, DocListCast, GetDocFromUrl, GetHrefFromHTML, Opt, RTFIsFragment, StrListCast } from '../../../fields/Doc';
import { AclPrivate } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
@@ -15,8 +15,9 @@ import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
import { GestureUtils } from '../../../pen-gestures/GestureUtils';
import { DocServer } from '../../DocServer';
import { Networking } from '../../Network';
+import { DocUtils } from '../../documents/DocUtils';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
-import { DocUtils, Docs, DocumentOptions } from '../../documents/Documents';
+import { Docs, DocumentOptions } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { dropActionType } from '../../util/DropActionTypes';
import { ImageUtils } from '../../util/Import & Export/ImageUtils';
@@ -26,7 +27,6 @@ import { UndoManager, undoBatch } from '../../util/UndoManager';
import { ViewBoxBaseComponent } from '../DocComponent';
import { FieldViewProps } from '../nodes/FieldView';
import { LoadingBox } from '../nodes/LoadingBox';
-import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
export interface CollectionViewProps extends React.PropsWithChildren {
isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc)
@@ -317,10 +317,10 @@ export function CollectionSubView() {
const addDocument = (doc: Doc | Doc[]) => this.addDocument(doc);
if (html) {
- if (FormattedTextBox.IsFragment(html)) {
- const href = FormattedTextBox.GetHref(html);
+ if (RTFIsFragment(html)) {
+ const href = GetHrefFromHTML(html);
if (href) {
- const docId = FormattedTextBox.GetDocFromUrl(href);
+ const docId = GetDocFromUrl(href);
if (docId) {
// prosemirror text containing link to dash document
DocServer.GetRefField(docId).then(f => {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 365b5acfd..d015e73ad 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -12,7 +12,8 @@ import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast, toList } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
import { emptyFunction, Utils } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager } from '../../util/DragManager';
import { dropActionType } from '../../util/DropActionTypes';
@@ -189,7 +190,7 @@ export class CollectionTreeView extends CollectionSubView 0 && prev) {
- FormattedTextBox.SetSelectOnLoad(prev);
+ Doc.SetSelectOnLoad(prev);
DocumentManager.Instance.getDocumentView(prev, this.DocumentView?.())?.select(false);
}
return true;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index d6cbe0dab..7cadd072b 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -7,14 +7,15 @@ import { Doc, DocListCast } from '../../../fields/Doc';
import { ObjectField } from '../../../fields/ObjectField';
import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { CollectionViewType } from '../../documents/DocumentTypes';
-import { DocUtils } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
+import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
import { ImageUtils } from '../../util/Import & Export/ImageUtils';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent';
-import { OpenWhere } from '../nodes/DocumentView';
import { FieldView } from '../nodes/FieldView';
+import { OpenWhere } from '../nodes/OpenWhere';
import { CollectionCalendarView } from './CollectionCalendarView';
import { CollectionCarousel3DView } from './CollectionCarousel3DView';
import { CollectionCarouselView } from './CollectionCarouselView';
@@ -234,3 +235,19 @@ export class CollectionView extends ViewBoxAnnotatableComponent {
const fieldKey = Doc.LayoutFieldKey(newParent);
if (remove && fieldKey && Cast(newParent[fieldKey], listSpec(Doc)) !== undefined) {
remove(child);
- FormattedTextBox.SetSelectOnLoad(child);
+ Doc.SetSelectOnLoad(child);
TreeView._editTitleOnLoad = editTitle ? { id: child[Id], parent } : undefined;
Doc.AddDocToList(newParent, fieldKey, child, addAfter, false);
newParent.treeView_Open = true;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 653a01a04..f55d5a23f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -9,7 +9,7 @@ import { computedFn } from 'mobx-utils';
import * as React from 'react';
import { ClientUtils, DashColor, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../../ClientUtils';
import { DateField } from '../../../../fields/DateField';
-import { Doc, DocListCast, Field, FieldType, Opt } from '../../../../fields/Doc';
+import { ActiveInkWidth, Doc, DocListCast, Field, FieldType, Opt, SetActiveInkColor, SetActiveInkWidth } from '../../../../fields/Doc';
import { DocData, Height, Width } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { InkData, InkField, InkTool, Segment } from '../../../../fields/InkField';
@@ -23,8 +23,9 @@ import { TraceMobx } from '../../../../fields/util';
import { Gestures, PointData } from '../../../../pen-gestures/GestureTypes';
import { GestureUtils } from '../../../../pen-gestures/GestureUtils';
import { aggregateBounds, emptyFunction, intersectRect, Utils } from '../../../../Utils';
-import { Docs, DocUtils } from '../../../documents/Documents';
+import { Docs } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
+import { DocUtils } from '../../../documents/DocUtils';
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager } from '../../../util/DragManager';
import { dropActionType } from '../../../util/DropActionTypes';
@@ -39,13 +40,15 @@ import { undoable, undoBatch, UndoManager } from '../../../util/UndoManager';
import { Timeline } from '../../animationtimeline/Timeline';
import { ContextMenu } from '../../ContextMenu';
import { GestureOverlay } from '../../GestureOverlay';
-import { ActiveInkWidth, InkingStroke, SetActiveInkColor, SetActiveInkWidth } from '../../InkingStroke';
+import { InkingStroke } from '../../InkingStroke';
import { LightboxView } from '../../LightboxView';
import { CollectionFreeFormDocumentView } from '../../nodes/CollectionFreeFormDocumentView';
import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp';
-import { DocumentView, OpenWhere } from '../../nodes/DocumentView';
-import { FieldViewProps, FocusViewOptions } from '../../nodes/FieldView';
+import { DocumentView } from '../../nodes/DocumentView';
+import { FieldViewProps } from '../../nodes/FieldView';
+import { FocusViewOptions } from '../../nodes/FocusViewOptions';
import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
+import { OpenWhere } from '../../nodes/OpenWhere';
import { PinDocView, PinProps } from '../../PinFuncs';
import { StyleProp } from '../../StyleProvider';
import { CollectionSubView } from '../CollectionSubView';
@@ -285,7 +288,7 @@ export class CollectionFreeFormView extends CollectionSubView this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout);
isAnyChildContentActive = () => this._props.isAnyChildContentActive();
addLiveTextBox = (newDoc: Doc) => {
- FormattedTextBox.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+ Doc.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
this.addDocument(newDoc);
};
selectDocuments = (docs: Doc[]) => {
@@ -1052,7 +1055,7 @@ export class CollectionFreeFormView extends CollectionSubView {
const text = Docs.Create.TextDocument('', { _width: 150, _height: 50 });
- FormattedTextBox.SetSelectOnLoad(text); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+ Doc.SetSelectOnLoad(text); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
Doc.AddDocToList(this.Document, this._props.fieldKey, text);
this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(clickEv.clientX, clickEv.clientY))));
})
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index ee79812a1..406a7d626 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -13,7 +13,8 @@ import { List } from '../../../../fields/List';
import { listSpec } from '../../../../fields/Schema';
import { ColumnType } from '../../../../fields/SchemaHeaderField';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
-import { DocUtils, Docs, DocumentOptions, FInfo } from '../../../documents/Documents';
+import { DocUtils } from '../../../documents/DocUtils';
+import { Docs, DocumentOptions, FInfo } from '../../../documents/Documents';
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager } from '../../../util/DragManager';
import { dropActionType } from '../../../util/DropActionTypes';
@@ -26,7 +27,8 @@ import { ObservableReactComponent } from '../../ObservableReactComponent';
import { DefaultStyleProvider, StyleProp } from '../../StyleProvider';
import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../../nodes/DocumentView';
-import { FieldViewProps, FocusViewOptions } from '../../nodes/FieldView';
+import { FieldViewProps } from '../../nodes/FieldView';
+import { FocusViewOptions } from '../../nodes/FocusViewOptions';
import { KeyValueBox } from '../../nodes/KeyValueBox';
import { CollectionSubView } from '../CollectionSubView';
import './CollectionSchemaView.scss';
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
index 61afe08cf..32b48e4d1 100644
--- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
@@ -5,8 +5,8 @@ import { computedFn } from 'mobx-utils';
import * as React from 'react';
import { CgClose, CgLock, CgLockUnlock } from 'react-icons/cg';
import { FaExternalLinkAlt } from 'react-icons/fa';
-import { emptyFunction } from '../../../../Utils';
import { returnFalse, setupMoveUpEvents } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
import { Doc } from '../../../../fields/Doc';
import { BoolCast } from '../../../../fields/Types';
import { DragManager } from '../../../util/DragManager';
@@ -15,8 +15,8 @@ import { Transform } from '../../../util/Transform';
import { undoable } from '../../../util/UndoManager';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
-import { OpenWhere } from '../../nodes/DocumentView';
import { FieldView, FieldViewProps } from '../../nodes/FieldView';
+import { OpenWhere } from '../../nodes/OpenWhere';
import { CollectionSchemaView } from './CollectionSchemaView';
import './CollectionSchemaView.scss';
import { SchemaTableCell } from './SchemaTableCell';
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 231bac541..d17d4ff7c 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -1,7 +1,7 @@
import { Colors } from 'browndash-components';
import { action, runInAction } from 'mobx';
import { aggregateBounds } from '../../../Utils';
-import { Doc, Opt } from '../../../fields/Doc';
+import { ActiveFillColor, ActiveInkColor, ActiveInkHideTextLabels, ActiveInkWidth, ActiveIsInkMask, Doc, Opt, SetActiveFillColor, SetActiveInkColor, SetActiveInkHideTextLabels, SetActiveInkWidth, SetActiveIsInkMask } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { InkTool } from '../../../fields/InkField';
import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types';
@@ -13,7 +13,7 @@ import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SelectionManager } from '../../util/SelectionManager';
import { UndoManager, undoable } from '../../util/UndoManager';
import { GestureOverlay } from '../GestureOverlay';
-import { ActiveFillColor, ActiveInkColor, ActiveInkHideTextLabels, ActiveInkWidth, ActiveIsInkMask, InkingStroke, SetActiveFillColor, SetActiveInkColor, SetActiveInkHideTextLabels, SetActiveInkWidth, SetActiveIsInkMask } from '../InkingStroke';
+import { InkingStroke } from '../InkingStroke';
import { CollectionFreeFormView } from '../collections/collectionFreeForm';
import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
import { DocumentView } from '../nodes/DocumentView';
@@ -111,7 +111,7 @@ ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) {
if (NumCast(selected?.Document.z) >= 1) return true;
return false;
}
- selected ? selected.CollectionFreeFormDocumentView?.float() : console.log('[FontIconBox.tsx] toggleOverlay failed');
+ selected ? CollectionFreeFormDocumentView.from(selected)?.float() : console.log('[FontIconBox.tsx] toggleOverlay failed');
return undefined;
});
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 278d30d6a..df3accb0d 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -20,8 +20,9 @@ import { SelectionManager } from '../../util/SelectionManager';
import { SettingsManager } from '../../util/SettingsManager';
import { undoBatch } from '../../util/UndoManager';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { DocumentView, DocumentViewInternal, OpenWhere } from '../nodes/DocumentView';
+import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
import { LinkInfo } from '../nodes/LinkDocPreview';
+import { OpenWhere } from '../nodes/OpenWhere';
import './LinkMenuItem.scss';
interface LinkMenuItemProps {
diff --git a/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx b/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx
index bce2b296f..72d81e9eb 100644
--- a/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx
+++ b/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx
@@ -5,7 +5,7 @@ import { InkTool } from '../../../../fields/InkField';
import { SelectionManager } from '../../../util/SelectionManager';
import { SnappingManager } from '../../../util/SnappingManager';
import { CollectionDockingView } from '../../collections/CollectionDockingView';
-import { OpenWhereMod } from '../../nodes/DocumentView';
+import { OpenWhereMod } from '../../nodes/OpenWhere';
import { NewLightboxView } from '../NewLightboxView';
import './ButtonMenu.scss';
import { IButtonMenu } from './utils';
diff --git a/src/client/views/newlightbox/NewLightboxView.tsx b/src/client/views/newlightbox/NewLightboxView.tsx
index 6616abad1..dc6bf3e9c 100644
--- a/src/client/views/newlightbox/NewLightboxView.tsx
+++ b/src/client/views/newlightbox/NewLightboxView.tsx
@@ -6,10 +6,9 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../../ClientUtils';
import { emptyFunction } from '../../../Utils';
-import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc';
import { InkTool } from '../../../fields/InkField';
import { Cast, NumCast, StrCast, toList } from '../../../fields/Types';
-import { DocUtils } from '../../documents/Documents';
import { DocumentManager } from '../../util/DocumentManager';
import { LinkManager } from '../../util/LinkManager';
import { SelectionManager } from '../../util/SelectionManager';
@@ -20,7 +19,8 @@ import { LightboxView } from '../LightboxView';
import { DefaultStyleProvider } from '../StyleProvider';
import { CollectionStackedTimeline } from '../collections/CollectionStackedTimeline';
import { TabDocView } from '../collections/TabDocView';
-import { DocumentView, OpenWhere } from '../nodes/DocumentView';
+import { DocumentView } from '../nodes/DocumentView';
+import { OpenWhere } from '../nodes/OpenWhere';
import { ExploreView } from './ExploreView';
import { IBounds, emptyBounds } from './ExploreView/utils';
import { NewLightboxHeader } from './Header';
@@ -108,7 +108,7 @@ export class NewLightboxView extends React.Component {
Doc.ActiveTool = InkTool.None;
SnappingManager.SetExploreMode(false);
} else {
- const l = DocUtils.MakeLinkToActiveAudio(() => doc).lastElement();
+ const l = CreateLinkToActiveAudio(() => doc).lastElement();
l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
CollectionStackedTimeline.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.());
// TabDocView.PinDoc(doc, { hidePresBox: true });
@@ -150,7 +150,7 @@ export class NewLightboxView extends React.Component {
const target = (NewLightboxView._docTarget = this._future?.pop());
const targetDocView = target && DocumentManager.Instance.getLightboxDocumentView(target);
if (targetDocView && target) {
- const l = DocUtils.MakeLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.(true) || target).lastElement();
+ const l = CreateLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.(true) || target).lastElement();
l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
DocumentManager.Instance.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
if (NewLightboxView._history?.lastElement().target !== target) NewLightboxView._history?.push({ doc, target });
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 1f618135f..4697491e0 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -13,7 +13,9 @@ import { ComputedField } from '../../../fields/ScriptField';
import { Cast, DateCast, NumCast } from '../../../fields/Types';
import { AudioField, nullAudio } from '../../../fields/URLField';
import { formatTime } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { DocUtils } from '../../documents/DocUtils';
import { Networking } from '../../Network';
import { DragManager } from '../../util/DragManager';
import { LinkManager } from '../../util/LinkManager';
@@ -24,8 +26,8 @@ import { ContextMenuProps } from '../ContextMenuItem';
import { ViewBoxAnnotatableComponent } from '../DocComponent';
import { PinDocView, PinProps } from '../PinFuncs';
import './AudioBox.scss';
-import { OpenWhere } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
+import { OpenWhere } from './OpenWhere';
/**
* AudioBox
@@ -761,3 +763,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent() {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.AUDIO, {
+ layout: { view: AudioBox, dataField: 'data' },
+ options: { acl: '', _height: 100, _layout_fitWidth: true, _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true, systemIcon: 'BsFillVolumeUpFill' },
+});
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 9c4d748bd..691d07e31 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -11,14 +11,16 @@ import { ComputedField } from '../../../fields/ScriptField';
import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
import { DocumentManager } from '../../util/DocumentManager';
+import { DragManager } from '../../util/DragManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SelectionManager } from '../../util/SelectionManager';
import { DocComponent } from '../DocComponent';
import { StyleProp } from '../StyleProvider';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import './CollectionFreeFormDocumentView.scss';
-import { DocumentView, DocumentViewProps, OpenWhere } from './DocumentView';
+import { DocumentView, DocumentViewProps } from './DocumentView';
import { FieldViewProps } from './FieldView';
+import { OpenWhere } from './OpenWhere';
/// Ugh, typescript has no run-time way of iterating through the keys of an interface. so we need
/// manaully keep this list of keys in synch wih the fields of the freeFormProps interface
@@ -48,7 +50,7 @@ export class CollectionFreeFormDocumentView extends DocComponent()
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.COMPARISON, {
+ data: '',
+ layout: { view: ComparisonBox, dataField: 'data' },
+ options: {
+ acl: '',
+ backgroundColor: 'gray',
+ dropAction: dropActionType.move,
+ waitForDoubleClickToClick: 'always',
+ _layout_reflowHorizontal: true,
+ _layout_reflowVertical: true,
+ _layout_nativeDimEditable: true,
+ systemIcon: 'BsLayoutSplit',
+ },
+});
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 113a857c3..ecfdcc229 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -13,22 +13,26 @@ import { List } from '../../../../fields/List';
import { Cast, CsvCast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
import { CsvField } from '../../../../fields/URLField';
import { TraceMobx } from '../../../../fields/util';
-import { DocUtils, Docs } from '../../../documents/Documents';
+import { DocUtils } from '../../../documents/DocUtils';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { Docs } from '../../../documents/Documents';
import { DocumentManager } from '../../../util/DocumentManager';
import { UndoManager, undoable } from '../../../util/UndoManager';
-import { PinProps, ViewBoxAnnotatableComponent, ViewBoxInterface } from '../../DocComponent';
+import { ContextMenu } from '../../ContextMenu';
+import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../../DocComponent';
import { MarqueeAnnotator } from '../../MarqueeAnnotator';
+import { PinProps } from '../../PinFuncs';
import { SidebarAnnos } from '../../SidebarAnnos';
import { AnchorMenu } from '../../pdf/AnchorMenu';
import { GPTPopup, GPTPopupMode } from '../../pdf/GPTPopup/GPTPopup';
import { DocumentView } from '../DocumentView';
-import { FieldView, FieldViewProps, FocusViewOptions } from '../FieldView';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
import './DataVizBox.scss';
import { Histogram } from './components/Histogram';
import { LineChart } from './components/LineChart';
import { PieChart } from './components/PieChart';
import { TableBox } from './components/TableBox';
-import { ContextMenu } from '../../ContextMenu';
export enum DataVizView {
TABLE = 'table',
@@ -522,3 +526,18 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im
);
}
}
+Docs.Prototypes.TemplateMap.set(DocumentType.DATAVIZ, {
+ layout: { view: DataVizBox, dataField: 'data' },
+ options: {
+ acl: '',
+ dataViz_title: '',
+ dataViz_line: '',
+ dataViz_pie: '',
+ dataViz_histogram: '',
+ dataViz: 'table',
+ _layout_fitWidth: true,
+ _layout_reflowHorizontal: true,
+ _layout_reflowVertical: true,
+ _layout_nativeDimEditable: true,
+ },
+});
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 9b4e36509..977899589 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -10,13 +10,13 @@ import { emptyFunction } from '../../../Utils';
import { Doc } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { StrCast } from '../../../fields/Types';
-import { DocUtils } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
import { DragManager } from '../../util/DragManager';
import { Hypothesis } from '../../util/HypothesisUtils';
import { LinkManager } from '../../util/LinkManager';
import { UndoManager, undoBatch } from '../../util/UndoManager';
-import { PinProps } from '../DocComponent';
import { ObservableReactComponent } from '../ObservableReactComponent';
+import { PinProps } from '../PinFuncs';
import './DocumentLinksButton.scss';
import { DocumentView } from './DocumentView';
import { LinkDescriptionPopup } from './LinkDescriptionPopup';
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a603de10b..e8d1e582e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -16,20 +16,20 @@ import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { PrefetchProxy } from '../../../fields/Proxy';
import { listSpec } from '../../../fields/Schema';
-import { ScriptField } from '../../../fields/ScriptField';
+import { FollowLinkScript, ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { AudioField } from '../../../fields/URLField';
import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
import { DocServer } from '../../DocServer';
import { Networking } from '../../Network';
+import { DocUtils } from '../../documents/DocUtils';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
-import { DocUtils, Docs } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
import { DictationManager } from '../../util/DictationManager';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager } from '../../util/DragManager';
import { dropActionType } from '../../util/DropActionTypes';
import { MakeTemplate, makeUserTemplateButton } from '../../util/DropConverter';
-import { FollowLinkScript } from '../../util/LinkFollower';
import { LinkManager, UPDATE_SERVER_CACHE } from '../../util/LinkManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SearchUtil } from '../../util/SearchUtil';
@@ -48,38 +48,14 @@ import { AudioAnnoState, StyleProp } from '../StyleProvider';
import { DocumentContentsView, ObserverJsxParser } from './DocumentContentsView';
import { DocumentLinksButton } from './DocumentLinksButton';
import './DocumentView.scss';
-import { FieldViewProps, FieldViewSharedProps, FocusViewOptions } from './FieldView';
+import { FieldViewProps, FieldViewSharedProps } from './FieldView';
+import { FocusViewOptions } from './FocusViewOptions';
import { KeyValueBox } from './KeyValueBox';
import { LinkAnchorBox } from './LinkAnchorBox';
+import { OpenWhere } from './OpenWhere';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
import { PresEffect, PresEffectDirection } from './trails';
-export enum OpenWhereMod {
- none = '',
- left = 'left',
- right = 'right',
- top = 'top',
- bottom = 'bottom',
- keyvalue = 'keyValue',
-}
-export enum OpenWhere {
- lightbox = 'lightbox',
- add = 'add',
- addLeft = 'add:left',
- addRight = 'add:right',
- addBottom = 'add:bottom',
- close = 'close',
- toggle = 'toggle',
- toggleRight = 'toggle:right',
- replace = 'replace',
- replaceRight = 'replace:right',
- replaceLeft = 'replace:left',
- inParent = 'inParent',
- inParentFromScreen = 'inParentFromScreen',
- overlay = 'overlay',
- addRightKeyvalue = 'add:right:keyValue',
-}
-
export interface DocumentViewProps extends FieldViewSharedProps {
hideDecorations?: boolean; // whether to suppress all DocumentDecorations when doc is selected
hideResizeHandles?: boolean; // whether to suppress resized handles on doc decorations when this document is selected
@@ -292,7 +268,8 @@ export class DocumentViewInternal extends DocComponent docView.props.dragEnding?.();
+ dragData.dragStarting = () => docView.props.dragStarting?.();
dragData.canEmbed = !!(this.Document.dragAction ?? this._props.dragAction);
(this._props.dragConfig ?? this._componentView?.dragConfig)?.(dragData);
DragManager.StartDocumentDrag(
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index 9c216cba4..32d08fbe7 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -3,10 +3,12 @@ import { action, makeObservable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { DivHeight, DivWidth } from '../../../ClientUtils';
-import { Id } from '../../../fields/FieldSymbols';
+import { Doc } from '../../../fields/Doc';
import { NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { DocUtils, Docs } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
import { undoBatch } from '../../util/UndoManager';
import { ViewBoxBaseComponent } from '../DocComponent';
import { LightboxView } from '../LightboxView';
@@ -19,7 +21,6 @@ export class EquationBox extends ViewBoxBaseComponent() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(EquationBox, fieldKey);
}
- public static SelectOnLoad: string = '';
_ref: React.RefObject = React.createRef();
constructor(props: FieldViewProps) {
@@ -29,12 +30,12 @@ export class EquationBox extends ViewBoxBaseComponent() {
componentDidMount() {
this._props.setContentViewBox?.(this);
- if (EquationBox.SelectOnLoad === this.Document[Id] && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.()))) {
+ if (Doc.SelectOnLoad === this.Document && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.()))) {
this._props.select(false);
this._ref.current!.mathField.focus();
this.dataDoc.text === 'x' && this._ref.current!.mathField.select();
- EquationBox.SelectOnLoad = '';
+ Doc.SetSelectOnLoad(undefined);
}
reaction(
() => StrCast(this.dataDoc.text),
@@ -69,7 +70,7 @@ export class EquationBox extends ViewBoxBaseComponent() {
x: NumCast(this.layoutDoc.x),
y: NumCast(this.layoutDoc.y) + _height + 10,
});
- EquationBox.SelectOnLoad = nextEq[Id];
+ Doc.SetSelectOnLoad(nextEq);
this._props.addDocument?.(nextEq);
e.stopPropagation();
}
@@ -130,3 +131,8 @@ export class EquationBox extends ViewBoxBaseComponent() {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.EQUATION, {
+ layout: { view: EquationBox, dataField: 'text' },
+ options: { acl: '', fontSize: '14px', _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true, layout_hideDecorationTitle: true, systemIcon: 'BsCalculatorFill' }, // systemIcon: 'BsSuperscript' + BsSubscript
+});
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index ab0850790..c6c77d8d2 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -10,29 +10,12 @@ import { ScriptField } from '../../../fields/ScriptField';
import { WebField } from '../../../fields/URLField';
import { dropActionType } from '../../util/DropActionTypes';
import { Transform } from '../../util/Transform';
-import { PinProps, ViewBoxInterface } from '../DocComponent';
-import { DocumentView, OpenWhere } from './DocumentView';
+import { ViewBoxInterface } from '../DocComponent';
+import { PinProps } from '../PinFuncs';
+import { DocumentView } from './DocumentView';
+import { FocusViewOptions } from './FocusViewOptions';
+import { OpenWhere } from './OpenWhere';
-export interface FocusViewOptions {
- willPan?: boolean; // determines whether to pan to target document
- willZoomCentered?: boolean; // determines whether to zoom in on target document. if zoomScale is 0, this just centers the document
- zoomScale?: number; // percent of containing frame to zoom into document
- zoomTime?: number;
- didMove?: boolean; // whether a document was changed during the showDocument process
- docTransform?: Transform; // when a document can't be panned and zoomed within its own container (say a group), then we need to continue to move up the render hierarchy to find something that can pan and zoom. when this happens the docTransform must accumulate all the transforms of each level of the hierarchy
- instant?: boolean; // whether focus should happen instantly (as opposed to smooth zoom)
- preview?: boolean; // whether changes should be previewed by the componentView or written to the document
- effect?: Doc; // animation effect for focus // bcz: needs to be changed to something more generic than a Doc
- noSelect?: boolean; // whether target should be selected after focusing
- playAudio?: boolean; // whether to play audio annotation on focus
- playMedia?: boolean; // whether to play start target videos
- openLocation?: OpenWhere; // where to open a missing document
- zoomTextSelections?: boolean; // whether to display a zoomed overlay of anchor text selections
- toggleTarget?: boolean; // whether to toggle target on and off
- easeFunc?: 'linear' | 'ease'; // transition method for scrolling
- pointFocus?: { X: number; Y: number }; // clientX and clientY coordinates to focus on instead of a document target (used by explore mode)
- contextPath?: Doc[]; // path of inner documents that will also be focused
-}
export type FocusFuncType = (doc: Doc, options: FocusViewOptions) => Opt;
// eslint-disable-next-line no-use-before-define
export type StyleProviderFuncType = (doc: Opt, props: Opt, property: string) => any;
diff --git a/src/client/views/nodes/FocusViewOptions.ts b/src/client/views/nodes/FocusViewOptions.ts
new file mode 100644
index 000000000..bb0d2b03c
--- /dev/null
+++ b/src/client/views/nodes/FocusViewOptions.ts
@@ -0,0 +1,24 @@
+import { Doc } from '../../../fields/Doc';
+import { Transform } from '../../util/Transform';
+import { OpenWhere } from './OpenWhere';
+
+export interface FocusViewOptions {
+ willPan?: boolean; // determines whether to pan to target document
+ willZoomCentered?: boolean; // determines whether to zoom in on target document. if zoomScale is 0, this just centers the document
+ zoomScale?: number; // percent of containing frame to zoom into document
+ zoomTime?: number;
+ didMove?: boolean; // whether a document was changed during the showDocument process
+ docTransform?: Transform; // when a document can't be panned and zoomed within its own container (say a group), then we need to continue to move up the render hierarchy to find something that can pan and zoom. when this happens the docTransform must accumulate all the transforms of each level of the hierarchy
+ instant?: boolean; // whether focus should happen instantly (as opposed to smooth zoom)
+ preview?: boolean; // whether changes should be previewed by the componentView or written to the document
+ effect?: Doc; // animation effect for focus // bcz: needs to be changed to something more generic than a Doc
+ noSelect?: boolean; // whether target should be selected after focusing
+ playAudio?: boolean; // whether to play audio annotation on focus
+ playMedia?: boolean; // whether to play start target videos
+ openLocation?: OpenWhere; // where to open a missing document
+ zoomTextSelections?: boolean; // whether to display a zoomed overlay of anchor text selections
+ toggleTarget?: boolean; // whether to toggle target on and off
+ easeFunc?: 'linear' | 'ease'; // transition method for scrolling
+ pointFocus?: { X: number; Y: number }; // clientX and clientY coordinates to focus on instead of a document target (used by explore mode)
+ contextPath?: Doc[]; // path of inner documents that will also be focused
+}
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index 1b2aefbe2..d83690cdd 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -9,6 +9,7 @@ import { ClientUtils, returnTrue, setupMoveUpEvents } from '../../../../ClientUt
import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
import { BoolCast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
import { emptyFunction } from '../../../../Utils';
+import { Docs } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
import { SelectionManager } from '../../../util/SelectionManager';
import { SettingsManager } from '../../../util/SettingsManager';
@@ -18,8 +19,8 @@ import { ViewBoxBaseComponent } from '../../DocComponent';
import { EditableView } from '../../EditableView';
import { SelectedDocView } from '../../selectedDoc';
import { StyleProp } from '../../StyleProvider';
-import { OpenWhere } from '../DocumentView';
import { FieldView, FieldViewProps } from '../FieldView';
+import { OpenWhere } from '../OpenWhere';
import './FontIconBox.scss';
import TrailsIcon from './TrailsIcon';
@@ -51,15 +52,6 @@ export class FontIconBox extends ViewBoxBaseComponent() {
super(props);
makeObservable(this);
}
- //
- // This controls whether fontIconButtons will display labels under their icons or not
- //
- public static get ShowIconLabels() {
- return BoolCast(Doc.UserDoc()._showLabel);
- }
- public static set ShowIconLabels(show: boolean) {
- Doc.UserDoc()._showLabel = show;
- }
@observable noTooltip = false;
@@ -397,3 +389,8 @@ export class FontIconBox extends ViewBoxBaseComponent() {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.FONTICON, {
+ layout: { view: FontIconBox, dataField: 'icon' },
+ options: { acl: '', defaultDoubleClick: 'ignore', waitForDoubleClickToClick: 'never', layout_hideContextMenu: true, layout_hideLinkButton: true, _width: 40, _height: 40 },
+});
diff --git a/src/client/views/nodes/FunctionPlotBox.tsx b/src/client/views/nodes/FunctionPlotBox.tsx
index 31faa7ac3..f32d39aaf 100644
--- a/src/client/views/nodes/FunctionPlotBox.tsx
+++ b/src/client/views/nodes/FunctionPlotBox.tsx
@@ -7,12 +7,14 @@ import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
import { Cast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { DocUtils, Docs } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { LinkManager } from '../../util/LinkManager';
import { undoBatch } from '../../util/UndoManager';
import { ViewBoxAnnotatableComponent } from '../DocComponent';
-import { PinProps, PinDocView } from '../PinFuncs';
+import { PinDocView, PinProps } from '../PinFuncs';
import { FieldView, FieldViewProps } from './FieldView';
@observer
@@ -138,3 +140,8 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.FUNCPLOT, {
+ layout: { view: FunctionPlotBox, dataField: 'data' },
+ options: { acl: '', _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true },
+});
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 8bd5ab03d..d317f46bb 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -15,8 +15,9 @@ import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
import { emptyFunction } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
+import { DocUtils } from '../../documents/DocUtils';
import { Networking } from '../../Network';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager } from '../../util/DragManager';
@@ -30,9 +31,10 @@ import { OverlayView } from '../OverlayView';
import { AnchorMenu } from '../pdf/AnchorMenu';
import { PinDocView, PinProps } from '../PinFuncs';
import { StyleProp } from '../StyleProvider';
-import { OpenWhere } from './DocumentView';
-import { FieldView, FieldViewProps, FocusViewOptions } from './FieldView';
+import { FieldView, FieldViewProps } from './FieldView';
+import { FocusViewOptions } from './FocusViewOptions';
import './ImageBox.scss';
+import { OpenWhere } from './OpenWhere';
export class ImageEditorData {
// eslint-disable-next-line no-use-before-define
@@ -546,3 +548,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl
input.click();
};
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.IMG, {
+ layout: { view: ImageBox, dataField: 'data' },
+ options: { acl: '', freeform: '', systemIcon: 'BsFileEarmarkImageFill' },
+});
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index b8296ce51..46bb16e50 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -3,12 +3,13 @@ import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { returnAlways, returnTrue } from '../../../ClientUtils';
-import { Doc, Field, FieldType, FieldResult } from '../../../fields/Doc';
+import { Doc, Field, FieldResult, FieldType } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { RichTextField } from '../../../fields/RichTextField';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { DocCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
+import { DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
import { SetupDrag } from '../../util/DragManager';
import { CompiledScript } from '../../util/Scripting';
@@ -17,11 +18,11 @@ import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { DocumentIconContainer } from './DocumentIcon';
-import { OpenWhere } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import { ImageBox } from './ImageBox';
import './KeyValueBox.scss';
import { KeyValuePair } from './KeyValuePair';
+import { OpenWhere } from './OpenWhere';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
export type KVPScript = {
@@ -339,3 +340,8 @@ export class KeyValueBox extends ObservableReactComponent {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.KVP, {
+ layout: { view: KeyValueBox, dataField: 'data' },
+ options: { acl: '', _layout_fitWidth: true, _height: 150 },
+});
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index a9aa017a1..878b0e54c 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -14,10 +14,11 @@ import { ContextMenu } from '../ContextMenu';
import { EditableView } from '../EditableView';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { DefaultStyleProvider } from '../StyleProvider';
-import { OpenWhere, returnEmptyDocViewList } from './DocumentView';
+import { returnEmptyDocViewList } from './DocumentView';
import { KeyValueBox } from './KeyValueBox';
import './KeyValueBox.scss';
import './KeyValuePair.scss';
+import { OpenWhere } from './OpenWhere';
// Represents one row in a key value plane
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index 89270652c..4dec3506c 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -5,13 +5,14 @@ import { Doc, DocListCast, Field, FieldType } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types';
+import { DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { undoBatch } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { ViewBoxBaseComponent } from '../DocComponent';
-import { PinProps, PinDocView } from '../PinFuncs';
+import { PinDocView, PinProps } from '../PinFuncs';
import { StyleProp } from '../StyleProvider';
import { FieldView, FieldViewProps } from './FieldView';
import BigText from './LabelBigText';
@@ -203,3 +204,12 @@ export class LabelBox extends ViewBoxBaseComponent() {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.LABEL, {
+ layout: { view: LabelBox, dataField: 'title' },
+ options: { acl: '', _singleLine: true, _layout_nativeDimEditable: true, _layout_reflowHorizontal: true, _layout_reflowVertical: true },
+});
+Docs.Prototypes.TemplateMap.set(DocumentType.BUTTON, {
+ layout: { view: LabelBox, dataField: 'title' },
+ options: { acl: '', _layout_nativeDimEditable: true, _layout_reflowHorizontal: true, _layout_reflowVertical: true },
+});
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index f01905ee1..559b1fcae 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -7,9 +7,12 @@ import { DashColor, lightOrDark, returnFalse } from '../../../ClientUtils';
import { FieldResult } from '../../../fields/Doc';
import { DocCss, DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
import { DocCast, NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
import { emptyFunction } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
import { DocumentManager } from '../../util/DocumentManager';
import { SnappingManager } from '../../util/SnappingManager';
import { ViewBoxBaseComponent } from '../DocComponent';
@@ -263,3 +266,18 @@ export class LinkBox extends ViewBoxBaseComponent() {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.LINK, {
+ layout: { view: LinkBox, dataField: 'link' },
+ options: {
+ acl: '',
+ childDontRegisterViews: true,
+ layout_hideLinkAnchors: true,
+ _height: 1,
+ _width: 1,
+ link: '',
+ link_description: '',
+ color: 'lightBlue', // lightblue is default color for linking dot and link documents text comment area
+ _dropPropertiesToRemove: new List(['onClick']),
+ },
+});
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index a9cfe6c0e..0936acc15 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -19,9 +19,10 @@ import { SearchUtil } from '../../util/SearchUtil';
import { SettingsManager } from '../../util/SettingsManager';
import { Transform } from '../../util/Transform';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { DocumentView, OpenWhere } from './DocumentView';
+import { DocumentView } from './DocumentView';
import { StyleProviderFuncType } from './FieldView';
import './LinkDocPreview.scss';
+import { OpenWhere } from './OpenWhere';
interface LinkDocPreviewProps {
linkDoc?: Doc;
diff --git a/src/client/views/nodes/LoadingBox.tsx b/src/client/views/nodes/LoadingBox.tsx
index 501831bca..aa89398f3 100644
--- a/src/client/views/nodes/LoadingBox.tsx
+++ b/src/client/views/nodes/LoadingBox.tsx
@@ -10,6 +10,8 @@ import { DocumentManager } from '../../util/DocumentManager';
import { ViewBoxAnnotatableComponent } from '../DocComponent';
import { FieldView, FieldViewProps } from './FieldView';
import './LoadingBox.scss';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
/**
* LoadingBox Class represents a placeholder doc for documents that are currently
@@ -89,3 +91,7 @@ export class LoadingBox extends ViewBoxAnnotatableComponent() {
);
}
}
+Docs.Prototypes.TemplateMap.set(DocumentType.LOADING, {
+ layout: { view: LoadingBox, dataField: '' },
+ options: { acl: '', _layout_fitWidth: true, _layout_nativeDimEditable: true },
+});
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 60dad314f..50831f8ea 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -18,20 +18,21 @@ import { ClientUtils, setupMoveUpEvents } from '../../../../ClientUtils';
import { emptyFunction } from '../../../../Utils';
import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc';
import { DocCast, NumCast, StrCast, toList } from '../../../../fields/Types';
+import { DocUtils } from '../../../documents/DocUtils';
import { DocumentType } from '../../../documents/DocumentTypes';
-import { DocUtils, Docs } from '../../../documents/Documents';
+import { Docs } from '../../../documents/Documents';
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager } from '../../../util/DragManager';
import { LinkManager } from '../../../util/LinkManager';
import { UndoManager, undoable } from '../../../util/UndoManager';
import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../../DocComponent';
-import { PinProps, PinDocView } from '../../PinFuncs';
+import { PinDocView, PinProps } from '../../PinFuncs';
import { SidebarAnnos } from '../../SidebarAnnos';
import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm';
import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../DocumentView';
-import { FieldView, FieldViewProps, FocusViewOptions } from '../FieldView';
-import { FormattedTextBox } from '../formattedText/FormattedTextBox';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
import { fastSpeedIcon, mediumSpeedIcon, slowSpeedIcon } from './AnimationSpeedIcons';
import { AnimationSpeed, AnimationStatus, AnimationUtility } from './AnimationUtility';
import { MapAnchorMenu } from './MapAnchorMenu';
@@ -355,7 +356,7 @@ export class MapBox extends ViewBoxAnnotatableComponent() implem
const targetCreator = (annotationOn: Doc | undefined) => {
const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, annotationOn, 'yellow');
- FormattedTextBox.SetSelectOnLoad(target);
+ Doc.SetSelectOnLoad(target);
return target;
};
const docView = this.DocumentView?.();
@@ -1360,3 +1361,8 @@ export class MapBox extends ViewBoxAnnotatableComponent() implem
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.MAP, {
+ layout: { view: MapBox, dataField: 'data' },
+ options: { acl: '', map: '', _height: 600, _width: 800, _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true, systemIcon: 'BsFillPinMapFill' },
+});
diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
index 6ccbbbe1c..c69cd8e89 100644
--- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
+++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
@@ -32,7 +32,7 @@
// addNoteClick = (e: React.PointerEvent) => {
// setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => {
// const newDoc = Docs.Create.TextDocument('Note', { _layout_autoHeight: true });
-// FormattedTextBox.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+// Doc.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
// Doc.AddDocToList(this.props.place, 'data', newDoc);
// this._stack?.scrollToBottom();
// e.stopPropagation();
diff --git a/src/client/views/nodes/MapBox/MapPushpinBox.tsx b/src/client/views/nodes/MapBox/MapPushpinBox.tsx
index 8ebc90157..f3dc44755 100644
--- a/src/client/views/nodes/MapBox/MapPushpinBox.tsx
+++ b/src/client/views/nodes/MapBox/MapPushpinBox.tsx
@@ -2,6 +2,8 @@ import * as React from 'react';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { FieldView, FieldViewProps } from '../FieldView';
import { MapBoxContainer } from '../MapboxMapBox/MapboxContainer';
+import { Docs } from '../../../documents/Documents';
+import { DocumentType } from '../../../documents/DocumentTypes';
/**
* Map Pushpin doc class
@@ -28,3 +30,8 @@ export class MapPushpinBox extends ViewBoxBaseComponent() {
return ;
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.PUSHPIN, {
+ layout: { view: MapPushpinBox, dataField: 'data' },
+ options: { acl: '' },
+});
diff --git a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
index d899fcb9a..3b4ffd4bd 100644
--- a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
+++ b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
@@ -10,23 +10,24 @@ import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc';
import { DocCss, Highlight } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { DocCast, NumCast, StrCast, toList } from '../../../../fields/Types';
+import { DocUtils } from '../../../documents/DocUtils';
import { DocumentType } from '../../../documents/DocumentTypes';
-import { DocUtils, Docs } from '../../../documents/Documents';
+import { Docs } from '../../../documents/Documents';
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager } from '../../../util/DragManager';
import { LinkManager } from '../../../util/LinkManager';
import { Transform } from '../../../util/Transform';
import { UndoManager, undoable } from '../../../util/UndoManager';
import { ViewBoxAnnotatableComponent } from '../../DocComponent';
-import { PinProps, PinDocView } from '../../PinFuncs';
+import { PinDocView, PinProps } from '../../PinFuncs';
import { SidebarAnnos } from '../../SidebarAnnos';
import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm';
import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../DocumentView';
-import { FieldView, FieldViewProps, FocusViewOptions } from '../FieldView';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
import { MapAnchorMenu } from '../MapBox/MapAnchorMenu';
import '../MapBox/MapBox.scss';
-import { FormattedTextBox } from '../formattedText/FormattedTextBox';
/**
* MapBox architecture:
@@ -237,7 +238,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent
const targetCreator = (annotationOn: Doc | undefined) => {
const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, annotationOn, 'yellow');
- FormattedTextBox.SetSelectOnLoad(target);
+ Doc.SetSelectOnLoad(target);
return target;
};
const docView = this.DocumentView?.();
diff --git a/src/client/views/nodes/OpenWhere.ts b/src/client/views/nodes/OpenWhere.ts
new file mode 100644
index 000000000..e2a5f1f2a
--- /dev/null
+++ b/src/client/views/nodes/OpenWhere.ts
@@ -0,0 +1,25 @@
+export enum OpenWhereMod {
+ none = '',
+ left = 'left',
+ right = 'right',
+ top = 'top',
+ bottom = 'bottom',
+ keyvalue = 'keyValue',
+}
+export enum OpenWhere {
+ lightbox = 'lightbox',
+ add = 'add',
+ addLeft = 'add:left',
+ addRight = 'add:right',
+ addBottom = 'add:bottom',
+ close = 'close',
+ toggle = 'toggle',
+ toggleRight = 'toggle:right',
+ replace = 'replace',
+ replaceRight = 'replace:right',
+ replaceLeft = 'replace:left',
+ inParent = 'inParent',
+ inParentFromScreen = 'inParentFromScreen',
+ overlay = 'overlay',
+ addRightKeyvalue = 'add:right:keyValue',
+}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index fbf5e018c..5d1874aca 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -16,8 +16,9 @@ import { Cast, FieldValue, ImageCast, NumCast, StrCast, toList } from '../../../
import { ImageField, PdfField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
import { emptyFunction } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
+import { DocUtils } from '../../documents/DocUtils';
import { DocumentManager } from '../../util/DocumentManager';
import { KeyCodes } from '../../util/KeyCodes';
import { SelectionManager } from '../../util/SelectionManager';
@@ -31,9 +32,11 @@ import { Colors } from '../global/globalEnums';
import { PDFViewer } from '../pdf/PDFViewer';
import { PinDocView, PinProps } from '../PinFuncs';
import { SidebarAnnos } from '../SidebarAnnos';
-import { DocumentView, OpenWhere } from './DocumentView';
-import { FieldView, FieldViewProps, FocusViewOptions } from './FieldView';
+import { DocumentView } from './DocumentView';
+import { FieldView, FieldViewProps } from './FieldView';
+import { FocusViewOptions } from './FocusViewOptions';
import { ImageBox } from './ImageBox';
+import { OpenWhere } from './OpenWhere';
import './PDFBox.scss';
import { CreateImage } from './WebBoxRenderer';
@@ -665,3 +668,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem
return pdfView ?? this.renderTitleBox;
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.PDF, {
+ layout: { view: PDFBox, dataField: 'data' },
+ options: { acl: '', _layout_curPage: 1, _layout_fitWidth: true, _layout_nativeDimEditable: true, _layout_reflowVertical: true, systemIcon: 'BsFileEarmarkPdfFill' },
+});
diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
index ae674d604..f88eb3bca 100644
--- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
+++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
@@ -1,3 +1,11 @@
+/* eslint-disable camelcase */
+/* eslint-disable jsx-a11y/control-has-associated-label */
+/* eslint-disable @typescript-eslint/no-unused-vars */
+/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable react/no-array-index-key */
+/* eslint-disable react/jsx-props-no-spreading */
+/* eslint-disable no-return-assign */
import ArrowLeftIcon from '@mui/icons-material/ArrowLeft';
import ArrowRightIcon from '@mui/icons-material/ArrowRight';
import PauseIcon from '@mui/icons-material/Pause';
@@ -13,13 +21,15 @@ import { NumListCast } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
import { BoolCast, NumCast, StrCast } from '../../../../fields/Types';
import { ViewBoxAnnotatableComponent } from '../../DocComponent';
-import { FieldView, FieldViewProps } from './../FieldView';
+import { FieldView, FieldViewProps } from '../FieldView';
import './PhysicsSimulationBox.scss';
import InputField from './PhysicsSimulationInputField';
import questions from './PhysicsSimulationQuestions.json';
import tutorials from './PhysicsSimulationTutorial.json';
import Wall from './PhysicsSimulationWall';
import Weight from './PhysicsSimulationWeight';
+import { Docs } from '../../../documents/Documents';
+import { DocumentType } from '../../../documents/DocumentTypes';
interface IWallProps {
length: number;
@@ -204,7 +214,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent) {
super.componentDidUpdate(prevProps);
- if (this.xMax !== this._props.PanelWidth() * 0.6 || this.yMax != this._props.PanelHeight()) {
+ if (this.xMax !== this._props.PanelWidth() * 0.6 || this.yMax !== this._props.PanelHeight()) {
this.xMax = this._props.PanelWidth() * 0.6;
this.yMax = this._props.PanelHeight();
this.setupSimulation();
@@ -219,16 +229,16 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent {
- const simulationType = this.simulationType;
+ const { simulationType } = this;
const mode = this.simulationMode;
this.dataDoc.simulation_paused = true;
- if (simulationType != 'Circular Motion') {
+ if (simulationType !== 'Circular Motion') {
this.dataDoc.mass1_velocityXstart = 0;
this.dataDoc.mass1_velocityYstart = 0;
this.dataDoc.mass1_velocityX = 0;
this.dataDoc.mass1_velocityY = 0;
}
- if (mode == 'Freeform') {
+ if (mode === 'Freeform') {
this.dataDoc.simulation_showForceMagnitudes = true;
// prettier-ignore
switch (simulationType) {
@@ -247,9 +257,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent {
let theta = this.wedgeAngle;
- let index = this.selectedQuestion.variablesForQuestionSetup.indexOf('theta - max 45');
+ const index = this.selectedQuestion.variablesForQuestionSetup.indexOf('theta - max 45');
if (index >= 0) {
theta = NumListCast(this.dataDoc.questionVariables)[index];
}
@@ -467,26 +480,26 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent {
let error: boolean = false;
- let epsilon: number = 0.01;
+ const epsilon: number = 0.01;
if (this.selectedQuestion) {
for (let i = 0; i < this.selectedQuestion.answerParts.length; i++) {
- if (this.selectedQuestion.answerParts[i] == 'force of gravity') {
+ if (this.selectedQuestion.answerParts[i] === 'force of gravity') {
if (Math.abs(NumCast(this.dataDoc.review_GravityMagnitude) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'angle of gravity') {
+ } else if (this.selectedQuestion.answerParts[i] === 'angle of gravity') {
if (Math.abs(NumCast(this.dataDoc.review_GravityAngle) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'normal force') {
+ } else if (this.selectedQuestion.answerParts[i] === 'normal force') {
if (Math.abs(NumCast(this.dataDoc.review_NormalMagnitude) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'angle of normal force') {
+ } else if (this.selectedQuestion.answerParts[i] === 'angle of normal force') {
if (Math.abs(NumCast(this.dataDoc.review_NormalAngle) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'force of static friction') {
+ } else if (this.selectedQuestion.answerParts[i] === 'force of static friction') {
if (Math.abs(NumCast(this.dataDoc.review_StaticMagnitude) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'angle of static friction') {
+ } else if (this.selectedQuestion.answerParts[i] === 'angle of static friction') {
if (Math.abs(NumCast(this.dataDoc.review_StaticAngle) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'coefficient of static friction') {
+ } else if (this.selectedQuestion.answerParts[i] === 'coefficient of static friction') {
if (Math.abs(NumCast(this.dataDoc.coefficientOfStaticFriction) - this.selectedSolutions[i]) > epsilon) {
error = true;
}
- } else if (this.selectedQuestion.answerParts[i] == 'wedge angle') {
+ } else if (this.selectedQuestion.answerParts[i] === 'wedge angle') {
if (Math.abs(this.wedgeAngle - this.selectedSolutions[i]) > epsilon) {
error = true;
}
@@ -539,7 +552,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent (this.dataDoc.simulation_paused = true), 3000);
}
- if (this.selectedQuestion.goal == 'noMovement') {
+ if (this.selectedQuestion.goal === 'noMovement') {
this.dataDoc.noMovement = !error;
}
};
@@ -571,12 +584,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent(this.getAnswersToQuestion(question, vars));
- //this.dataDoc.simulation_reset = (!this.dataDoc.simulation_reset);
+ // this.dataDoc.simulation_reset = (!this.dataDoc.simulation_reset);
};
// Default setup for uniform circular motion simulation
@@ -610,8 +623,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent {
- let xPos = (this.xMax + this.xMin) / 2 - this.mass1Radius;
- let yPos = this.yMin + 200;
+ const xPos = (this.xMax + this.xMin) / 2 - this.mass1Radius;
+ const yPos = this.yMin + 200;
this.dataDoc.mass1_positionYstart = yPos;
this.dataDoc.mass1_positionXstart = xPos;
this.dataDoc.mass1_positionY = this.getDisplayYPos(yPos);
this.dataDoc.mass1_positionX = xPos;
- let tensionMag = (this.mass1 * Math.abs(this.gravity)) / (2 * Math.sin(Math.PI / 4));
+ const tensionMag = (this.mass1 * Math.abs(this.gravity)) / (2 * Math.sin(Math.PI / 4));
const tensionForce1: IForce = {
description: 'Tension',
magnitude: tensionMag,
@@ -891,7 +904,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
- {this.simulationType == 'Pulley' && (
+ {this.simulationType === 'Pulley' && (
- {(this.simulationType == 'One Weight' || this.simulationType == 'Inclined Plane') &&
+ {(this.simulationType === 'One Weight' || this.simulationType === 'Inclined Plane') &&
this.wallPositions?.map((element, index) => )}
@@ -927,17 +940,17 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
- {this.dataDoc.simulation_paused && this.simulationMode != 'Tutorial' && (
+ {this.dataDoc.simulation_paused && this.simulationMode !== 'Tutorial' && (
(this.dataDoc.simulation_paused = false)}>
)}
- {!this.dataDoc.simulation_paused && this.simulationMode != 'Tutorial' && (
+ {!this.dataDoc.simulation_paused && this.simulationMode !== 'Tutorial' && (
(this.dataDoc.simulation_paused = true)}>
)}
- {this.dataDoc.simulation_paused && this.simulationMode != 'Tutorial' && (
+ {this.dataDoc.simulation_paused && this.simulationMode !== 'Tutorial' && (
this._simReset++)}>
@@ -974,15 +987,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
- {this.simulationMode == 'Review' && this.simulationType != 'Inclined Plane' && (
+ {this.simulationMode === 'Review' && this.simulationType !== 'Inclined Plane' && (
-
- <>{this.simulationType} review problems in progress!>
-
+
{this.simulationType} review problems in progress!
)}
- {this.simulationMode == 'Review' && this.simulationType == 'Inclined Plane' && (
+ {this.simulationMode === 'Review' && this.simulationType === 'Inclined Plane' && (
{!this.dataDoc.hintDialogueOpen && (
)}
-
)}
- {this.simulationMode == 'Tutorial' && (
+ {this.simulationMode === 'Tutorial' && (
Problem
@@ -1180,7 +1191,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
+ disabled={this.dataDoc.tutorial_stepNumber === 0}>
@@ -1204,8 +1215,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
- {(this.simulationType == 'One Weight' || this.simulationType == 'Inclined Plane' || this.simulationType == 'Pendulum') &&
Resources
}
- {this.simulationType == 'One Weight' && (
+ {(this.simulationType === 'One Weight' || this.simulationType === 'Inclined Plane' || this.simulationType === 'Pendulum') &&
Resources
}
+ {this.simulationType === 'One Weight' && (
)}
- {this.simulationType == 'Inclined Plane' && (
+ {this.simulationType === 'Inclined Plane' && (
)}
- {this.simulationType == 'Pendulum' && (
+ {this.simulationType === 'Pendulum' && (
)}
- {this.simulationMode == 'Review' && this.simulationType == 'Inclined Plane' && (
+ {this.simulationMode === 'Review' && this.simulationType === 'Inclined Plane' && (
)}
- {this.simulationMode == 'Freeform' && (
+ {this.simulationMode === 'Freeform' && (
- {this.simulationType == 'One Weight' && (
+ {this.simulationType === 'One Weight' && (
(this.dataDoc.elasticCollisions = !this.dataDoc.elasticCollisions)} />}
label="Make collisions elastic"
@@ -1334,7 +1345,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
- {(this.simulationType == 'Inclined Plane' || this.simulationType == 'Pendulum') && (
+ {(this.simulationType === 'Inclined Plane' || this.simulationType === 'Pendulum') && (
(this.dataDoc.simulation_showComponentForces = !this.dataDoc.simulation_showComponentForces)} />}
label="Show component force vectors"
@@ -1351,80 +1362,80 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
- Speed} lowerBound={1} dataDoc={this.dataDoc} prop="simulation_speed" step={1} unit={'x'} upperBound={10} value={NumCast(this.dataDoc.simulation_speed, 2)} labelWidth={'5em'} />
- {this.dataDoc.simulation_paused && this.simulationType != 'Circular Motion' && (
+ Speed} lowerBound={1} dataDoc={this.dataDoc} prop="simulation_speed" step={1} unit="x" upperBound={10} value={NumCast(this.dataDoc.simulation_speed, 2)} labelWidth="5em" />
+ {this.dataDoc.simulation_paused && this.simulationType !== 'Circular Motion' && (
Gravity}
lowerBound={-30}
dataDoc={this.dataDoc}
prop="gravity"
step={0.01}
- unit={'m/s2'}
+ unit="m/s2"
upperBound={0}
value={NumCast(this.dataDoc.simulation_gravity, -9.81)}
effect={(val: number) => this.setupSimulation()}
- labelWidth={'5em'}
+ labelWidth="5em"
/>
)}
- {this.dataDoc.simulation_paused && this.simulationType != 'Pulley' && (
+ {this.dataDoc.simulation_paused && this.simulationType !== 'Pulley' && (
Mass}
lowerBound={1}
dataDoc={this.dataDoc}
prop="mass1"
step={0.1}
- unit={'kg'}
+ unit="kg"
upperBound={5}
value={this.mass1 ?? 1}
effect={(val: number) => this.setupSimulation()}
- labelWidth={'5em'}
+ labelWidth="5em"
/>
)}
- {this.dataDoc.simulation_paused && this.simulationType == 'Pulley' && (
+ {this.dataDoc.simulation_paused && this.simulationType === 'Pulley' && (
Red mass}
lowerBound={1}
dataDoc={this.dataDoc}
prop="mass1"
step={0.1}
- unit={'kg'}
+ unit="kg"
upperBound={5}
value={this.mass1 ?? 1}
effect={(val: number) => this.setupSimulation()}
- labelWidth={'5em'}
+ labelWidth="5em"
/>
)}
- {this.dataDoc.simulation_paused && this.simulationType == 'Pulley' && (
+ {this.dataDoc.simulation_paused && this.simulationType === 'Pulley' && (
Blue mass}
lowerBound={1}
dataDoc={this.dataDoc}
prop="mass2"
step={0.1}
- unit={'kg'}
+ unit="kg"
upperBound={5}
value={this.mass2 ?? 1}
effect={(val: number) => this.setupSimulation()}
- labelWidth={'5em'}
+ labelWidth="5em"
/>
)}
- {this.dataDoc.simulation_paused && this.simulationType == 'Circular Motion' && (
+ {this.dataDoc.simulation_paused && this.simulationType === 'Circular Motion' && (
Rod length}
lowerBound={100}
dataDoc={this.dataDoc}
prop="circularMotionRadius"
step={5}
- unit={'m'}
+ unit="m"
upperBound={250}
value={this.circularMotionRadius}
effect={(val: number) => this.setupSimulation()}
- labelWidth={'5em'}
+ labelWidth="5em"
/>
)}
- {this.simulationType == 'Spring' && this.dataDoc.simulation_paused && (
+ {this.simulationType === 'Spring' && this.dataDoc.simulation_paused && (
Spring stiffness}
@@ -1432,13 +1443,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent this._simReset++)}
radianEquivalent={false}
- mode={'Freeform'}
- labelWidth={'7em'}
+ mode="Freeform"
+ labelWidth="7em"
/>
Rest length}
@@ -1452,7 +1463,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent this._simReset++)}
radianEquivalent={false}
mode="Freeform"
- labelWidth={'7em'}
+ labelWidth="7em"
/>
Starting displacement}
@@ -1470,11 +1481,11 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)}
- {this.simulationType == 'Inclined Plane' && this.dataDoc.simulation_paused && (
+ {this.simulationType === 'Inclined Plane' && this.dataDoc.simulation_paused && (
θ}
@@ -1482,16 +1493,16 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent {
this.changeWedgeBasedOnNewAngle(val);
this._simReset++;
})}
- radianEquivalent={true}
- mode={'Freeform'}
- labelWidth={'2em'}
+ radianEquivalent
+ mode="Freeform"
+ labelWidth="2em"
/>
{
@@ -1513,8 +1524,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
this._simReset++)}
- mode={'Freeform'}
- labelWidth={'2em'}
+ mode="Freeform"
+ labelWidth="2em"
/>
)}
- {this.simulationType == 'Inclined Plane' && !this.dataDoc.simulation_paused && (
+ {this.simulationType === 'Inclined Plane' && !this.dataDoc.simulation_paused && (
<>
θ: {Math.round(this.wedgeAngle * 100) / 100}° ≈ {Math.round(((this.wedgeAngle * Math.PI) / 180) * 100) / 100} rad
@@ -1546,12 +1557,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)}
- {this.simulationType == 'Pendulum' && !this.dataDoc.simulation_paused && (
+ {this.simulationType === 'Pendulum' && !this.dataDoc.simulation_paused && (
θ: {Math.round(this.pendulumAngle * 100) / 100}° ≈ {Math.round(((this.pendulumAngle * Math.PI) / 180) * 100) / 100} rad
)}
- {this.simulationType == 'Pendulum' && this.dataDoc.simulation_paused && (
+ {this.simulationType === 'Pendulum' && this.dataDoc.simulation_paused && (
Angle}
@@ -1559,13 +1570,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent {
this.dataDoc.pendulum_angleStart = value;
this.dataDoc.pendulum_lengthStart = this.dataDoc.pendulum_length;
- if (this.simulationType == 'Pendulum') {
+ if (this.simulationType === 'Pendulum') {
const mag = this.mass1 * Math.abs(this.gravity) * Math.cos((value * Math.PI) / 180);
const forceOfTension: IForce = {
@@ -1598,7 +1609,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
@@ -1612,7 +1623,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent {
- if (this.simulationType == 'Pendulum') {
+ if (this.simulationType === 'Pendulum') {
this.dataDoc.pendulum_angleStart = this.pendulumAngle;
this.dataDoc.pendulum_lengthStart = value;
this._simReset++;
@@ -1627,11 +1638,11 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)}
- {this.simulationMode == 'Freeform' && (
+ {this.simulationMode === 'Freeform' && (
- | {this.simulationType == 'Pulley' ? 'Red Weight' : ''} |
+ {this.simulationType === 'Pulley' ? 'Red Weight' : ''} |
X |
Y |
@@ -1646,36 +1657,34 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
Position
- {(!this.dataDoc.simulation_paused || this.simulationType == 'Inclined Plane' || this.simulationType == 'Circular Motion' || this.simulationType == 'Pulley') && (
-
- <>{this.dataDoc.mass1_positionX} m>
- |
+ {(!this.dataDoc.simulation_paused || this.simulationType === 'Inclined Plane' || this.simulationType === 'Circular Motion' || this.simulationType === 'Pulley') && (
+ {this.dataDoc.mass1_positionX + ''} m |
)}{' '}
- {this.dataDoc.simulation_paused && this.simulationType != 'Inclined Plane' && this.simulationType != 'Circular Motion' && this.simulationType != 'Pulley' && (
+ {this.dataDoc.simulation_paused && this.simulationType !== 'Inclined Plane' && this.simulationType !== 'Circular Motion' && this.simulationType !== 'Pulley' && (
{
this.dataDoc.mass1_xChange = value;
- if (this.simulationType == 'Suspension') {
- let x1rod = (this.xMax + this.xMin) / 2 - this.radius - this.yMin - 200;
- let x2rod = (this.xMax + this.xMin) / 2 + this.yMin + 200 + this.radius;
- let deltaX1 = value + this.radius - x1rod;
- let deltaX2 = x2rod - (value + this.radius);
- let deltaY = this.getYPosFromDisplay(NumCast(this.dataDoc.mass1_positionY)) + this.radius;
+ if (this.simulationType === 'Suspension') {
+ const x1rod = (this.xMax + this.xMin) / 2 - this.radius - this.yMin - 200;
+ const x2rod = (this.xMax + this.xMin) / 2 + this.yMin + 200 + this.radius;
+ const deltaX1 = value + this.radius - x1rod;
+ const deltaX2 = x2rod - (value + this.radius);
+ const deltaY = this.getYPosFromDisplay(NumCast(this.dataDoc.mass1_positionY)) + this.radius;
let dir1T = Math.PI - Math.atan(deltaY / deltaX1);
let dir2T = Math.atan(deltaY / deltaX2);
- let tensionMag2 = (this.mass1 * Math.abs(this.gravity)) / ((-Math.cos(dir2T) / Math.cos(dir1T)) * Math.sin(dir1T) + Math.sin(dir2T));
- let tensionMag1 = (-tensionMag2 * Math.cos(dir2T)) / Math.cos(dir1T);
+ const tensionMag2 = (this.mass1 * Math.abs(this.gravity)) / ((-Math.cos(dir2T) / Math.cos(dir1T)) * Math.sin(dir1T) + Math.sin(dir2T));
+ const tensionMag1 = (-tensionMag2 * Math.cos(dir2T)) / Math.cos(dir1T);
dir1T = (dir1T * 180) / Math.PI;
dir2T = (dir2T * 180) / Math.PI;
const tensionForce1: IForce = {
@@ -1692,15 +1701,15 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
|
)}{' '}
- {(!this.dataDoc.simulation_paused || this.simulationType == 'Inclined Plane' || this.simulationType == 'Circular Motion' || this.simulationType == 'Pulley') && (
+ {(!this.dataDoc.simulation_paused || this.simulationType === 'Inclined Plane' || this.simulationType === 'Circular Motion' || this.simulationType === 'Pulley') && (
{`${NumCast(this.dataDoc.mass1_positionY)} m`} |
)}{' '}
- {this.dataDoc.simulation_paused && this.simulationType != 'Inclined Plane' && this.simulationType != 'Circular Motion' && this.simulationType != 'Pulley' && (
+ {this.dataDoc.simulation_paused && this.simulationType !== 'Inclined Plane' && this.simulationType !== 'Circular Motion' && this.simulationType !== 'Pulley' && (
{
this.dataDoc.mass1_yChange = value;
- if (this.simulationType == 'Suspension') {
- let x1rod = (this.xMax + this.xMin) / 2 - this.radius - this.yMin - 200;
- let x2rod = (this.xMax + this.xMin) / 2 + this.yMin + 200 + this.radius;
- let deltaX1 = NumCast(this.dataDoc.mass1_positionX) + this.radius - x1rod;
- let deltaX2 = x2rod - (NumCast(this.dataDoc.mass1_positionX) + this.radius);
- let deltaY = this.getYPosFromDisplay(value) + this.radius;
+ if (this.simulationType === 'Suspension') {
+ const x1rod = (this.xMax + this.xMin) / 2 - this.radius - this.yMin - 200;
+ const x2rod = (this.xMax + this.xMin) / 2 + this.yMin + 200 + this.radius;
+ const deltaX1 = NumCast(this.dataDoc.mass1_positionX) + this.radius - x1rod;
+ const deltaX2 = x2rod - (NumCast(this.dataDoc.mass1_positionX) + this.radius);
+ const deltaY = this.getYPosFromDisplay(value) + this.radius;
let dir1T = Math.PI - Math.atan(deltaY / deltaX1);
let dir2T = Math.atan(deltaY / deltaX2);
- let tensionMag2 = (this.mass1 * Math.abs(this.gravity)) / ((-Math.cos(dir2T) / Math.cos(dir1T)) * Math.sin(dir1T) + Math.sin(dir2T));
- let tensionMag1 = (-tensionMag2 * Math.cos(dir2T)) / Math.cos(dir1T);
+ const tensionMag2 = (this.mass1 * Math.abs(this.gravity)) / ((-Math.cos(dir2T) / Math.cos(dir1T)) * Math.sin(dir1T) + Math.sin(dir2T));
+ const tensionMag1 = (-tensionMag2 * Math.cos(dir2T)) / Math.cos(dir1T);
dir1T = (dir1T * 180) / Math.PI;
dir2T = (dir2T * 180) / Math.PI;
const tensionForce1: IForce = {
@@ -1741,7 +1750,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
|
@@ -1758,10 +1767,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
Velocity
- {(!this.dataDoc.simulation_paused || (this.simulationType != 'One Weight' && this.simulationType != 'Circular Motion')) && (
+ {(!this.dataDoc.simulation_paused || (this.simulationType !== 'One Weight' && this.simulationType !== 'Circular Motion')) && (
{`${NumCast(this.dataDoc.mass1_velocityX)} m/s`} |
)}{' '}
- {this.dataDoc.simulation_paused && (this.simulationType == 'One Weight' || this.simulationType == 'Circular Motion') && (
+ {this.dataDoc.simulation_paused && (this.simulationType === 'One Weight' || this.simulationType === 'Circular Motion') && (
{
this.dataDoc.mass1_velocityXstart = value;
this._simReset++;
})}
- small={true}
+ small
mode="Freeform"
/>
|
)}{' '}
- {(!this.dataDoc.simulation_paused || this.simulationType != 'One Weight') && (
-
- <>{this.dataDoc.mass1_velocityY} m/s>
- |
- )}{' '}
- {this.dataDoc.simulation_paused && this.simulationType == 'One Weight' && (
+ {(!this.dataDoc.simulation_paused || this.simulationType !== 'One Weight') && {this.dataDoc.mass1_velocityY + ''} m/s | }{' '}
+ {this.dataDoc.simulation_paused && this.simulationType === 'One Weight' && (
{
this.dataDoc.mass1_velocityYstart = -value;
}}
- small={true}
+ small
mode="Freeform"
/>
|
@@ -1822,14 +1827,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponentAcceleration
- <>
- {this.dataDoc.mass1_accelerationX} m/s2
- >
+ {this.dataDoc.mass1_accelerationX + ''} m/s2
|
- <>
- {this.dataDoc.mass1_accelerationY} m/s2
- >
+ {this.dataDoc.mass1_accelerationY + ''} m/s2
|
@@ -1842,7 +1843,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)}
- {this.simulationMode == 'Freeform' && this.simulationType == 'Pulley' && (
+ {this.simulationMode === 'Freeform' && this.simulationType === 'Pulley' && (
@@ -1869,14 +1870,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponentAcceleration
|
- <>
- {this.dataDoc.mass2_accelerationX} m/s2
- >
+ {this.dataDoc.mass2_accelerationX + ''} m/s2
|
- <>
- {this.dataDoc.mass2_accelerationY} m/s2
- >
+ {this.dataDoc.mass2_accelerationY + ''} m/s2
|
@@ -1890,7 +1887,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)}
- {this.simulationType != 'Pendulum' && this.simulationType != 'Spring' && (
+ {this.simulationType !== 'Pendulum' && this.simulationType !== 'Spring' && (
Kinematic Equations
@@ -1907,7 +1904,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)}
- {this.simulationType == 'Spring' && (
+ {this.simulationType === 'Spring' && (
Harmonic Motion Equations: Spring
@@ -1936,7 +1933,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)}
- {this.simulationType == 'Pendulum' && (
+ {this.simulationType === 'Pendulum' && (
Harmonic Motion Equations: Pendulum
@@ -1959,11 +1956,11 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
-
+
-
-
+
+
- {this.simulationType == 'Circular Motion' ? 'Z' : 'Y'}
+ {this.simulationType === 'Circular Motion' ? 'Z' : 'Y'}
()
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.SCREENSHOT, {
+ layout: { view: ScreenshotBox, dataField: 'data' },
+ options: { acl: '', _layout_nativeDimEditable: true, systemIcon: 'BsCameraFill' },
+});
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index 5ebc50a1b..bc19d7ad1 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -21,6 +21,8 @@ import { OverlayView } from '../OverlayView';
import { FieldView, FieldViewProps } from './FieldView';
import { DocumentIconContainer } from './DocumentIcon';
import './ScriptingBox.scss';
+import { Docs } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
const _global = (window /* browser */ || global) /* node */ as any;
const ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete').default;
@@ -845,3 +847,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent()
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.SCRIPTING, {
+ layout: { view: ScriptingBox, dataField: 'data' },
+ options: { acl: '', systemIcon: 'BsFileEarmarkCodeFill' },
+});
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 13ee3250e..16767d11e 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -10,14 +10,15 @@ import { DocData } from '../../../fields/DocSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
+import { FollowLinkScript } from '../../../fields/ScriptField';
import { Cast, NumCast, StrCast, toList } from '../../../fields/Types';
import { AudioField, ImageField, VideoField } from '../../../fields/URLField';
import { emptyFunction, formatTime } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
+import { DocUtils } from '../../documents/DocUtils';
import { DocumentManager } from '../../util/DocumentManager';
import { dropActionType } from '../../util/DropActionTypes';
-import { FollowLinkScript } from '../../util/LinkFollower';
import { LinkManager } from '../../util/LinkManager';
import { ReplayMovements } from '../../util/ReplayMovements';
import { undoBatch } from '../../util/UndoManager';
@@ -31,7 +32,8 @@ import { AnchorMenu } from '../pdf/AnchorMenu';
import { PinDocView, PinProps } from '../PinFuncs';
import { StyleProp } from '../StyleProvider';
import { DocumentView } from './DocumentView';
-import { FieldView, FieldViewProps, FocusViewOptions } from './FieldView';
+import { FieldView, FieldViewProps } from './FieldView';
+import { FocusViewOptions } from './FocusViewOptions';
import { RecordingBox } from './RecordingBox';
import './VideoBox.scss';
@@ -1162,3 +1164,12 @@ export class VideoBox extends ViewBoxAnnotatableComponent() impl
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.VID, {
+ layout: { view: VideoBox, dataField: 'data' },
+ options: { acl: '', _layout_currentTimecode: 0, systemIcon: 'BsFileEarmarkPlayFill' },
+});
+Docs.Prototypes.TemplateMap.set(DocumentType.REC, {
+ layout: { view: VideoBox, dataField: 'data' },
+ options: { acl: '', _height: 100, backgroundColor: 'pink', systemIcon: 'BsFillMicFill' },
+});
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index dfe237a86..54f246b20 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -18,7 +18,9 @@ import { Cast, NumCast, StrCast, toList, WebCast } from '../../../fields/Types';
import { ImageField, WebField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
import { emptyFunction, stringHash } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { DocUtils } from '../../documents/DocUtils';
import { DocumentManager } from '../../util/DocumentManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SnappingManager } from '../../util/SnappingManager';
@@ -37,9 +39,11 @@ import { GPTPopup } from '../pdf/GPTPopup/GPTPopup';
import { PinDocView, PinProps } from '../PinFuncs';
import { SidebarAnnos } from '../SidebarAnnos';
import { StyleProp } from '../StyleProvider';
-import { DocumentView, OpenWhere } from './DocumentView';
-import { FieldView, FieldViewProps, FocusViewOptions } from './FieldView';
+import { DocumentView } from './DocumentView';
+import { FieldView, FieldViewProps } from './FieldView';
+import { FocusViewOptions } from './FocusViewOptions';
import { LinkInfo } from './LinkDocPreview';
+import { OpenWhere } from './OpenWhere';
import './WebBox.scss';
const { CreateImage } = require('./WebBoxRenderer');
@@ -1242,3 +1246,8 @@ export class WebBox extends ViewBoxAnnotatableComponent() implem
ScriptingGlobals.add(function urlHash(url: string) {
return stringHash(url);
});
+
+Docs.Prototypes.TemplateMap.set(DocumentType.WEB, {
+ layout: { view: WebBox, dataField: 'data' },
+ options: { acl: '', _height: 300, _layout_fitWidth: true, _layout_nativeDimEditable: true, _layout_reflowVertical: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' },
+});
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
index 8b9e3cc5d..bd66941c3 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.tsx
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -7,6 +7,8 @@ import * as React from 'react';
import { dateRangeStrToDates } from '../../../../ClientUtils';
import { Doc } from '../../../../fields/Doc';
import { StrCast } from '../../../../fields/Types';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { Docs } from '../../../documents/Documents';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { FieldView, FieldViewProps } from '../FieldView';
@@ -119,3 +121,7 @@ export class CalendarBox extends ViewBoxBaseComponent() {
);
}
}
+Docs.Prototypes.TemplateMap.set(DocumentType.CALENDAR, {
+ layout: { view: CalendarBox, dataField: 'data' },
+ options: { acl: '' },
+});
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index f311b3cdd..93371685d 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -9,11 +9,12 @@ import { Doc } from '../../../../fields/Doc';
import { Height, Width } from '../../../../fields/DocSymbols';
import { NumCast } from '../../../../fields/Types';
import { DocServer } from '../../../DocServer';
-import { Docs, DocUtils } from '../../../documents/Documents';
+import { Docs } from '../../../documents/Documents';
+import { DocUtils } from '../../../documents/DocUtils';
import { Transform } from '../../../util/Transform';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { DocumentView } from '../DocumentView';
-import { FocusViewOptions } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
import { FormattedTextBox } from './FormattedTextBox';
const horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side.
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index dc388b22a..1c5ea2dd4 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -23,7 +23,7 @@ import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
import { SchemaTableCell } from '../../collections/collectionSchema/SchemaTableCell';
import { FilterPanel } from '../../FilterPanel';
import { ObservableReactComponent } from '../../ObservableReactComponent';
-import { OpenWhere } from '../DocumentView';
+import { OpenWhere } from '../OpenWhere';
import './DashFieldView.scss';
import { FormattedTextBox } from './FormattedTextBox';
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 9bcf5027f..ad6629fc9 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -15,7 +15,7 @@ import * as React from 'react';
import { BsMarkdownFill } from 'react-icons/bs';
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, StopEvent } from '../../../../ClientUtils';
import { DateField } from '../../../../fields/DateField';
-import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc';
+import { CreateLinkToActiveAudio, Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, DocData, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
@@ -28,8 +28,9 @@ import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util';
import { emptyFunction, numberRange, unimplementedFunction, Utils } from '../../../../Utils';
import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT';
import { DocServer } from '../../../DocServer';
-import { Docs, DocUtils } from '../../../documents/Documents';
-import { CollectionViewType } from '../../../documents/DocumentTypes';
+import { Docs } from '../../../documents/Documents';
+import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
+import { DocUtils } from '../../../documents/DocUtils';
import { DictationManager } from '../../../util/DictationManager';
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager } from '../../../util/DragManager';
@@ -54,9 +55,11 @@ import { PinDocView, PinProps } from '../../PinFuncs';
import { SidebarAnnos } from '../../SidebarAnnos';
import { styleFromLayoutString, StyleProp } from '../../StyleProvider';
import { mediaState } from '../AudioBox';
-import { DocumentView, DocumentViewInternal, OpenWhere } from '../DocumentView';
-import { FieldView, FieldViewProps, FocusViewOptions } from '../FieldView';
+import { DocumentView, DocumentViewInternal } from '../DocumentView';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
import { LinkInfo } from '../LinkDocPreview';
+import { OpenWhere } from '../OpenWhere';
import { DashDocCommentView } from './DashDocCommentView';
import { DashDocView } from './DashDocView';
import { DashFieldView } from './DashFieldView';
@@ -182,26 +185,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent {
const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, annotationOn);
- FormattedTextBox.SetSelectOnLoad(target);
+ Doc.SetSelectOnLoad(target);
return target;
};
@@ -992,7 +977,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent });
+ helpItems.push({ description: `show markdown options`, event: () => RTFMarkup.Instance.setOpen(true), icon: });
!help && cm.addItem({ description: 'Help...', subitems: helpItems, icon: 'eye' });
};
@@ -1062,7 +1047,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent>(schema: S, props: any): KeyMa
return true;
});
bind('Cmd-?', () => {
- RTFMarkup.Instance.open();
+ RTFMarkup.Instance.setOpen(true);
return true;
});
bind('Cmd-e', (state: EditorState, dispatch: (tx: Transaction) => void) => {
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index 72a2b706d..1ff862859 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -8,7 +8,8 @@ import { List } from '../../../../fields/List';
import { NumCast, StrCast } from '../../../../fields/Types';
import { Utils } from '../../../../Utils';
import { DocServer } from '../../../DocServer';
-import { Docs, DocUtils } from '../../../documents/Documents';
+import { Docs } from '../../../documents/Documents';
+import { DocUtils } from '../../../documents/DocUtils';
import { CollectionViewType } from '../../../documents/DocumentTypes';
import { CollectionView } from '../../collections/CollectionView';
import { ContextMenu } from '../../ContextMenu';
diff --git a/src/client/views/nodes/generativeFill/GenerativeFill.tsx b/src/client/views/nodes/generativeFill/GenerativeFill.tsx
index 87b7a4069..d5fad296f 100644
--- a/src/client/views/nodes/generativeFill/GenerativeFill.tsx
+++ b/src/client/views/nodes/generativeFill/GenerativeFill.tsx
@@ -14,12 +14,13 @@ import { Doc, DocListCast } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
import { NumCast } from '../../../../fields/Types';
import { Networking } from '../../../Network';
-import { DocUtils, Docs } from '../../../documents/Documents';
+import { DocUtils } from '../../../documents/DocUtils';
+import { Docs } from '../../../documents/Documents';
import { DocumentManager } from '../../../util/DocumentManager';
import { CollectionDockingView } from '../../collections/CollectionDockingView';
import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
-import { OpenWhereMod } from '../DocumentView';
import { ImageEditorData } from '../ImageBox';
+import { OpenWhereMod } from '../OpenWhere';
import './GenerativeFill.scss';
import Buttons from './GenerativeFillButtons';
import { BrushHandler } from './generativeFillUtils/BrushHandler';
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 4cf9e99fa..485ba7367 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -36,8 +36,10 @@ import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
import { LightboxView } from '../../LightboxView';
import { pinDataTypes as dataTypes } from '../../PinFuncs';
-import { DocumentView, OpenWhere, OpenWhereMod } from '../DocumentView';
-import { FieldView, FieldViewProps, FocusViewOptions } from '../FieldView';
+import { DocumentView } from '../DocumentView';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { FocusViewOptions } from '../FocusViewOptions';
+import { OpenWhere, OpenWhereMod } from '../OpenWhere';
import { ScriptingBox } from '../ScriptingBox';
import './PresBox.scss';
import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums';
@@ -423,7 +425,7 @@ export class PresBox extends ViewBoxBaseComponent() {
const acontext = activeItem.config_activeFrame !== undefined ? DocCast(DocCast(activeItem.presentation_targetDoc).embedContainer) : DocCast(activeItem.presentation_targetDoc);
const context = DocCast(acontext)?.annotationOn ? DocCast(DocCast(acontext).annotationOn) : acontext;
if (context) {
- const ffview = DocumentManager.Instance.getFirstDocumentView(context)?.CollectionFreeFormView;
+ const ffview = CollectionFreeFormView.from(DocumentManager.Instance.getFirstDocumentView(context));
if (ffview?.childDocs) {
PresBox.Instance._keyTimer = CollectionFreeFormView.gotoKeyframe(PresBox.Instance._keyTimer, ffview.childDocs, frameTime);
ffview.layoutDoc._currentFrame = NumCast(activeFrame);
@@ -745,7 +747,7 @@ export class PresBox extends ViewBoxBaseComponent() {
};
_exitTrail: Opt<() => void>;
- PlayTrail = (docs: Doc[]) => {
+ playTrail = (docs: Doc[]) => {
const savedStates = docs.map(doc => {
switch (doc.type) {
case DocumentType.COL:
@@ -2688,3 +2690,8 @@ export class PresBox extends ViewBoxBaseComponent() {
ScriptingGlobals.add(function navigateToDoc(bestTarget: Doc, activeItem: Doc) {
PresBox.NavigateToTarget(bestTarget, activeItem);
});
+
+Docs.Prototypes.TemplateMap.set(DocumentType.PRES, {
+ layout: { view: PresBox, dataField: 'data' },
+ options: { acl: '', defaultDoubleClick: 'ignore', hideClickBehaviors: true, layout_hideLinkAnchors: true },
+});
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index cf78a45b7..af0ab3b53 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -12,7 +12,7 @@ import { List } from '../../../../fields/List';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
import { emptyFunction } from '../../../../Utils';
import { Docs } from '../../../documents/Documents';
-import { CollectionViewType } from '../../../documents/DocumentTypes';
+import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager } from '../../../util/DragManager';
import { SettingsManager } from '../../../util/SettingsManager';
@@ -606,3 +606,8 @@ export class PresElementBox extends ViewBoxBaseComponent() {
return !(this.slideDoc instanceof Doc) || this.targetDoc instanceof Promise ? null : this.mainItem;
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.PRESELEMENT, {
+ layout: { view: PresElementBox, dataField: 'data' },
+ options: { acl: '', title: 'pres element template', _layout_fitWidth: true, _xMargin: 0, isTemplateDoc: true, isTemplateForField: 'data' },
+});
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index f1cd1a4f7..8b2b179d3 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -9,8 +9,8 @@ import { LinkFollower } from '../../util/LinkFollower';
import { LinkManager } from '../../util/LinkManager';
import { undoable } from '../../util/UndoManager';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { OpenWhere } from '../nodes/DocumentView';
import { FieldViewProps } from '../nodes/FieldView';
+import { OpenWhere } from '../nodes/OpenWhere';
import { AnchorMenu } from './AnchorMenu';
import './Annotation.scss';
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index 56ff2959c..c1bfdf176 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -12,7 +12,8 @@ import { Doc } from '../../../../fields/Doc';
import { NumCast, StrCast } from '../../../../fields/Types';
import { Networking } from '../../../Network';
import { GPTCallType, gptAPICall, gptImageCall } from '../../../apis/gpt/GPT';
-import { DocUtils, Docs } from '../../../documents/Documents';
+import { Docs } from '../../../documents/Documents';
+import { DocUtils } from '../../../documents/DocUtils';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { AnchorMenu } from '../AnchorMenu';
import './GPTPopup.scss';
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 22355bc57..15ac73f78 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -6,21 +6,22 @@ import * as Pdfjs from 'pdfjs-dist';
import 'pdfjs-dist/web/pdf_viewer.css';
import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs';
import * as React from 'react';
-import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, returnAll, returnFalse, returnNone, returnZero, smoothScroll } from '../../../ClientUtils';
+import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc';
import { DocData, Height } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
import { emptyFunction } from '../../../Utils';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, returnAll, returnFalse, returnNone, returnZero, smoothScroll } from '../../../ClientUtils';
-import { DocUtils } from '../../documents/Documents';
+import { DocUtils } from '../../documents/DocUtils';
import { SelectionManager } from '../../util/SelectionManager';
import { SnappingManager } from '../../util/SnappingManager';
import { MarqueeOptionsMenu } from '../collections/collectionFreeForm';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
-import { FocusViewOptions, FieldViewProps } from '../nodes/FieldView';
+import { FieldViewProps } from '../nodes/FieldView';
+import { FocusViewOptions } from '../nodes/FocusViewOptions';
import { LinkInfo } from '../nodes/LinkDocPreview';
import { PDFBox } from '../nodes/PDFBox';
import { ObservableReactComponent } from '../ObservableReactComponent';
@@ -331,7 +332,7 @@ export class PDFViewer extends ObservableReactComponent {
this._ignoreScroll = false;
if (this._scrollTimer) clearTimeout(this._scrollTimer); // wait until a scrolling pause, then create an anchor to audio
this._scrollTimer = setTimeout(() => {
- DocUtils.MakeLinkToActiveAudio(() => this._props.pdfBox.getAnchor(true)!, false);
+ CreateLinkToActiveAudio(() => this._props.pdfBox.getAnchor(true)!, false);
this._scrollTimer = undefined;
}, 200);
}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 384e6d654..5df934231 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -4,11 +4,14 @@ import { Tooltip } from '@mui/material';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { ClientUtils } from '../../../ClientUtils';
import { Doc, DocListCastAsync, Field, FieldType } from '../../../fields/Doc';
import { DirectLinks, DocData } from '../../../fields/DocSymbols';
+import { Id } from '../../../fields/FieldSymbols';
import { DocCast, StrCast } from '../../../fields/Types';
+import { DocUtils } from '../../documents/DocUtils';
import { DocumentType } from '../../documents/DocumentTypes';
-import { DocUtils } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
import { DocumentManager } from '../../util/DocumentManager';
import { LinkManager } from '../../util/LinkManager';
import { SearchUtil } from '../../util/SearchUtil';
@@ -21,8 +24,6 @@ import { IRecommendation, Recommendation } from '../newlightbox/components';
import { fetchRecommendations } from '../newlightbox/utils';
import { FieldView, FieldViewProps } from '../nodes/FieldView';
import './SearchBox.scss';
-import { Id } from '../../../fields/FieldSymbols';
-import { ClientUtils } from '../../../ClientUtils';
const DAMPENING_FACTOR = 0.9;
const MAX_ITERATIONS = 25;
@@ -520,3 +521,8 @@ export class SearchBox extends ViewBoxBaseComponent() {
);
}
}
+
+Docs.Prototypes.TemplateMap.set(DocumentType.SEARCH, {
+ layout: { view: SearchBox, dataField: 'data' },
+ options: { acl: '', _width: 400 },
+});
diff --git a/src/client/views/selectedDoc/SelectedDocView.tsx b/src/client/views/selectedDoc/SelectedDocView.tsx
index 7ad7b2927..6ed3b240d 100644
--- a/src/client/views/selectedDoc/SelectedDocView.tsx
+++ b/src/client/views/selectedDoc/SelectedDocView.tsx
@@ -8,7 +8,7 @@ import { Doc } from '../../../fields/Doc';
import { StrCast } from '../../../fields/Types';
import { DocumentManager } from '../../util/DocumentManager';
import { SettingsManager } from '../../util/SettingsManager';
-import { FocusViewOptions } from '../nodes/FieldView';
+import { FocusViewOptions } from '../nodes/FocusViewOptions';
export interface SelectedDocViewProps {
selectedDocs: Doc[];
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 9083d6ca3..5fd053eef 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -174,6 +174,49 @@ export function updateCachedAcls(doc: Doc) {
return undefined;
}
+export function ActiveInkPen(): Doc { return Doc.UserDoc(); } // prettier-ignore
+export function ActiveInkColor(): string { return StrCast(ActiveInkPen()?.activeInkColor, 'black'); } // prettier-ignore
+export function ActiveFillColor(): string { return StrCast(ActiveInkPen()?.activeFillColor, ''); } // prettier-ignore
+export function ActiveIsInkMask(): boolean { return BoolCast(ActiveInkPen()?.activeIsInkMask, false); } // prettier-ignore
+export function ActiveInkHideTextLabels(): boolean { return BoolCast(ActiveInkPen().activeInkHideTextLabels, false); } // prettier-ignore
+export function ActiveArrowStart(): string { return StrCast(ActiveInkPen()?.activeArrowStart, ''); } // prettier-ignore
+export function ActiveArrowEnd(): string { return StrCast(ActiveInkPen()?.activeArrowEnd, ''); } // prettier-ignore
+export function ActiveArrowScale(): number { return NumCast(ActiveInkPen()?.activeArrowScale, 1); } // prettier-ignore
+export function ActiveDash(): string { return StrCast(ActiveInkPen()?.activeDash, '0'); } // prettier-ignore
+export function ActiveInkWidth(): number { return Number(ActiveInkPen()?.activeInkWidth); } // prettier-ignore
+export function ActiveInkBezierApprox(): string { return StrCast(ActiveInkPen()?.activeInkBezier); } // prettier-ignore
+
+export function SetActiveInkWidth(width: string): void {
+ !isNaN(parseInt(width)) && ActiveInkPen() && (ActiveInkPen().activeInkWidth = width);
+}
+export function SetActiveBezierApprox(bezier: string): void {
+ ActiveInkPen() && (ActiveInkPen().activeInkBezier = isNaN(parseInt(bezier)) ? '' : bezier);
+}
+export function SetActiveInkColor(value: string) {
+ ActiveInkPen() && (ActiveInkPen().activeInkColor = value);
+}
+export function SetActiveIsInkMask(value: boolean) {
+ ActiveInkPen() && (ActiveInkPen().activeIsInkMask = value);
+}
+export function SetActiveInkHideTextLabels(value: boolean) {
+ ActiveInkPen() && (ActiveInkPen().activeInkHideTextLabels = value);
+}
+export function SetActiveFillColor(value: string) {
+ ActiveInkPen() && (ActiveInkPen().activeFillColor = value);
+}
+export function SetActiveArrowStart(value: string) {
+ ActiveInkPen() && (ActiveInkPen().activeArrowStart = value);
+}
+export function SetActiveArrowEnd(value: string) {
+ ActiveInkPen() && (ActiveInkPen().activeArrowEnd = value);
+}
+export function SetActiveArrowScale(value: number) {
+ ActiveInkPen() && (ActiveInkPen().activeArrowScale = value);
+}
+export function SetActiveDash(dash: string): void {
+ !isNaN(parseInt(dash)) && ActiveInkPen() && (ActiveInkPen().activeDash = dash);
+}
+
@scriptingGlobal
@Deserializable('Doc', updateCachedAcls, ['id'])
export class Doc extends RefField {
@@ -420,6 +463,16 @@ export class Doc extends RefField {
// eslint-disable-next-line no-redeclare
export namespace Doc {
+ // eslint-disable-next-line import/no-mutable-exports
+ export let SelectOnLoad: Doc | undefined;
+ export function SetSelectOnLoad(doc: Doc | undefined) {
+ SelectOnLoad = doc;
+ }
+ // eslint-disable-next-line import/no-mutable-exports
+ export let DocDragDataName: string = '';
+ export function SetDocDragDataName(name: string) {
+ DocDragDataName = name;
+ }
export function SetContainer(doc: Doc, container: Doc) {
if (container !== Doc.MyRecentlyClosed) {
doc.embedContainer = container;
@@ -1605,6 +1658,29 @@ export namespace Doc {
}
}
+export function RTFIsFragment(html: string) {
+ return html.indexOf('data-pm-slice') !== -1;
+}
+export function GetHrefFromHTML(html: string): string {
+ const parser = new DOMParser();
+ const parsedHtml = parser.parseFromString(html, 'text/html');
+ if (parsedHtml.body.childNodes.length === 1 && parsedHtml.body.childNodes[0].childNodes.length === 1 && (parsedHtml.body.childNodes[0].childNodes[0] as any).href) {
+ return (parsedHtml.body.childNodes[0].childNodes[0] as any).href;
+ }
+ return '';
+}
+export function GetDocFromUrl(url: string) {
+ return url.startsWith(document.location.origin) ? new URL(url).pathname.split('doc/').lastElement() : ''; // docId
+}
+
+let activeAudioLinker: (f: () => Doc | undefined, broadcast?: boolean) => (Doc | undefined)[];
+export function SetActiveAudioLinker(func: (f: () => Doc | undefined, broadcast?: boolean) => (Doc | undefined)[]) {
+ activeAudioLinker = func;
+}
+export function CreateLinkToActiveAudio(func: () => Doc | undefined, broadcast?: boolean) {
+ return activeAudioLinker(func, broadcast);
+}
+
export function IdToDoc(id: string) {
return DocCast(DocServer.GetCachedRefField(id));
}
diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts
index a2cc47a43..5eb60a2f8 100644
--- a/src/fields/RichTextUtils.ts
+++ b/src/fields/RichTextUtils.ts
@@ -12,7 +12,8 @@ import { DocServer } from '../client/DocServer';
import { Networking } from '../client/Network';
import { GoogleApiClientUtils } from '../client/apis/google_docs/GoogleApiClientUtils';
import { GooglePhotos } from '../client/apis/google_docs/GooglePhotosClientUtils';
-import { DocUtils, Docs } from '../client/documents/Documents';
+import { Docs } from '../client/documents/Documents';
+import { DocUtils } from '../client/documents/DocUtils';
import { FormattedTextBox } from '../client/views/nodes/formattedText/FormattedTextBox';
import { schema } from '../client/views/nodes/formattedText/schema_rts';
import { Doc, Opt } from './Doc';
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 8a3787768..5e5f5527f 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -277,6 +277,10 @@ export class ComputedField extends ScriptField {
}
}
+export function FollowLinkScript() {
+ return ScriptField.MakeScript('return followLink(this,altKey)', { altKey: 'boolean' });
+}
+
ScriptingGlobals.add(
// eslint-disable-next-line prefer-arrow-callback
function setIndexVal(list: any[], index: number, value: any) {
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index b355e70a7..55a85ed1b 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -127,6 +127,7 @@ import './AudioUpload.scss';
import { Uploader } from './ImageUpload';
import './ImageUpload.scss';
import './MobileInterface.scss';
+import { DashboardView } from '../client/views/DashboardView';
library.add(
...[
@@ -583,7 +584,7 @@ export class MobileInterface extends React.Component {
};
const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
- const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, 'row');
+ const dashboardDoc = DashboardView.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, 'row');
const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
const cloneDashboard = ScriptField.MakeScript(`cloneDashboard()`);
--
cgit v1.2.3-70-g09d2
From dd08c20ec6df3fad6ecd6b16c787f10b0c23feb4 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Thu, 2 May 2024 00:39:31 -0400
Subject: lots more dependency cycle unwinding.
---
src/client/documents/DocUtils.ts | 36 ++--
src/client/documents/Documents.ts | 4 +-
src/client/util/BranchingTrailManager.tsx | 5 +-
src/client/util/CalendarManager.tsx | 20 +-
src/client/util/CaptureManager.tsx | 9 +-
src/client/util/CurrentUserUtils.ts | 24 +--
src/client/util/DictationManager.ts | 44 ++++-
src/client/util/DocumentManager.ts | 85 +++-----
src/client/util/DragManager.ts | 13 --
src/client/util/GroupManager.tsx | 2 +-
src/client/util/HypothesisUtils.ts | 10 +-
.../util/Import & Export/DirectoryImportBox.tsx | 1 -
src/client/util/LinkFollower.ts | 31 ++-
src/client/util/LinkManager.ts | 9 +-
src/client/util/PingManager.ts | 4 +-
src/client/util/ReplayMovements.ts | 6 +-
src/client/util/Scripting.ts | 9 +-
src/client/util/SelectionManager.ts | 29 +--
src/client/util/SettingsManager.tsx | 20 +-
src/client/util/SharingManager.tsx | 12 +-
src/client/util/SnappingManager.ts | 16 +-
src/client/views/AntimodeMenu.tsx | 8 +-
src/client/views/ComponentDecorations.tsx | 4 +-
src/client/views/DocComponent.tsx | 2 +
src/client/views/DocViewUtils.ts | 21 ++
src/client/views/DocumentButtonBar.tsx | 29 +--
src/client/views/DocumentDecorations.tsx | 117 ++++++-----
src/client/views/FieldsDropdown.tsx | 22 +--
src/client/views/FilterPanel.tsx | 8 +-
src/client/views/GestureOverlay.tsx | 6 +-
src/client/views/GlobalKeyHandler.ts | 78 +++++---
src/client/views/InkControlPtHandles.tsx | 6 +-
src/client/views/InkStrokeProperties.ts | 3 +-
src/client/views/InkTranscription.tsx | 1 -
src/client/views/InkingStroke.tsx | 2 +-
src/client/views/LightboxView.tsx | 36 ++--
src/client/views/Main.tsx | 12 +-
src/client/views/MainView.tsx | 85 ++++----
src/client/views/MarqueeAnnotator.tsx | 1 -
src/client/views/OverlayView.tsx | 5 +-
src/client/views/PropertiesButtons.tsx | 29 ++-
.../views/PropertiesDocBacklinksSelector.tsx | 8 +-
src/client/views/PropertiesDocContextSelector.tsx | 3 +-
src/client/views/PropertiesView.tsx | 50 +++--
src/client/views/ScriptBox.tsx | 8 +-
src/client/views/ScriptingRepl.tsx | 16 +-
src/client/views/SidebarAnnos.tsx | 8 +-
src/client/views/StyleProp.ts | 24 +++
src/client/views/StyleProvider.tsx | 105 ++++------
.../views/collections/CollectionCarousel3DView.tsx | 5 +-
.../views/collections/CollectionCarouselView.tsx | 2 +-
.../views/collections/CollectionDockingView.tsx | 18 +-
src/client/views/collections/CollectionMenu.tsx | 32 ++-
.../views/collections/CollectionNoteTakingView.tsx | 2 +-
.../views/collections/CollectionPileView.tsx | 4 +-
.../collections/CollectionStackedTimeline.tsx | 16 +-
.../views/collections/CollectionStackingView.tsx | 2 +-
src/client/views/collections/CollectionSubView.tsx | 11 +-
.../views/collections/CollectionTimeView.tsx | 3 +-
.../views/collections/CollectionTreeView.tsx | 17 +-
.../views/collections/CollectionTreeViewType.ts | 5 +
src/client/views/collections/TabDocView.tsx | 216 +++++++++++----------
src/client/views/collections/TreeView.tsx | 15 +-
.../CollectionFreeFormClusters.ts | 31 ++-
.../CollectionFreeFormInfoUI.tsx | 10 +-
.../CollectionFreeFormPannableContents.tsx | 9 +-
.../collectionFreeForm/CollectionFreeFormView.tsx | 88 ++++-----
.../collections/collectionFreeForm/MarqueeView.tsx | 15 +-
.../collectionLinear/CollectionLinearView.tsx | 10 +-
.../collectionMulticolumn/MulticolumnResizer.tsx | 2 +-
.../collectionMulticolumn/MultirowResizer.tsx | 2 +-
.../collectionSchema/CollectionSchemaView.tsx | 28 +--
.../collectionSchema/SchemaTableCell.tsx | 8 +-
src/client/views/global/globalScripts.ts | 58 +++---
src/client/views/linking/LinkMenuGroup.tsx | 4 +-
src/client/views/linking/LinkMenuItem.tsx | 31 ++-
.../views/newlightbox/ButtonMenu/ButtonMenu.tsx | 3 +-
src/client/views/newlightbox/NewLightboxView.tsx | 27 ++-
.../components/Recommendation/Recommendation.tsx | 12 +-
src/client/views/nodes/AudioBox.tsx | 25 +--
.../views/nodes/CollectionFreeFormDocumentView.tsx | 41 ++--
src/client/views/nodes/ComparisonBox.tsx | 2 +-
src/client/views/nodes/DataVizBox/DataVizBox.tsx | 3 +-
.../nodes/DataVizBox/components/LineChart.tsx | 6 +-
.../views/nodes/DataVizBox/components/PieChart.tsx | 2 +-
.../views/nodes/DataVizBox/components/TableBox.tsx | 9 +-
src/client/views/nodes/DocumentContentsView.tsx | 13 +-
src/client/views/nodes/DocumentIcon.tsx | 11 +-
src/client/views/nodes/DocumentLinksButton.tsx | 13 --
src/client/views/nodes/DocumentView.tsx | 203 +++++++++----------
src/client/views/nodes/FontIconBox/FontIconBox.tsx | 38 ++--
src/client/views/nodes/FunctionPlotBox.tsx | 7 +-
src/client/views/nodes/ImageBox.tsx | 6 +-
src/client/views/nodes/KeyValueBox.tsx | 4 +-
src/client/views/nodes/LabelBox.tsx | 2 +-
src/client/views/nodes/LinkAnchorBox.scss | 34 ----
src/client/views/nodes/LinkAnchorBox.tsx | 118 -----------
src/client/views/nodes/LinkBox.tsx | 5 +-
src/client/views/nodes/LinkDescriptionPopup.tsx | 3 +-
src/client/views/nodes/LinkDocPreview.tsx | 26 ++-
src/client/views/nodes/LoadingBox.tsx | 21 +-
.../views/nodes/MapBox/DirectionsAnchorMenu.tsx | 4 +-
src/client/views/nodes/MapBox/MapAnchorMenu.tsx | 4 +-
src/client/views/nodes/MapBox/MapBox.tsx | 6 +-
src/client/views/nodes/MapBox/MapBox2.tsx | 6 +-
.../views/nodes/MapboxMapBox/MapboxContainer.tsx | 6 +-
src/client/views/nodes/PDFBox.tsx | 6 +-
.../views/nodes/RecordingBox/RecordingBox.tsx | 16 +-
src/client/views/nodes/ScreenshotBox.tsx | 11 +-
src/client/views/nodes/VideoBox.tsx | 28 ++-
src/client/views/nodes/WebBox.tsx | 5 +-
.../views/nodes/formattedText/DashFieldView.tsx | 5 +-
.../views/nodes/formattedText/FormattedTextBox.tsx | 45 ++---
.../formattedText/ProsemirrorExampleTransfer.ts | 4 +-
.../views/nodes/formattedText/RichTextMenu.tsx | 17 +-
.../views/nodes/formattedText/SummaryView.tsx | 5 +-
.../views/nodes/generativeFill/GenerativeFill.tsx | 8 +-
src/client/views/nodes/trails/PresBox.tsx | 58 +++---
src/client/views/nodes/trails/PresElementBox.tsx | 11 +-
src/client/views/pdf/AnchorMenu.tsx | 6 +-
src/client/views/pdf/Annotation.tsx | 6 +-
src/client/views/pdf/PDFViewer.tsx | 6 +-
src/client/views/search/SearchBox.tsx | 31 ++-
src/client/views/selectedDoc/SelectedDocView.tsx | 14 +-
src/client/views/topbar/TopBar.tsx | 8 +-
src/fields/Doc.ts | 19 +-
src/fields/ScriptField.ts | 1 -
src/fields/documentSchemas.ts | 1 -
src/mobile/MobileInterface.tsx | 9 +-
src/server/SharedMediaTypes.ts | 5 +
130 files changed, 1254 insertions(+), 1461 deletions(-)
create mode 100644 src/client/views/DocViewUtils.ts
create mode 100644 src/client/views/StyleProp.ts
create mode 100644 src/client/views/collections/CollectionTreeViewType.ts
delete mode 100644 src/client/views/nodes/LinkAnchorBox.scss
delete mode 100644 src/client/views/nodes/LinkAnchorBox.tsx
(limited to 'src/client/views/PropertiesDocContextSelector.tsx')
diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts
index 0a47e0359..0c9fe0315 100644
--- a/src/client/documents/DocUtils.ts
+++ b/src/client/documents/DocUtils.ts
@@ -9,7 +9,7 @@ import { ClientUtils } from '../../ClientUtils';
import * as JSZipUtils from '../../JSZipUtils';
import { decycle } from '../../decycler/decycler';
import { DateField } from '../../fields/DateField';
-import { Doc, DocListCast, Field, FieldType, LinkedTo, Opt, SetActiveAudioLinker, StrListCast } from '../../fields/Doc';
+import { Doc, DocListCast, Field, FieldResult, FieldType, LinkedTo, Opt, StrListCast } from '../../fields/Doc';
import { DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { InkDataFieldName, InkField } from '../../fields/InkField';
@@ -29,9 +29,7 @@ import { SerializationHelper } from '../util/SerializationHelper';
import { UndoManager, undoable } from '../util/UndoManager';
import { ContextMenu } from '../views/ContextMenu';
import { ContextMenuProps } from '../views/ContextMenuItem';
-import { FieldViewProps } from '../views/nodes/FieldView';
import { LinkDescriptionPopup } from '../views/nodes/LinkDescriptionPopup';
-import { LoadingBox } from '../views/nodes/LoadingBox';
import { OpenWhere } from '../views/nodes/OpenWhere';
import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
import { DocumentType } from './DocumentTypes';
@@ -50,7 +48,7 @@ export namespace DocUtils {
}
if (key === LinkedTo) {
// links are not a field value, so handled here. value is an expression of form ([field=]idToDoc("..."))
- const allLinks = LinkManager.Instance.getAllRelatedLinks(doc);
+ const allLinks = Doc.Links(doc);
const matchLink = (val: string, anchor: Doc) => {
const linkedToExp = (val ?? '').split('=');
if (linkedToExp.length === 1) return Field.toScriptString(anchor) === val;
@@ -131,7 +129,7 @@ export namespace DocUtils {
if (!unsets.length && !exists.length && !xs.length && !checks.length && !matches.length) return true;
const failsNotEqualFacets = !xs.length ? false : xs.some(value => matchFieldValue(d, facetKey, value));
const satisfiesCheckFacets = !checks.length ? true : checks.some(value => matchFieldValue(d, facetKey, value));
- const satisfiesExistsFacets = !exists.length ? true : facetKey !== LinkedTo ? d[facetKey] !== undefined : LinkManager.Instance.getAllRelatedLinks(d).length;
+ const satisfiesExistsFacets = !exists.length ? true : facetKey !== LinkedTo ? d[facetKey] !== undefined : Doc.Links(d).length;
const satisfiesUnsetsFacets = !unsets.length ? true : d[facetKey] === undefined;
const satisfiesMatchFacets = !matches.length
? true
@@ -170,19 +168,7 @@ export namespace DocUtils {
return rangeFilteredDocs;
}
- export const ActiveRecordings: { props: FieldViewProps; getAnchor: (addAsAnnotation: boolean) => Doc }[] = [];
-
- export function MakeLinkToActiveAudio(getSourceDoc: () => Doc | undefined, broadcastEvent = true) {
- broadcastEvent && runInAction(() => { Doc.RecordingEvent += 1; }); // prettier-ignore
- return DocUtils.ActiveRecordings.map(audio => {
- const sourceDoc = getSourceDoc();
- return sourceDoc && DocUtils.MakeLink(sourceDoc, audio.getAnchor(true) || audio.props.Document, { link_displayLine: false, link_relationship: 'recording annotation:linked recording', link_description: 'recording timeline' });
- });
- }
-
- SetActiveAudioLinker(MakeLinkToActiveAudio);
-
- export function MakeLink(source: Doc, target: Doc, linkSettings: { link_relationship?: string; link_description?: string; link_displayLine?: boolean }, id?: string, showPopup?: number[]) {
+ export function MakeLink(source: Doc, target: Doc, linkSettings: { link_relationship?: string; link_description?: string }, id?: string, showPopup?: number[]) {
if (!linkSettings.link_relationship) linkSettings.link_relationship = target.type === DocumentType.RTF ? 'Commentary:Comments On' : 'link';
if (target.doc === Doc.UserDoc()) return undefined;
@@ -232,7 +218,6 @@ export namespace DocUtils {
title: ComputedField.MakeFunction('generateLinkTitle(this)') as any,
link_anchor_1_useSmallAnchor: source.useSmallAnchor ? true : undefined,
link_anchor_2_useSmallAnchor: target.useSmallAnchor ? true : undefined,
- link_displayLine: linkSettings.link_displayLine,
link_relationship: linkSettings.link_relationship,
link_description: linkSettings.link_description,
x: ComputedField.MakeFunction(`((this.${a}?.x||0)+(this.${b}?.x||0))/2`) as any,
@@ -256,7 +241,6 @@ export namespace DocUtils {
const script = scripts[key];
if (ScriptCast(doc[key])?.script.originalScript !== scripts[key] && script) {
(key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = ScriptField.MakeScript(script, {
- self: Doc.name,
this: Doc.name,
dragData: Doc.DocDragDataName,
value: 'any',
@@ -579,7 +563,7 @@ export namespace DocUtils {
export function LeavePushpin(doc: Doc, annotationField: string) {
if (doc.followLinkToggle) return undefined;
const context = Cast(doc.embedContainer, Doc, null) ?? Cast(doc.annotationOn, Doc, null);
- const hasContextAnchor = LinkManager.Links(doc).some(l => (l.link_anchor_2 === doc && Cast(l.link_anchor_1, Doc, null)?.annotationOn === context) || (l.link_anchor_1 === doc && Cast(l.link_anchor_2, Doc, null)?.annotationOn === context));
+ const hasContextAnchor = Doc.Links(doc).some(l => (l.link_anchor_2 === doc && Cast(l.link_anchor_1, Doc, null)?.annotationOn === context) || (l.link_anchor_1 === doc && Cast(l.link_anchor_2, Doc, null)?.annotationOn === context));
if (context && !hasContextAnchor && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) {
const pushpin = Docs.Create.FontIconDocument({
title: '',
@@ -673,7 +657,7 @@ export namespace DocUtils {
proto.data_duration = result.duration;
}
if (overwriteDoc) {
- LoadingBox.removeCurrentlyLoading(overwriteDoc);
+ Doc.removeCurrentlyLoading(overwriteDoc);
}
generatedDocuments.push(doc);
}
@@ -717,7 +701,7 @@ export namespace DocUtils {
if (overwriteDoc) {
overwriteDoc.isLoading = false;
overwriteDoc.loadingError = (result as any).message;
- LoadingBox.removeCurrentlyLoading(overwriteDoc);
+ Doc.removeCurrentlyLoading(overwriteDoc);
}
} else newFilename && processFileupload(generatedDocuments, newFilename, mimetype ?? '', result, options, overwriteDoc);
});
@@ -755,7 +739,7 @@ export namespace DocUtils {
if ((result as any).message) {
if (overwriteDoc) {
overwriteDoc.loadingError = (result as any).message;
- LoadingBox.removeCurrentlyLoading(overwriteDoc);
+ Doc.removeCurrentlyLoading(overwriteDoc);
}
} else newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options, overwriteDoc);
});
@@ -868,6 +852,10 @@ export function FollowLinkScript() {
return ScriptField.MakeScript('return followLink(this,altKey)', { altKey: 'boolean' });
}
+export function IsFollowLinkScript(field: FieldResult) {
+ return ScriptCast(field)?.script.originalScript.includes('return followLink(');
+}
+
ScriptingGlobals.add('Docs', Docs);
// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function copyDragFactory(dragFactory: Doc, asDelegate?: boolean) {
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index a3fea1ce4..1c18c0d84 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -19,7 +19,6 @@ import { SharingPermissions } from '../../fields/util';
import { PointData } from '../../pen-gestures/GestureTypes';
import { DocServer } from '../DocServer';
import { dropActionType } from '../util/DropActionTypes';
-import { LinkManager } from '../util/LinkManager';
import { CollectionViewType, DocumentType } from './DocumentTypes';
class EmptyBox {
@@ -394,7 +393,6 @@ export class DocumentOptions {
link?: string;
link_description?: string; // added for links
link_relationship?: string; // type of relatinoship a link represents
- link_displayLine?: BOOLt = new BoolInfo('whether a link line should be dipslayed between the two link anchors');
link_displayArrow?: BOOLt = new BoolInfo("whether to display link's directional arrowhead");
link_anchor_1?: DOCt = new DocInfo('start anchor of a link');
link_anchor_2?: DOCt = new DocInfo('end anchor of a link');
@@ -810,7 +808,7 @@ export namespace Docs {
'link'
);
- LinkManager.Instance.addLink(linkDoc);
+ Doc.AddLink(linkDoc);
return linkDoc;
}
diff --git a/src/client/util/BranchingTrailManager.tsx b/src/client/util/BranchingTrailManager.tsx
index 28c00644f..119d103c5 100644
--- a/src/client/util/BranchingTrailManager.tsx
+++ b/src/client/util/BranchingTrailManager.tsx
@@ -6,8 +6,8 @@ import * as React from 'react';
import { Doc } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { OverlayView } from '../views/OverlayView';
+import { DocumentView } from '../views/nodes/DocumentView';
import { PresBox } from '../views/nodes/trails';
-import { DocumentManager } from './DocumentManager';
@observer
export class BranchingTrailManager extends React.Component {
@@ -46,7 +46,6 @@ export class BranchingTrailManager extends React.Component {
// hi.overlayY = 100;
// Doc.AddToMyOverlay(hi);
- console.log(DocumentManager._overlayViews);
};
@action setSlideHistoryStack = action((newArr: String[]) => {
@@ -103,7 +102,7 @@ export class BranchingTrailManager extends React.Component {
this.setSlideHistoryStack(newStack);
removed.forEach(info => this.containsSet.delete(info.toString()));
- DocumentManager.Instance.showDocument(targetDoc, { willZoomCentered: true });
+ DocumentView.showDocument(targetDoc, { willZoomCentered: true });
if (this.slideHistoryStack.length === 0) {
Doc.UserDoc().isBranchingMode = false;
}
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 8e3936d34..77cf80151 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -13,15 +13,12 @@ import { Doc, DocListCast } from '../../fields/Doc';
import { DocData } from '../../fields/DocSymbols';
import { StrCast } from '../../fields/Types';
import { Docs } from '../documents/Documents';
-import { DictationOverlay } from '../views/DictationOverlay';
import { MainViewModal } from '../views/MainViewModal';
import { ObservableReactComponent } from '../views/ObservableReactComponent';
import { DocumentView } from '../views/nodes/DocumentView';
import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
import './CalendarManager.scss';
-import { DocumentManager } from './DocumentManager';
-import { SelectionManager } from './SelectionManager';
-import { SettingsManager } from './SettingsManager';
+import { SnappingManager } from './SnappingManager';
// import 'react-date-range/dist/styles.css';
// import 'react-date-range/dist/theme/default.css';
@@ -85,11 +82,9 @@ export class CalendarManager extends ObservableReactComponent<{}> {
};
public open = (target?: DocumentView, targetDoc?: Doc) => {
- console.log('hi');
runInAction(() => {
this.targetDoc = targetDoc || target?.Document;
this.targetDocView = target;
- DictationOverlay.Instance.hasActiveModal = true;
this.isOpen = this.targetDoc !== undefined;
});
};
@@ -99,7 +94,6 @@ export class CalendarManager extends ObservableReactComponent<{}> {
TaskCompletionBox.taskCompleted = false;
setTimeout(
action(() => {
- DictationOverlay.Instance.hasActiveModal = false;
this.targetDoc = undefined;
}),
500
@@ -137,7 +131,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
// TODO: Make undoable
private addToCalendar = () => {
- const docs = SelectionManager.Views.length < 2 ? [this.targetDoc] : SelectionManager.Views.map(docView => docView.Document);
+ const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document);
const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; // doc to add to calendar
console.log(targetDoc);
@@ -190,14 +184,14 @@ export class CalendarManager extends ObservableReactComponent<{}> {
private focusOn = (contents: string) => {
const title = this.targetDoc ? StrCast(this.targetDoc.title) : '';
- const docs = SelectionManager.Views.length > 1 ? SelectionManager.Views.map(docView => docView.Document) : [this.targetDoc];
+ const docs = DocumentView.Selected().length > 1 ? DocumentView.Selected().map(docView => docView.Document) : [this.targetDoc];
return (
{
if (this.targetDoc && this.targetDocView && docs.length === 1) {
- DocumentManager.Instance.showDocument(this.targetDoc, { willZoomCentered: true });
+ DocumentView.showDocument(this.targetDoc, { willZoomCentered: true });
}
}}
onPointerEnter={action(() => {
@@ -251,17 +245,17 @@ export class CalendarManager extends ObservableReactComponent<{}> {
@computed
get calendarInterface() {
- const docs = SelectionManager.Views.length < 2 ? [this.targetDoc] : SelectionManager.Views.map(docView => docView.Document);
+ const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document);
const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData];
return (
-
+
{this.focusOn(docs.length < 2 ? StrCast(targetDoc?.title, 'this document') : '-multiple-')}
diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx
index a03c80f2a..4fd934774 100644
--- a/src/client/util/CaptureManager.tsx
+++ b/src/client/util/CaptureManager.tsx
@@ -10,8 +10,7 @@ import { DocCast, StrCast } from '../../fields/Types';
import { LightboxView } from '../views/LightboxView';
import { MainViewModal } from '../views/MainViewModal';
import './CaptureManager.scss';
-import { LinkManager } from './LinkManager';
-import { SelectionManager } from './SelectionManager';
+import { DocumentView } from '../views/nodes/DocumentView';
@observer
export class CaptureManager extends React.Component<{}> {
@@ -56,7 +55,7 @@ export class CaptureManager extends React.Component<{}> {
const doc = this._document;
const order: JSX.Element[] = [];
if (doc) {
- LinkManager.Links(doc).forEach((l, i) =>
+ Doc.Links(doc).forEach((l, i) =>
order.push(
{i}
@@ -88,8 +87,8 @@ export class CaptureManager extends React.Component<{}> {
{
- const selected = SelectionManager.Views.slice();
- SelectionManager.DeselectAll();
+ const selected = DocumentView.Selected();
+ DocumentView.DeselectAll();
selected.map(dv => dv.props.removeDocument?.(dv.Document));
this.close();
}}>
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 15c8fec5a..ffc1304bf 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1,4 +1,4 @@
-import { observable, reaction, runInAction } from "mobx";
+import { reaction, runInAction } from "mobx";
import * as rp from 'request-promise';
import { ClientUtils, OmitKeys } from "../../ClientUtils";
import { Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc";
@@ -19,7 +19,8 @@ import { CollectionViewType, DocumentType } from "../documents/DocumentTypes";
import { Docs, DocumentOptions, FInfo, FInfoFieldType } from "../documents/Documents";
import { DashboardView } from "../views/DashboardView";
import { OverlayView } from "../views/OverlayView";
-import { CollectionTreeView, TreeViewType } from "../views/collections/CollectionTreeView";
+import { CollectionTreeView } from "../views/collections/CollectionTreeView";
+import { TreeViewType } from "../views/collections/CollectionTreeViewType";
import { Colors } from "../views/global/globalEnums";
import { mediaState } from "../views/nodes/AudioBox";
import { ButtonType, FontIconBox } from "../views/nodes/FontIconBox/FontIconBox";
@@ -30,8 +31,9 @@ import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox";
import { DragManager } from "./DragManager";
import { dropActionType } from "./DropActionTypes";
import { MakeTemplate } from "./DropConverter";
-import { LinkManager, UPDATE_SERVER_CACHE } from "./LinkManager";
+import { UPDATE_SERVER_CACHE } from "./LinkManager";
import { ScriptingGlobals } from "./ScriptingGlobals";
+import { SelectionManager } from "./SelectionManager";
import { ColorScheme } from "./SettingsManager";
import { SnappingManager } from "./SnappingManager";
import { UndoManager } from "./UndoManager";
@@ -937,14 +939,13 @@ pie title Minerals in my tap water
DocUtils.AssignDocField(doc, "globalScriptDatabase", () => Docs.Prototypes.MainScriptDocument(), {});
DocUtils.AssignDocField(doc, "myHeaderBar", (opts) => Docs.Create.MulticolumnDocument([], opts), { title: "My Header Bar", isSystem: true, _chromeHidden:true, layout_maxShown: 10, childLayoutFitWidth:false, childDocumentsActive:false, dropAction: dropActionType.move}); // drop down panel at top of dashboard for stashing documents
- Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MyDashboards)
- Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MySharedDocs)
- Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MyRecentlyClosed)
-
- Doc.GetProto(DocCast(Doc.UserDoc().emptyWebpage)).data = new WebField("https://www.wikipedia.org")
+ SelectionManager.DeselectAll(); // this forces SelectionManager implementation to copy over to DocumentView's API. This also triggers the LinkManager to be created
+
+ Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MyDashboards);
+ Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MySharedDocs);
+ Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MyRecentlyClosed);
- // eslint-disable-next-line no-new
- new LinkManager();
+ Doc.GetProto(DocCast(Doc.UserDoc().emptyWebpage)).data = new WebField("https://www.wikipedia.org");
DocServer.CacheNeedsUpdate() && setTimeout(UPDATE_SERVER_CACHE, 2500);
setInterval(UPDATE_SERVER_CACHE, 120000);
@@ -969,12 +970,11 @@ pie title Minerals in my tap water
});
}
- @observable public static ServerVersion: string = ';'
public static async loadCurrentUser() {
return rp.get(ClientUtils.prepend("/getCurrentUser")).then(async response => {
if (response) {
const result: { version: string, userDocumentId: string, sharingDocumentId: string, linkDatabaseId: string, email: string, cacheDocumentIds: string, resolvedPorts: string } = JSON.parse(response);
- runInAction(() => { CurrentUserUtils.ServerVersion = result.version; });
+ runInAction(() => { SnappingManager.SetServerVersion(result.version); });
ClientUtils.SetCurrentUserEmail(result.email);
resolvedPorts = result.resolvedPorts as any;
DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts?.socket, result.email);
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index 97ee628e2..bc9fe813f 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -10,12 +10,13 @@ import { RichTextField } from '../../fields/RichTextField';
import { listSpec } from '../../fields/Schema';
import { Cast, CastCtor } from '../../fields/Types';
import { AudioField, ImageField } from '../../fields/URLField';
+import { AudioAnnoState } from '../../server/SharedMediaTypes';
+import { Networking } from '../Network';
import { DocumentType } from '../documents/DocumentTypes';
import { Docs } from '../documents/Documents';
import { DictationOverlay } from '../views/DictationOverlay';
import { DocumentView } from '../views/nodes/DocumentView';
import { OpenWhere } from '../views/nodes/OpenWhere';
-import { SelectionManager } from './SelectionManager';
import { UndoManager } from './UndoManager';
/**
@@ -244,7 +245,7 @@ export namespace DictationManager {
export const execute = async (phrase: string) =>
UndoManager.RunInBatch(async () => {
console.log('PHRASE: ' + phrase);
- const targets = SelectionManager.Views;
+ const targets = DocumentView.Selected();
if (!targets || !targets.length) {
return undefined;
}
@@ -395,4 +396,43 @@ export namespace DictationManager {
},
];
}
+ export function recordAudioAnnotation(dataDoc: Doc, field: string, onRecording?: (stop: () => void) => void, onEnd?: () => void) {
+ let gumStream: any;
+ let recorder: any;
+ navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
+ let audioTextAnnos = Cast(dataDoc[field + '_audioAnnotations_text'], listSpec('string'), null);
+ if (audioTextAnnos) audioTextAnnos.push('');
+ else audioTextAnnos = dataDoc[field + '_audioAnnotations_text'] = new List(['']);
+ DictationManager.Controls.listen({
+ interimHandler: value => { audioTextAnnos[audioTextAnnos.length - 1] = value; }, // prettier-ignore
+ continuous: { indefinite: false },
+ }).then(results => {
+ if (results && [DictationManager.Controls.Infringed].includes(results)) {
+ DictationManager.Controls.stop();
+ }
+ onEnd?.();
+ });
+
+ gumStream = stream;
+ recorder = new MediaRecorder(stream);
+ recorder.ondataavailable = async (e: any) => {
+ const [{ result }] = await Networking.UploadFilesToServer({ file: e.data });
+ if (!(result instanceof Error)) {
+ const audioField = new AudioField(result.accessPaths.agnostic.client);
+ const audioAnnos = Cast(dataDoc[field + '_audioAnnotations'], listSpec(AudioField), null);
+ if (audioAnnos) audioAnnos.push(audioField);
+ else dataDoc[field + '_audioAnnotations'] = new List([audioField]);
+ }
+ };
+ recorder.start();
+ const stopFunc = () => {
+ recorder.stop();
+ DictationManager.Controls.stop(/* false */);
+ dataDoc.audioAnnoState = AudioAnnoState.stopped;
+ gumStream.getAudioTracks()[0].stop();
+ };
+ if (onRecording) onRecording(stopFunc);
+ else setTimeout(stopFunc, 5000);
+ });
+ }
}
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 8f0c2b0bf..5bcac7330 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -1,23 +1,17 @@
import { Howl } from 'howler';
import { action, computed, makeObservable, observable, ObservableSet, observe } from 'mobx';
import { Doc, Opt } from '../../fields/Doc';
-import { AclAdmin, AclEdit, Animation, DocData } from '../../fields/DocSymbols';
+import { Animation, DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { listSpec } from '../../fields/Schema';
import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { AudioField } from '../../fields/URLField';
-import { GetEffectiveAcl } from '../../fields/util';
import { CollectionViewType } from '../documents/DocumentTypes';
-import { TabDocView } from '../views/collections/TabDocView';
import { LightboxView } from '../views/LightboxView';
import { DocumentView, DocumentViewInternal } from '../views/nodes/DocumentView';
import { FocusViewOptions } from '../views/nodes/FocusViewOptions';
-import { KeyValueBox } from '../views/nodes/KeyValueBox';
-import { LinkAnchorBox } from '../views/nodes/LinkAnchorBox';
import { OpenWhere } from '../views/nodes/OpenWhere';
import { PresBox } from '../views/nodes/trails';
-import { ScriptingGlobals } from './ScriptingGlobals';
-import { SelectionManager } from './SelectionManager';
type childIterator = { viewSpec: Opt; childDocView: Opt; focused: boolean; contextPath: Doc[] };
export class DocumentManager {
@@ -29,10 +23,9 @@ export class DocumentManager {
}
// global holds all of the nodes (regardless of which collection they're in)
- @observable _documentViews = new Set();
- @observable.shallow public CurrentlyLoading: Doc[] = [];
+ @observable private _documentViews = new Set();
@computed public get DocumentViews() {
- return Array.from(this._documentViews).filter(view => !(view.ComponentView instanceof KeyValueBox) && (!LightboxView.LightboxDoc || LightboxView.Contains(view)));
+ return Array.from(this._documentViews).filter(view => (!view.ComponentView?.dontRegisterView?.() && !LightboxView.LightboxDoc) || LightboxView.Contains(view));
}
public AddDocumentView(dv: DocumentView) {
this._documentViews.add(dv);
@@ -44,7 +37,19 @@ export class DocumentManager {
// private constructor so no other class can create a nodemanager
private constructor() {
makeObservable(this);
- observe(this.CurrentlyLoading, change => {
+
+ DocumentView.allViews = () => this.DocumentViews;
+ DocumentView.addView = this.AddView;
+ DocumentView.removeView = this.RemoveView;
+ DocumentView.showDocument = this.showDocument;
+ DocumentView.showDocumentView = this.showDocumentView;
+ DocumentView.linkCommonAncestor = DocumentManager.LinkCommonAncestor;
+ DocumentView.addViewRenderedCb = this.AddViewRenderedCb;
+ DocumentView.getFirstDocumentView = this.getFirstDocumentView;
+ DocumentView.getDocumentView = this.getDocumentView;
+ DocumentView.getContextPath = DocumentManager.GetContextPath;
+ DocumentView.getLightboxDocumentView = this.getLightboxDocumentView;
+ observe(Doc.CurrentlyLoading, change => {
// watch CurrentlyLoading-- when something is loaded, it's removed from the list and we have to update its icon if it were iconified since LoadingBox icons are different than the media they become
switch (change.type as any) {
case 'update':
@@ -92,17 +97,12 @@ export class DocumentManager {
@action
public AddView = (view: DocumentView) => {
- if (!view._props.LayoutTemplateString?.includes(KeyValueBox.name) &&
- !view._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
- this.AddDocumentView(view);
- this.callAddViewFuncs(view);
- } // prettier-ignore
+ this.AddDocumentView(view);
+ this.callAddViewFuncs(view);
};
public RemoveView = action((view: DocumentView) => {
- if (!view._props.LayoutTemplateString?.includes(KeyValueBox.name) && !view._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
- this.DeleteDocumentView(view);
- }
- SelectionManager.DeselectView(view);
+ this.DeleteDocumentView(view);
+ DocumentView.DeselectView(view);
});
// gets all views
@@ -203,6 +203,11 @@ export class DocumentManager {
}
static _overlayViews = new ObservableSet();
+ /**
+ * Find the nearest common ancestor collection that contains a link's source and target
+ * @param linkDoc
+ * @returns common ancestor DocumentView
+ */
public static LinkCommonAncestor(linkDoc: Doc) {
const getAnchor = (which: number) => {
const anch = DocCast(linkDoc['link_anchor_' + which]);
@@ -245,11 +250,8 @@ export class DocumentManager {
Doc.RemoveDocFromList(Doc.MyRecentlyClosed, undefined, targetDoc);
const docContextPath = DocumentManager.GetContextPath(targetDoc, true);
if (docContextPath.some(doc => doc.hidden)) options.toggleTarget = false;
- const tabView = Array.from(TabDocView._allTabs).find(view => view._document === docContextPath[0]);
- if (!tabView?._activated && tabView?._document) {
- options.toggleTarget = false;
- TabDocView.Activate(tabView?._document);
- }
+ if (DocumentView.activateTabView(docContextPath[0])) options.toggleTarget = false;
+
const rootContextView =
docContextPath.length &&
(await new Promise(res => {
@@ -260,7 +262,7 @@ export class DocumentManager {
return;
}
options.didMove = true;
- (!LightboxView.LightboxDoc && docContextPath.some(doc => TabDocView.Activate(doc))) || DocumentViewInternal.addDocTabFunc(docContextPath[0], options.openLocation ?? OpenWhere.addRight);
+ (!LightboxView.LightboxDoc && docContextPath.some(doc => DocumentView.activateTabView(doc))) || DocumentViewInternal.addDocTabFunc(docContextPath[0], options.openLocation ?? OpenWhere.addRight);
this.AddViewRenderedCb(docContextPath[0], dv => res(dv));
}));
if (options.openLocation === OpenWhere.lightbox) {
@@ -355,33 +357,4 @@ export class DocumentManager {
}
}
}
-// eslint-disable-next-line default-param-last
-export function DocFocusOrOpen(docIn: Doc, optionsIn: FocusViewOptions = { willZoomCentered: true, zoomScale: 0, openLocation: OpenWhere.toggleRight }, containingDoc?: Doc) {
- let doc = docIn;
- const options = optionsIn;
- const func = () => {
- const cv = DocumentManager.Instance.getDocumentView(containingDoc);
- const dv = DocumentManager.Instance.getDocumentView(doc, cv);
- if (dv && (!containingDoc || dv.containerViewPath?.().lastElement()?.Document === containingDoc)) {
- DocumentManager.Instance.showDocumentView(dv, options).then(() => dv && Doc.linkFollowHighlight(dv.Document));
- } else {
- const container = DocCast(containingDoc ?? doc.embedContainer ?? Doc.BestEmbedding(doc));
- const showDoc = !Doc.IsSystem(container) && !cv ? container : doc;
- options.toggleTarget = undefined;
- DocumentManager.Instance.showDocument(showDoc, options, () => DocumentManager.Instance.showDocument(doc, { ...options, openLocation: undefined })).then(() => {
- const cvFound = DocumentManager.Instance.getDocumentView(containingDoc);
- const dvFound = DocumentManager.Instance.getDocumentView(doc, cvFound);
- dvFound && Doc.linkFollowHighlight(dvFound.Document);
- });
- }
- };
- if (Doc.IsDataProto(doc) && Doc.GetEmbeddings(doc).some(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))) {
- doc = Doc.GetEmbeddings(doc).find(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))!;
- }
- if (doc.hidden) {
- doc.hidden = false;
- options.toggleTarget = false;
- setTimeout(func);
- } else func();
-}
-ScriptingGlobals.add(DocFocusOrOpen);
+setTimeout(() => DocumentManager.Instance);
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 34f54be2e..fda505420 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -27,8 +27,6 @@ import { ScriptCast } from '../../fields/Types';
import { Docs } from '../documents/Documents';
import { DocumentView } from '../views/nodes/DocumentView';
import { dropActionType } from './DropActionTypes';
-import { ScriptingGlobals } from './ScriptingGlobals';
-import { SelectionManager } from './SelectionManager';
import { SnappingManager } from './SnappingManager';
import { UndoManager } from './UndoManager';
@@ -648,14 +646,3 @@ export namespace DragManager {
document.addEventListener('pointerup', upHandler, true);
}
}
-
-// eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function toggleRaiseOnDrag(readOnly?: boolean) {
- if (readOnly) {
- return SelectionManager.Views.some(dv => dv.Document.keepZWhenDragged);
- }
- SelectionManager.Views.forEach(dv => {
- dv.Document.keepZWhenDragged = !dv.Document.keepZWhenDragged;
- });
- return undefined;
-});
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index e1a503ac9..5701a22c0 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -77,7 +77,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
*/
@action
open = () => {
- // SelectionManager.DeselectAll();
+ // DocumentView.DeselectAll();
this.isOpen = true;
this.populateUsers();
};
diff --git a/src/client/util/HypothesisUtils.ts b/src/client/util/HypothesisUtils.ts
index dd18b2533..5a6522dc8 100644
--- a/src/client/util/HypothesisUtils.ts
+++ b/src/client/util/HypothesisUtils.ts
@@ -6,8 +6,6 @@ import { WebField } from '../../fields/URLField';
import { Docs } from '../documents/Documents';
import { DocumentLinksButton } from '../views/nodes/DocumentLinksButton';
import { DocumentView } from '../views/nodes/DocumentView';
-import { DocumentManager } from './DocumentManager';
-import { SelectionManager } from './SelectionManager';
export namespace Hypothesis {
/**
@@ -25,7 +23,7 @@ export namespace Hypothesis {
* Search for a WebDocument whose url field matches the given uri, return undefined if not found
*/
export const findWebDoc = async (uri: string) => {
- const currentDoc = SelectionManager.Docs.lastElement();
+ const currentDoc = DocumentView.Selected().lastElement()?.Document;
if (currentDoc && Cast(currentDoc.data, WebField)?.url.href === uri) return currentDoc; // always check first whether the currently selected doc is the annotation's source, only use Search otherwise
const results: Doc[] = [];
@@ -39,7 +37,7 @@ export namespace Hypothesis {
// })
// );
- const onScreenResults = results.filter(doc => DocumentManager.Instance.getFirstDocumentView(doc));
+ const onScreenResults = results.filter(doc => DocumentView.getFirstDocumentView(doc));
return onScreenResults.length ? onScreenResults[0] : results.length ? results[0] : undefined; // prioritize results that are currently on the screen
};
@@ -65,7 +63,7 @@ export namespace Hypothesis {
DocumentLinksButton.AnnotationId = annotationId;
DocumentLinksButton.AnnotationUri = annotationUri;
});
- const endLinkView = DocumentManager.Instance.getFirstDocumentView(sourceDoc);
+ const endLinkView = DocumentView.getFirstDocumentView(sourceDoc);
const rect = document.body.getBoundingClientRect();
const x = rect.x + rect.width / 2;
const y = 250;
@@ -182,7 +180,7 @@ export namespace Hypothesis {
bubbles: true,
})
);
- const targetView: Opt = DocumentManager.Instance.getFirstDocumentView(target);
+ const targetView: Opt = DocumentView.getFirstDocumentView(target);
const position = targetView?.screenToViewTransform().inverse().transformPoint(0, 0);
targetView && position && simulateMouseClick(targetView.ContentDiv!, position[0], position[1], position[0], position[1], false);
}, 300);
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 398ba3c04..baa0786b7 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -17,7 +17,6 @@
// import { DocumentType } from '../../documents/DocumentTypes';
// import { Networking } from '../../Network';
// import { FieldView, FieldViewProps } from '../../views/nodes/FieldView';
-// import { DocumentManager } from '../DocumentManager';
// import './DirectoryImportBox.scss';
// import ImportMetadataEntry, { keyPlaceholder, valuePlaceholder } from './ImportMetadataEntry';
// import * as React from 'react';
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index a6f6122ab..9a0edcfec 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -1,14 +1,12 @@
import { action, runInAction } from 'mobx';
-import { Doc, DocListCast, FieldResult, FieldType, Opt } from '../../fields/Doc';
-import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../fields/Types';
+import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { DocumentType } from '../documents/DocumentTypes';
+import { DocumentView } from '../views/nodes/DocumentView';
import { FocusViewOptions } from '../views/nodes/FocusViewOptions';
import { OpenWhere } from '../views/nodes/OpenWhere';
import { PresBox } from '../views/nodes/trails';
-import { DocumentManager } from './DocumentManager';
-import { LinkManager } from './LinkManager';
import { ScriptingGlobals } from './ScriptingGlobals';
-import { SelectionManager } from './SelectionManager';
import { SnappingManager } from './SnappingManager';
import { UndoManager } from './UndoManager';
/*
@@ -24,6 +22,9 @@ import { UndoManager } from './UndoManager';
* - user defined kvps
*/
export class LinkFollower {
+ public static Init() {
+ DocumentView.FollowLink = LinkFollower.FollowLink;
+ }
// follows a link - if the target is on screen, it highlights/pans to it.
// if the target isn't onscreen, then it will open up the target in the lightbox, or in place
// depending on the followLinkLocation property of the source (or the link itself as a fallback);
@@ -42,9 +43,9 @@ export class LinkFollower {
};
public static traverseLink(link: Opt, sourceDoc: Doc, finished?: () => void, traverseBacklink?: boolean) {
- const getView = (doc: Doc) => DocumentManager.Instance.getFirstDocumentView(DocCast(doc.layout_unrendered ? doc.annotationOn : doc));
+ const getView = (doc: Doc) => DocumentView.getFirstDocumentView(DocCast(doc.layout_unrendered ? doc.annotationOn : doc));
const isAnchor = (source: Doc, anchor: Doc) => Doc.AreProtosEqual(anchor, source) || Doc.AreProtosEqual(anchor.annotationOn as Doc, source);
- const linkDocs = link ? [link] : LinkManager.Links(sourceDoc);
+ const linkDocs = link ? [link] : Doc.Links(sourceDoc);
const fwdLinks = linkDocs.filter(l => isAnchor(sourceDoc, l.link_anchor_1 as Doc)); // link docs where 'sourceDoc' is link_anchor_1
const backLinks = linkDocs.filter(l => isAnchor(sourceDoc, l.link_anchor_2 as Doc)); // link docs where 'sourceDoc' is link_anchor_2
const fwdLinkWithoutTargetView = fwdLinks.find(l => !getView(DocCast(l.link_anchor_2)));
@@ -68,7 +69,7 @@ export class LinkFollower {
? linkDoc.link_anchor_2
: linkDoc.link_anchor_1
) as Doc;
- const srcAnchor: Doc = LinkManager.getOppositeAnchor(linkDoc, target) ?? sourceDoc;
+ const srcAnchor: Doc = Doc.getOppositeAnchor(linkDoc, target) ?? sourceDoc;
if (target) {
const doFollow = (canToggle?: boolean) => {
const toggleTarget = canToggle && BoolCast(sourceDoc.followLinkToggle);
@@ -87,14 +88,14 @@ export class LinkFollower {
zoomTextSelections: BoolCast(srcAnchor.followLinkZoomText),
};
if (target.type === DocumentType.PRES) {
- const containerDocContext = DocumentManager.GetContextPath(sourceDoc, true); // gather all views that affect layout of sourceDoc so we can revert them after playing the rail
- SelectionManager.DeselectAll();
- if (!DocumentManager.Instance.AddViewRenderedCb(target, dv => containerDocContext.length && dv.ComponentView?.playTrail?.(containerDocContext))) {
+ const containerDocContext = DocumentView.getContextPath(sourceDoc, true); // gather all views that affect layout of sourceDoc so we can revert them after playing the rail
+ DocumentView.DeselectAll();
+ if (!DocumentView.addViewRenderedCb(target, dv => containerDocContext.length && dv.ComponentView?.playTrail?.(containerDocContext))) {
PresBox.OpenPresMinimized(target, [0, 0]);
}
finished?.();
} else {
- DocumentManager.Instance.showDocument(target, options, allFinished);
+ DocumentView.showDocument(target, options, allFinished);
}
};
let movedTarget = false;
@@ -133,10 +134,6 @@ export class LinkFollower {
// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function followLink(doc: Doc, altKey: boolean) {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
return LinkFollower.FollowLink(undefined, doc, altKey) ? undefined : { select: true };
});
-
-export function IsFollowLinkScript(field: FieldResult) {
- return ScriptCast(field)?.script.originalScript.includes('return followLink(');
-}
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index dbd13f978..56d5dce4e 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -30,8 +30,8 @@ export class LinkManager {
@observable.shallow userLinkDBs: Doc[] = [];
@observable public currentLink: Opt = undefined;
@observable public currentLinkAnchor: Opt = undefined;
- public static get Instance() {
- return LinkManager._instance;
+ public static get Instance(): LinkManager {
+ return Doc.UserDoc() ? LinkManager._instance ?? new LinkManager() : (undefined as any as LinkManager);
}
public static Links(doc: Doc | undefined) {
@@ -47,10 +47,13 @@ export class LinkManager {
this.userLinkDBs.push(linkDb);
};
public static AutoKeywords = 'keywords:Usages';
- constructor() {
+ private constructor() {
makeObservable(this);
LinkManager._instance = this;
Doc.AddLink = this.addLink;
+ Doc.DeleteLink = this.deleteLink;
+ Doc.Links = LinkManager.Links;
+ Doc.getOppositeAnchor = LinkManager.getOppositeAnchor;
this.createlink_relationshipLists();
// since this is an action, not a reaction, we get only one shot to add this link to the Anchor docs
// Thus make sure all promised values are resolved from link -> link.proto -> link.link_anchor_[1,2] -> link.link_anchor_[1,2].proto
diff --git a/src/client/util/PingManager.ts b/src/client/util/PingManager.ts
index e5e69c5ac..255e9cee0 100644
--- a/src/client/util/PingManager.ts
+++ b/src/client/util/PingManager.ts
@@ -1,6 +1,6 @@
import { action, makeObservable, observable, runInAction } from 'mobx';
import { Networking } from '../Network';
-import { CurrentUserUtils } from './CurrentUserUtils';
+import { SnappingManager } from './SnappingManager';
export class PingManager {
// create static instance and getter for global use
@@ -32,7 +32,7 @@ export class PingManager {
try {
const res = await Networking.PostToServer('/ping', { date: new Date() });
runInAction(() => {
- CurrentUserUtils.ServerVersion = res.message;
+ SnappingManager.SetServerVersion(res.message);
});
!this.IsBeating && this.setIsBeating(true);
} catch {
diff --git a/src/client/util/ReplayMovements.ts b/src/client/util/ReplayMovements.ts
index dcc6aabab..530fcf211 100644
--- a/src/client/util/ReplayMovements.ts
+++ b/src/client/util/ReplayMovements.ts
@@ -4,8 +4,8 @@ import { CollectionDockingView } from '../views/collections/CollectionDockingVie
import { CollectionFreeFormView } from '../views/collections/collectionFreeForm';
import { OpenWhereMod } from '../views/nodes/OpenWhere';
import { VideoBox } from '../views/nodes/VideoBox';
-import { DocumentManager } from './DocumentManager';
import { Movement, Presentation } from './TrackMovements';
+import { DocumentView } from '../views/nodes/DocumentView';
export class ReplayMovements {
private timers: NodeJS.Timeout[] | null;
@@ -106,7 +106,7 @@ export class ReplayMovements {
// returns undefined if the docView isn't open on the screen
getCollectionFFView = (doc: Doc) => {
- const isInView = DocumentManager.Instance.getDocumentView(doc);
+ const isInView = DocumentView.getDocumentView(doc);
return isInView?.ComponentView as CollectionFreeFormView;
};
@@ -118,7 +118,7 @@ export class ReplayMovements {
}
// console.log('openTab', docId, doc);
CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
- const docView = DocumentManager.Instance.getDocumentView(doc);
+ const docView = DocumentView.getDocumentView(doc);
// BUG - this returns undefined if the doc is already open
return docView?.ComponentView as CollectionFreeFormView;
};
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index 8df579e75..6948469cc 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -5,8 +5,8 @@
// import * as typescriptlib from '!!raw-loader!../../../node_modules/typescript/lib/lib.d.ts'
// import * as typescriptes5 from '!!raw-loader!../../../node_modules/typescript/lib/lib.es5.d.ts'
// eslint-disable-next-line node/no-unpublished-import
-import * as ts from 'typescript';
import * as typescriptlib from '!!raw-loader!./type_decls.d';
+import * as ts from 'typescript';
import { Doc, FieldType } from '../../fields/Doc';
import { RefField } from '../../fields/RefField';
import { ScriptField } from '../../fields/ScriptField';
@@ -195,7 +195,6 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
if (found) return found as CompiledScript;
const { requiredType = '', addReturn = false, params = {}, capturedVariables = {}, typecheck = true } = options;
if (options.params && !options.params.this) options.params.this = Doc.name;
- if (options.params && !options.params.self) options.params.self = Doc.name;
if (options.globals) {
ScriptingGlobals.setScriptingGlobals(options.globals);
}
@@ -266,9 +265,3 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
!signature.includes('XXX') && ScriptField._scriptFieldCache.set(script + ':' + signature, result as CompiledScript);
return result;
}
-
-ScriptingGlobals.add(CompileScript);
-// eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function runScript(doc: Doc, script: ScriptField) {
- return script?.script.run({ this: doc }).result;
-});
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 7e8f42de9..0b942116c 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,6 +1,5 @@
import { action, makeObservable, observable, runInAction } from 'mobx';
import { Doc, Opt } from '../../fields/Doc';
-import { DocViews } from '../../fields/DocSymbols';
import { List } from '../../fields/List';
import { listSpec } from '../../fields/Schema';
import { Cast, DocCast } from '../../fields/Types';
@@ -24,6 +23,13 @@ export class SelectionManager {
private constructor() {
SelectionManager._manager = this;
makeObservable(this);
+ DocumentView.DeselectAll = SelectionManager.DeselectAll;
+ DocumentView.DeselectView = SelectionManager.DeselectView;
+ DocumentView.SelectView = SelectionManager.SelectView;
+ DocumentView.SelectedDocs = SelectionManager.Docs;
+ DocumentView.Selected = SelectionManager.Views;
+ DocumentView.SelectSchemaDoc = SelectionManager.SelectSchemaViewDoc;
+ DocumentView.SelectedSchemaDoc = () => this.SelectedSchemaDocument;
}
@action
@@ -54,8 +60,10 @@ export class SelectionManager {
public static DeselectAll = (except?: Doc): void => {
const found = this.Instance.SelectedViews.find(dv => dv.Document === except);
runInAction(() => {
- LinkManager.Instance.currentLink = undefined;
- LinkManager.Instance.currentLinkAnchor = undefined;
+ if (LinkManager.Instance) {
+ LinkManager.Instance.currentLink = undefined;
+ LinkManager.Instance.currentLinkAnchor = undefined;
+ }
this.Instance.SelectedSchemaDocument = undefined;
});
this.Instance.SelectedViews.forEach(dv => {
@@ -68,19 +76,18 @@ export class SelectionManager {
if (found) this.SelectView(found, false);
};
- public static IsSelected = (doc?: Doc) => Array.from(doc?.[DocViews] ?? []).some(dv => dv?.IsSelected);
- public static get Views() { return this.Instance.SelectedViews; } // prettier-ignore
- public static get SelectedSchemaDoc() { return this.Instance.SelectedSchemaDocument; } // prettier-ignore
- public static get Docs() { return this.Instance.SelectedViews.map(dv => dv.Document).filter(doc => doc?._type_collection !== CollectionViewType.Docking); } // prettier-ignore
+ public static Views() { return SelectionManager.Instance.SelectedViews; } // prettier-ignore
+ public static get SelectedSchemaDoc() { return SelectionManager.Instance.SelectedSchemaDocument; } // prettier-ignore
+ public static Docs() { return SelectionManager.Instance.SelectedViews.map(dv => dv.Document).filter(doc => doc?._type_collection !== CollectionViewType.Docking); } // prettier-ignore
}
// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function SelectedDocType(type: string, expertMode: boolean, checkContext?: boolean) {
if (Doc.noviceMode && expertMode) return false;
if (type === 'tab') {
- return SelectionManager.Views.lastElement()?._props.renderDepth === 0;
+ return DocumentView.Selected().lastElement()?._props.renderDepth === 0;
}
- const selected = (sel => (checkContext ? DocCast(sel?.embedContainer) : sel))(SelectionManager.SelectedSchemaDoc ?? SelectionManager.Docs.lastElement());
+ const selected = (sel => (checkContext ? DocCast(sel?.embedContainer) : sel))(DocumentView.SelectedSchemaDoc() ?? SelectionManager.Docs().lastElement());
return selected?.type === type || selected?.type_collection === type || !type;
});
// eslint-disable-next-line prefer-arrow-callback
@@ -109,8 +116,6 @@ ScriptingGlobals.add(function redo() {
});
// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) {
- const docs = SelectionManager.Views.map(dv => dv.Document).filter(
- d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.KVP && (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null))
- );
+ const docs = SelectionManager.Docs().filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.KVP && (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null)));
return docs.length ? new List(docs) : prevValue;
});
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 8cb97fe50..d3c10f9f4 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -8,7 +8,7 @@ import * as React from 'react';
import { BsGoogle } from 'react-icons/bs';
import { FaFillDrip, FaPalette } from 'react-icons/fa';
import { ClientUtils, addStyleSheet, addStyleSheetRule } from '../../ClientUtils';
-import { Doc, Opt } from '../../fields/Doc';
+import { Doc } from '../../fields/Doc';
import { DashVersion } from '../../fields/DocSymbols';
import { BoolCast, Cast, NumCast, StrCast } from '../../fields/Types';
import { DocServer } from '../DocServer';
@@ -17,7 +17,7 @@ import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager
import { MainViewModal } from '../views/MainViewModal';
import { GroupManager } from './GroupManager';
import './SettingsManager.scss';
-import { SnappingManager } from './SnappingManager';
+import { SnappingManager, freeformScrollMode } from './SnappingManager';
import { undoable } from './UndoManager';
export enum ColorScheme {
@@ -28,11 +28,6 @@ export enum ColorScheme {
Cupcake = 'Cupcake',
}
-export enum freeformScrollMode {
- Pan = 'pan',
- Zoom = 'zoom',
-}
-
@observer
export class SettingsManager extends React.Component<{}> {
// eslint-disable-next-line no-use-before-define
@@ -44,17 +39,15 @@ export class SettingsManager extends React.Component<{}> {
@observable private _curr_password = '';
@observable private _new_password = '';
@observable private _new_confirm = '';
- @observable private _lastPressedSidebarBtn: Opt = undefined; // bcz: this is a hack to handle highlighting buttons in the leftpanel menu .. need to find a cleaner approach
@observable private _activeTab = 'Accounts';
@observable private _isOpen = false;
- @observable public propertiesWidth: number = 0;
-
private googleAuthorize = action(() => GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true));
public closeMgr = action(() => {
this._isOpen = false;
});
+ // eslint-disable-next-line react/no-unused-class-component-methods
public openMgr = action(() => {
this._isOpen = true;
});
@@ -154,9 +147,6 @@ export class SettingsManager extends React.Component<{}> {
SnappingManager.SettingsStyle = SettingsManager._settingsStyle;
}
- public get LastPressedBtn() { return this._lastPressedSidebarBtn; } // prettier-ignore
- public set LastPressedBtn(state:Doc|undefined) { this._lastPressedSidebarBtn = state; } // prettier-ignore
-
@computed public static get userColor() {
return StrCast(Doc.UserDoc().userColor);
}
@@ -287,7 +277,7 @@ export class SettingsManager extends React.Component<{}> {
size={Size.XSMALL}
color={SettingsManager.userColor}
/>
- {
toggleStatus={BoolCast(Doc.UserDoc().showLinkLines)}
size={Size.XSMALL}
color={SettingsManager.userColor}
- />
+ /> */}
{
const users = this.individualSort === 'ascending' ? this.users.slice().sort(this.sortUsers) : this.individualSort === 'descending' ? this.users.slice().sort(this.sortUsers).reverse() : this.users;
const groups = this.groupSort === 'ascending' ? groupList.slice().sort(this.sortGroups) : this.groupSort === 'descending' ? groupList.slice().sort(this.sortGroups).reverse() : groupList;
- let docs = SelectionManager.Views.length < 2 ? [this.targetDoc] : SelectionManager.Views.map(docView => docView.Document);
+ let docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document);
if (this.myDocAcls) {
const newDocs: Doc[] = [];
@@ -442,7 +440,7 @@ export class SharingManager extends React.Component<{}> {
const { user, sharingDoc } = recipient;
const target = targetDoc || this.targetDoc!;
const acl = `acl_${normalizeEmail(user.email)}`;
- const docs = SelectionManager.Views.length < 2 ? [target] : SelectionManager.Views.map(docView => docView.Document);
+ const docs = DocumentView.Selected().length < 2 ? [target] : DocumentView.Selected().map(docView => docView.Document);
docs.map(doc => (this.layoutDocAcls || doc.dockingConfig ? doc : Doc.GetProto(doc))).forEach(doc => {
distributeAcls(acl, permission as SharingPermissions, doc, undefined, this.upgradeNested ? true : undefined);
if (permission !== SharingPermissions.None) {
@@ -460,7 +458,7 @@ export class SharingManager extends React.Component<{}> {
const target = targetDoc || this.targetDoc!;
const acl = `acl_${normalizeEmail(StrCast(group.title))}`;
- const docs = SelectionManager.Views.length < 2 ? [target] : SelectionManager.Views.map(docView => docView.Document);
+ const docs = DocumentView.Selected().length < 2 ? [target] : DocumentView.Selected().map(docView => docView.Document);
docs.map(doc => (this.layoutDocAcls || doc.dockingConfig ? doc : Doc.GetProto(doc))).forEach(doc => {
distributeAcls(acl, permission as SharingPermissions, doc, undefined, this.upgradeNested ? true : undefined);
@@ -643,14 +641,14 @@ export class SharingManager extends React.Component<{}> {
private focusOn = (contents: string) => {
const title = this.targetDoc ? StrCast(this.targetDoc.title) : '';
- const docs = SelectionManager.Views.length > 1 ? SelectionManager.Views.map(docView => docView.props.Document) : [this.targetDoc];
+ const docs = DocumentView.Selected().length > 1 ? DocumentView.Selected().map(docView => docView.props.Document) : [this.targetDoc];
return (
{
if (this.targetDoc && this.targetDocView && docs.length === 1) {
- DocumentManager.Instance.showDocument(this.targetDoc, { willZoomCentered: true });
+ DocumentView.showDocument(this.targetDoc, { willZoomCentered: true });
}
}}
onPointerEnter={action(() => {
diff --git a/src/client/util/SnappingManager.ts b/src/client/util/SnappingManager.ts
index 5cd6ecfe1..6789c2ab8 100644
--- a/src/client/util/SnappingManager.ts
+++ b/src/client/util/SnappingManager.ts
@@ -1,5 +1,9 @@
import { observable, action, runInAction, makeObservable } from 'mobx';
+export enum freeformScrollMode {
+ Pan = 'pan',
+ Zoom = 'zoom',
+}
export class SnappingManager {
// eslint-disable-next-line no-use-before-define
private static _manager: SnappingManager;
@@ -19,6 +23,9 @@ export class SnappingManager {
@observable _vertSnapLines: number[] = [];
@observable _exploreMode = false;
@observable _userPanned = false;
+ @observable _serverVersion: string = '';
+ @observable _lastBtnId: string = '';
+ @observable _propertyWid: number = 0;
private constructor() {
SnappingManager._manager = this;
@@ -45,6 +52,10 @@ export class SnappingManager {
public static get CanEmbed() { return this.Instance._canEmbed; } // prettier-ignore
public static get ExploreMode() { return this.Instance._exploreMode; } // prettier-ignore
public static get UserPanned() { return this.Instance._userPanned; } // prettier-ignore
+ public static get ServerVersion() { return this.Instance._serverVersion; } // prettier-ignore
+ public static get LastPressedBtn() { return this.Instance._lastBtnId; } // prettier-ignore
+ public static get PropertiesWidth(){ return this.Instance._propertyWid; } // prettier-ignore
+
public static SetShiftKey = (down: boolean) => runInAction(() => {this.Instance._shiftKey = down}); // prettier-ignore
public static SetCtrlKey = (down: boolean) => runInAction(() => {this.Instance._ctrlKey = down}); // prettier-ignore
public static SetMetaKey = (down: boolean) => runInAction(() => {this.Instance._metaKey = down}); // prettier-ignore
@@ -54,7 +65,10 @@ export class SnappingManager {
public static SetIsResizing = (docid?:string) => runInAction(() => {this.Instance._isResizing = docid}); // prettier-ignore
public static SetCanEmbed = (embed:boolean) => runInAction(() => {this.Instance._canEmbed = embed}); // prettier-ignore
public static SetExploreMode = (state:boolean) => runInAction(() => {this.Instance._exploreMode = state}); // prettier-ignore
- public static TriggerUserPanned = () => runInAction(() => {this.Instance._userPanned = !this.Instance._userPanned}); // prettier-ignore
+ public static TriggerUserPanned = () => runInAction(() => {this.Instance._userPanned = !this.Instance._userPanned}); // prettier-ignore
+ public static SetServerVersion = (version:string) =>runInAction(() => {this.Instance._serverVersion = version}); // prettier-ignore
+ public static SetLastPressedBtn = (id:string) =>runInAction(() => {this.Instance._lastBtnId = id}); // prettier-ignore
+ public static SetPropertiesWidth= (wid:number) =>runInAction(() => {this.Instance._propertyWid = wid}); // prettier-ignore
public static userColor: string | undefined;
public static userVariantColor: string | undefined;
diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx
index b1eb730fa..303672d90 100644
--- a/src/client/views/AntimodeMenu.tsx
+++ b/src/client/views/AntimodeMenu.tsx
@@ -1,6 +1,6 @@
import { action, makeObservable, observable, runInAction } from 'mobx';
import * as React from 'react';
-import { SettingsManager } from '../util/SettingsManager';
+import { SnappingManager } from '../util/SnappingManager';
import './AntimodeMenu.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
@@ -157,7 +157,7 @@ export abstract class AntimodeMenu extends Observab
left: this._left,
top: this._top,
opacity: this._opacity,
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
transitionProperty: this._transitionProperty,
transitionDuration: this._transitionDuration,
transitionDelay: this._transitionDelay,
@@ -183,7 +183,7 @@ export abstract class AntimodeMenu extends Observab
height: 'inherit',
width: 200,
opacity: this._opacity,
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
transitionProperty: this._transitionProperty,
transitionDuration: this._transitionDuration,
transitionDelay: this._transitionDelay,
@@ -206,7 +206,7 @@ export abstract class AntimodeMenu extends Observab
left: this._left,
top: this._top,
opacity: this._opacity,
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
transitionProperty: this._transitionProperty,
transitionDuration: this._transitionDuration,
transitionDelay: this._transitionDelay,
diff --git a/src/client/views/ComponentDecorations.tsx b/src/client/views/ComponentDecorations.tsx
index 64b8a8446..929b549e0 100644
--- a/src/client/views/ComponentDecorations.tsx
+++ b/src/client/views/ComponentDecorations.tsx
@@ -1,7 +1,7 @@
import { observer } from 'mobx-react';
import * as React from 'react';
-import { SelectionManager } from '../util/SelectionManager';
import './ComponentDecorations.scss';
+import { DocumentView } from './nodes/DocumentView';
@observer
export class ComponentDecorations extends React.Component<{ boundsTop: number; boundsLeft: number }, { value: string }> {
@@ -9,7 +9,7 @@ export class ComponentDecorations extends React.Component<{ boundsTop: number; b
static Instance: ComponentDecorations;
render() {
- const seldoc = SelectionManager.Views.lastElement();
+ const seldoc = DocumentView.Selected().lastElement();
return seldoc?.ComponentView?.componentUI?.(this.props.boundsLeft, this.props.boundsTop) ?? null;
}
}
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index a0e3d2ddd..97ff346e4 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -60,6 +60,8 @@ export interface ViewBoxInterface {
ptFromScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number };
snapPt?: (pt: { X: number; Y: number }, excludeSegs?: number[]) => { nearestPt: { X: number; Y: number }; distance: number };
search?: (str: string, bwd?: boolean, clear?: boolean) => boolean;
+ dontRegisterView?: () => boolean; // KeyValueBox's don't want to register their views
+ isUnstyledView?: () => boolean; // SchemaView and KeyValue are untyled -- not tiles, no opacity
}
/**
* DocComponent returns a React base class used by Doc views with accessors for unpacking the Document,layoutDoc, and dataDoc's
diff --git a/src/client/views/DocViewUtils.ts b/src/client/views/DocViewUtils.ts
new file mode 100644
index 000000000..1f5f29c7e
--- /dev/null
+++ b/src/client/views/DocViewUtils.ts
@@ -0,0 +1,21 @@
+/* eslint-disable prefer-destructuring */
+/* eslint-disable default-param-last */
+/* eslint-disable no-use-before-define */
+import { runInAction } from 'mobx';
+import { Doc, SetActiveAudioLinker } from '../../fields/Doc';
+import { DocUtils } from '../documents/DocUtils';
+import { FieldViewProps } from './nodes/FieldView';
+
+export namespace DocViewUtils {
+ export const ActiveRecordings: { props: FieldViewProps; getAnchor: (addAsAnnotation: boolean) => Doc }[] = [];
+
+ export function MakeLinkToActiveAudio(getSourceDoc: () => Doc | undefined, broadcastEvent = true) {
+ broadcastEvent && runInAction(() => { Doc.RecordingEvent += 1; }); // prettier-ignore
+ return ActiveRecordings.map(audio => {
+ const sourceDoc = getSourceDoc();
+ return sourceDoc && DocUtils.MakeLink(sourceDoc, audio.getAnchor(true) || audio.props.Document, { link_relationship: 'recording annotation:linked recording', link_description: 'recording timeline' });
+ });
+ }
+
+ SetActiveAudioLinker(MakeLinkToActiveAudio);
+}
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index dd744f272..487868169 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -14,23 +14,21 @@ import { returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '
import { emptyFunction } from '../../Utils';
import { Doc } from '../../fields/Doc';
import { Cast, DocCast } from '../../fields/Types';
-import { DocUtils } from '../documents/DocUtils';
+import { DocUtils, IsFollowLinkScript } from '../documents/DocUtils';
import { CalendarManager } from '../util/CalendarManager';
+import { DictationManager } from '../util/DictationManager';
import { DragManager } from '../util/DragManager';
import { dropActionType } from '../util/DropActionTypes';
-import { IsFollowLinkScript } from '../util/LinkFollower';
-import { SelectionManager } from '../util/SelectionManager';
import { SharingManager } from '../util/SharingManager';
import { UndoManager, undoBatch } from '../util/UndoManager';
import './DocumentButtonBar.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
import { PinProps } from './PinFuncs';
import { TemplateMenu } from './TemplateMenu';
-import { TabDocView } from './collections/TabDocView';
import { Colors } from './global/globalEnums';
import { LinkPopup } from './linking/LinkPopup';
import { DocumentLinksButton } from './nodes/DocumentLinksButton';
-import { DocumentView, DocumentViewInternal } from './nodes/DocumentView';
+import { DocumentView } from './nodes/DocumentView';
import { OpenWhere } from './nodes/OpenWhere';
import { DashFieldView } from './nodes/formattedText/DashFieldView';
@@ -206,7 +204,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
.views()
.filter(v => v)
.map(dv => dv!.Document);
- TabDocView.PinDoc(docs, {
+ DocumentView.PinDoc(docs, {
pinAudioPlay: true,
pinDocLayout: pinLayoutView,
pinData: { dataview: pinContentView },
@@ -221,7 +219,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
);
};
return !targetDoc ? null : (
- {`Pin Document ${SelectionManager.Views.length > 1 ? 'multiple documents' : ''} to Trail`}
}>
+
{`Pin Document ${DocumentView.Selected().length > 1 ? 'multiple documents' : ''} to Trail`} }>
{
@@ -229,7 +227,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
.views()
.filter(v => v)
.map(dv => dv!.Document);
- TabDocView.PinDoc(docs, { pinAudioPlay: true, pinDocLayout: e.shiftKey, pinData: { dataview: e.altKey }, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) });
+ DocumentView.PinDoc(docs, { pinAudioPlay: true, pinDocLayout: e.shiftKey, pinData: { dataview: e.altKey }, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) });
e.stopPropagation();
}}>
@@ -299,7 +297,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
this._props.views().map(
view =>
view &&
- DocumentViewInternal.recordAudioAnnotation(
+ DictationManager.recordAudioAnnotation(
view.dataDoc,
view.LayoutFieldKey,
stopFunc => {
@@ -381,7 +379,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
}
openContextMenu = (e: PointerEvent) => {
- let child = SelectionManager.Views[0].ContentDiv!.children[0];
+ let child = DocumentView.Selected()[0].ContentDiv!.children[0];
while (child.children.length) {
const next = Array.from(child.children).find(c => c.className?.toString().includes('SVGAnimatedString') || typeof c.className === 'string');
if (next?.className?.toString().includes(DocumentView.ROOT_DIV)) break;
@@ -442,14 +440,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
{this._showLinkPopup ? (
- {
- link.link_displayLine = !IsFollowLinkScript(this._props.views().lastElement()?.Document.onClick);
- }}
- linkCreateAnchor={() => this._props.views().lastElement()?.ComponentView?.getAnchor?.(true)}
- linkFrom={() => this._props.views().lastElement()?.Document}
- />
+ this._props.views().lastElement()?.ComponentView?.getAnchor?.(true)} linkFrom={() => this._props.views().lastElement()?.Document} />
) : (
{this.linkButton}
@@ -457,7 +448,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
{DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== doc ?
{this.endLinkButton}
: null}
{this.templateButton}
- {!SelectionManager.Views?.some(v => v.allLinks.length) ? null :
{this.followLinkButton}
}
+ {!DocumentView.Selected().some(v => v.allLinks.length) ? null :
{this.followLinkButton}
}
{this.pinButton}
{this.recordButton}
{this.calendarButton}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index ef493fb69..432b02782 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -17,9 +17,7 @@ import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { GetEffectiveAcl } from '../../fields/util';
import { DocumentType } from '../documents/DocumentTypes';
import { Docs } from '../documents/Documents';
-import { DocumentManager } from '../util/DocumentManager';
import { DragManager } from '../util/DragManager';
-import { SelectionManager } from '../util/SelectionManager';
import { SettingsManager } from '../util/SettingsManager';
import { SnappingManager } from '../util/SnappingManager';
import { UndoManager } from '../util/UndoManager';
@@ -81,14 +79,14 @@ export class DocumentDecorations extends ObservableReactComponent
center.x+x || this.Bounds.r < center.x+x ||
this.Bounds.y > center.y+y || this.Bounds.b < center.y+y )));
@@ -110,7 +108,7 @@ export class DocumentDecorations extends ObservableReactComponent dv._props.renderDepth > 0)
.map(dv => dv.getBounds)
.reduce((bounds, rect) => !rect ? bounds
@@ -127,7 +125,7 @@ export class DocumentDecorations extends ObservableReactComponent#')) {
- SelectionManager.Docs.forEach(doc => {
+ DocumentView.SelectedDocs().forEach(doc => {
doc[DocData].onViewMounted = ScriptField.MakeScript(`updateTagsCollection(this)`);
});
}
@@ -135,11 +133,11 @@ export class DocumentDecorations extends ObservableReactComponent
titleFieldKey &&
- SelectionManager.Views.forEach(d => {
+ DocumentView.Selected().forEach(dv => {
if (titleFieldKey === 'title') {
- d.dataDoc.title_custom = !this._accumulatedTitle.startsWith('-');
+ dv.dataDoc.title_custom = !this._accumulatedTitle.startsWith('-');
}
- KeyValueBox.SetField(d.Document, titleFieldKey, this._accumulatedTitle);
+ KeyValueBox.SetField(dv.Document, titleFieldKey, this._accumulatedTitle);
}),
'edit title'
);
@@ -154,7 +152,7 @@ export class DocumentDecorations extends ObservableReactComponent {
- const effectiveLayoutAcl = GetEffectiveAcl(SelectionManager.Views[0].Document);
+ const effectiveLayoutAcl = GetEffectiveAcl(DocumentView.Selected()[0].Document);
if (effectiveLayoutAcl === AclAdmin || effectiveLayoutAcl === AclEdit || effectiveLayoutAcl === AclAugment) {
setupMoveUpEvents(this, e, moveEv => this.onBackgroundMove(true, moveEv), emptyFunction, emptyFunction);
e.stopPropagation();
@@ -162,7 +160,7 @@ export class DocumentDecorations extends ObservableReactComponent {
- const effectiveLayoutAcl = GetEffectiveAcl(SelectionManager.Views[0].Document);
+ const effectiveLayoutAcl = GetEffectiveAcl(DocumentView.SelectedDocs()[0]);
if (effectiveLayoutAcl === AclAdmin || effectiveLayoutAcl === AclEdit || effectiveLayoutAcl === AclAugment) {
setupMoveUpEvents(
this,
@@ -170,7 +168,7 @@ export class DocumentDecorations extends ObservableReactComponent this.onBackgroundMove(true, moveEv),
emptyFunction,
action(() => {
- const selected = SelectionManager.Views.length === 1 ? SelectionManager.Docs[0] : undefined;
+ const selected = DocumentView.SelectedDocs().length === 1 ? DocumentView.SelectedDocs()[0] : undefined;
!this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('$') ? (selected && Field.toKeyValueString(selected, this._titleControlString.substring(1))) || '-unset-' : this._titleControlString);
this._editingTitle = true;
this._keyinput.current && setTimeout(this._keyinput.current.focus);
@@ -186,19 +184,16 @@ export class DocumentDecorations extends ObservableReactComponent {
- const dragDocView = SelectionManager.Views[0];
+ const dragDocView = DocumentView.Selected()[0];
const effectiveLayoutAcl = GetEffectiveAcl(dragDocView.Document);
if (effectiveLayoutAcl !== AclAdmin && effectiveLayoutAcl !== AclEdit && effectiveLayoutAcl !== AclAugment) {
return false;
}
const containers = new Set();
- SelectionManager.Views.forEach(v => containers.add(DocCast(v.Document.embedContainer)));
+ DocumentView.Selected().forEach(v => containers.add(DocCast(v.Document.embedContainer)));
if (containers.size > 1) return false;
const { left, top } = dragDocView.getBounds || { left: 0, top: 0 };
- const dragData = new DragManager.DocumentDragData(
- SelectionManager.Views.map(dv => dv.Document),
- dragDocView._props.dropAction
- );
+ const dragData = new DragManager.DocumentDragData(DocumentView.SelectedDocs(), dragDocView._props.dropAction);
dragData.offset = dragDocView.screenToContentsTransform().transformDirection(e.x - left, e.y - top);
dragData.moveDocument = dragDocView._props.moveDocument;
dragData.removeDocument = dragDocView._props.removeDocument;
@@ -206,7 +201,7 @@ export class DocumentDecorations extends ObservableReactComponent dv.ContentDiv!),
+ DocumentView.Selected().map(dv => dv.ContentDiv!),
dragData,
e.x,
e.y,
@@ -223,7 +218,7 @@ export class DocumentDecorations extends ObservableReactComponent {
- const views = SelectionManager.Views.filter(v => v && v._props.renderDepth > 0);
+ const views = DocumentView.Selected().filter(v => v && v._props.renderDepth > 0);
if (forceDeleteOrIconify === false && this._iconifyBatch) return;
this._deleteAfterIconify = !!(forceDeleteOrIconify || this._iconifyBatch);
let iconifyingCount = views.length;
@@ -239,7 +234,7 @@ export class DocumentDecorations extends ObservableReactComponent {
- setupMoveUpEvents(this, e, () => DragManager.StartWindowDrag?.(e, [SelectionManager.Views.lastElement().Document]) ?? false, emptyFunction, this.onMaximizeClick, false, false);
+ setupMoveUpEvents(this, e, () => DragManager.StartWindowDrag?.(e, [DocumentView.SelectedDocs().lastElement()]) ?? false, emptyFunction, this.onMaximizeClick, false, false);
e.stopPropagation();
};
onMaximizeClick = (e: any): void => {
- const selectedDocs = SelectionManager.Views;
+ const selectedDocs = DocumentView.SelectedDocs();
if (selectedDocs.length) {
if (e.ctrlKey) {
// open an embedding in a new tab with Ctrl Key
- CollectionDockingView.AddSplit(Doc.BestEmbedding(selectedDocs[0].Document), OpenWhereMod.right);
+ CollectionDockingView.AddSplit(Doc.BestEmbedding(selectedDocs[0]), OpenWhereMod.right);
} else if (e.shiftKey) {
// open centered in a new workspace with Shift Key
- const embedding = Doc.MakeEmbedding(selectedDocs[0].Document);
+ const embedding = Doc.MakeEmbedding(selectedDocs[0]);
embedding.embedContainer = undefined;
embedding.x = -NumCast(embedding._width) / 2;
embedding.y = -NumCast(embedding._height) / 2;
CollectionDockingView.AddSplit(Docs.Create.FreeformDocument([embedding], { title: 'Tab for ' + embedding.title }), OpenWhereMod.right);
} else if (e.altKey) {
// open same document in new tab
- CollectionDockingView.ToggleSplit(selectedDocs[0].Document, OpenWhereMod.right);
+ CollectionDockingView.ToggleSplit(selectedDocs[0], OpenWhereMod.right);
} else {
- let openDoc = selectedDocs[0].Document;
+ let openDoc = selectedDocs[0];
if (openDoc.layout_fieldKey === 'layout_icon') {
openDoc = Doc.GetEmbeddings(openDoc).find(embedding => !embedding.embedContainer) ?? Doc.MakeEmbedding(openDoc);
Doc.deiconifyView(openDoc);
}
- LightboxView.Instance.SetLightboxDoc(
- openDoc,
- undefined,
- selectedDocs.slice(1).map(view => view.Document)
- );
+ LightboxView.Instance.SetLightboxDoc(openDoc, undefined, selectedDocs.slice(1));
}
}
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
};
onIconifyClick = (): void => {
- SelectionManager.Views.forEach(dv => dv?.iconify());
- SelectionManager.DeselectAll();
+ DocumentView.Selected().forEach(dv => dv?.iconify());
+ DocumentView.DeselectAll();
};
- onSelectContainerDocClick = () => SelectionManager.Views?.[0]?.containerViewPath?.().lastElement()?.select(false);
+ onSelectContainerDocClick = () => DocumentView.Selected()?.[0]?.containerViewPath?.().lastElement()?.select(false);
/**
* sets up events when user clicks on the border radius editor
*/
@action
onRadiusDown = (e: React.PointerEvent): void => {
- SnappingManager.SetIsResizing(SelectionManager.Docs.lastElement()?.[Id]);
+ SnappingManager.SetIsResizing(DocumentView.SelectedDocs().lastElement()?.[Id]);
this._isRounding = true;
this._resizeUndo = UndoManager.StartBatch('DocDecs set radius');
setupMoveUpEvents(
@@ -314,7 +305,7 @@ export class DocumentDecorations extends ObservableReactComponent {
+ DocumentView.SelectedDocs().forEach(doc => {
const docMax = Math.min(NumCast(doc.width) / 2, NumCast(doc.height) / 2);
const radius = Math.min(1, dist / maxDist) * docMax; // set radius based on ratio of drag distance to half diagonal distance of bounding box
doc._layout_borderRounding = `${radius}px`;
@@ -339,7 +330,7 @@ export class DocumentDecorations extends ObservableReactComponent UndoManager.RunInBatch(() => SelectionManager.Docs.forEach(doc => Doc.toggleLockedPosition(doc)), 'toggleBackground')
+ () => UndoManager.RunInBatch(() => DocumentView.Selected().forEach(dv => Doc.toggleLockedPosition(dv.Document)), 'toggleBackground')
);
e.stopPropagation();
};
@@ -356,7 +347,7 @@ export class DocumentDecorations extends ObservableReactComponent {
this._isRotating = true;
- const seldocview = SelectionManager.Views[0];
+ const seldocview = DocumentView.Selected()[0];
setupMoveUpEvents(
this,
e,
@@ -374,11 +365,11 @@ export class DocumentDecorations extends ObservableReactComponent i.ComponentView instanceof InkingStroke);
+ const selectedInk = DocumentView.Selected().filter(i => i.ComponentView instanceof InkingStroke);
const centerPoint = this.rotCenter.slice();
const infos = new Map();
- const seldocview = SelectionManager.Views[0];
- SelectionManager.Views.forEach(dv => {
+ const seldocview = DocumentView.Selected()[0];
+ DocumentView.Selected().forEach(dv => {
const accumRot = (NumCast(dv.Document._rotation) / 180) * Math.PI;
const localRotCtr = dv.screenToViewTransform().transformPoint(rcScreen.X, rcScreen.Y);
const localRotCtrOffset = [localRotCtr[0] - NumCast(dv.Document.width) / 2, localRotCtr[1] - NumCast(dv.Document.height) / 2];
@@ -387,7 +378,7 @@ export class DocumentDecorations extends ObservableReactComponent {
- SelectionManager.Views.forEach(
+ DocumentView.Selected().forEach(
action(dv => {
const { unrotatedDocPos, startRotCtr, accumRot } = infos.get(dv.Document)!;
const endRotCtr = Utils.rotPt(startRotCtr.x, startRotCtr.y, isAbs ? angle : accumRot + angle);
@@ -437,7 +428,7 @@ export class DocumentDecorations extends ObservableReactComponent {
- SnappingManager.SetIsResizing(SelectionManager.Docs.lastElement()?.[Id]); // turns off pointer events on things like youtube videos and web pages so that dragging doesn't get "stuck" when cursor moves over them
+ SnappingManager.SetIsResizing(DocumentView.Selected().lastElement()?.Document[Id]); // turns off pointer events on things like youtube videos and web pages so that dragging doesn't get "stuck" when cursor moves over them
setupMoveUpEvents(this, e, this.onPointerMove, this.onPointerUp, emptyFunction);
e.stopPropagation();
const id = (this._resizeHdlId = e.currentTarget.className);
@@ -449,7 +440,7 @@ export class DocumentDecorations extends ObservableReactComponent CollectionFreeFormView.from(docView)?.dragStarting(false, false));
+ DocumentView.Selected().forEach(docView => CollectionFreeFormView.from(docView)?.dragStarting(false, false));
};
projectDragToAspect = (e: PointerEvent, docView: DocumentView, fixedAspect: number) => {
@@ -467,7 +458,7 @@ export class DocumentDecorations extends ObservableReactComponent {
- const first = SelectionManager.Views[0];
+ const first = DocumentView.Selected()[0];
const effectiveAcl = GetEffectiveAcl(first.Document);
if (!(effectiveAcl === AclAdmin || effectiveAcl === AclEdit || effectiveAcl === AclAugment)) return false;
if (!first) return false;
@@ -484,10 +475,10 @@ export class DocumentDecorations extends ObservableReactComponent { // resize selected docs if we're not in the middle of a resize (ie, throttle input events to frame rate)
this._interactionLock = true;
this._snapPt = thisPt;
- e.ctrlKey && (SelectionManager.Views.forEach(docView => !Doc.NativeHeight(docView.Document) && docView.toggleNativeDimensions()));
- const hasFixedAspect = SelectionManager.Docs.some(this.hasFixedAspect);
+ e.ctrlKey && (DocumentView.Selected().forEach(docView => !Doc.NativeHeight(docView.Document) && docView.toggleNativeDimensions()));
+ const hasFixedAspect = DocumentView.Selected().map(dv => dv.Document).some(this.hasFixedAspect);
const scaleAspect = {x:scale.x === 1 && hasFixedAspect ? scale.y : scale.x, y: scale.x !== 1 && hasFixedAspect ? scale.x : scale.y};
- SelectionManager.Views.forEach(docView =>
+ DocumentView.Selected().forEach(docView =>
this.resizeView(docView, refPt, scaleAspect, { dragHdl, ctrlKey:e.ctrlKey })); // prettier-ignore
await new Promise(res => { setTimeout(() => { res(this._interactionLock = undefined)})});
}); // prettier-ignore
@@ -526,7 +517,7 @@ export class DocumentDecorations extends ObservableReactComponent DocumentManager.Instance.getDocumentView(member, docView)!)
+ .map(member => DocumentView.getDocumentView(member, docView)!)
.forEach(member => this.resizeView(member, refPt, scale, opts));
doc.xPadding = NumCast(doc.xPadding) * scale.x;
doc.yPadding = NumCast(doc.yPadding) * scale.y;
@@ -607,7 +598,7 @@ export class DocumentDecorations extends ObservableReactComponent {
+ DocumentView.Selected().forEach(view => {
NumCast(view.Document._height) < 20 && (view.layoutDoc._layout_autoHeight = true);
});
// need to change points for resize, or else rotation/control points will fail.
@@ -626,18 +617,18 @@ export class DocumentDecorations extends ObservableReactComponent 1 ? '-multiple-' : '-unset-';
+ return DocumentView.Selected().length > 1 ? '-multiple-' : '-unset-';
}
@computed get rotCenter() {
- const lastView = SelectionManager.Views.lastElement();
+ const lastView = DocumentView.Selected().lastElement();
if (lastView) {
const invXf = lastView.screenToContentsTransform().inverse();
const seldoc = lastView.layoutDoc;
@@ -649,7 +640,7 @@ export class DocumentDecorations extends ObservableReactComponent {
@@ -678,7 +669,7 @@ export class DocumentDecorations extends ObservableReactComponent docView.Document._dragOnlyWithinContainer || docView.Document.isGroup || docView.Document.layout_hideOpenButton) ||
+ DocumentView.Selected().some(docView => docView.Document._dragOnlyWithinContainer || docView.Document.isGroup || docView.Document.layout_hideOpenButton) ||
this._isRounding ||
this._isRotating;
const hideDeleteButton =
@@ -688,7 +679,7 @@ export class DocumentDecorations extends ObservableReactComponent {
+ DocumentView.Selected().some(docView => {
const collectionAcl = docView.containerViewPath?.()?.lastElement() ? GetEffectiveAcl(docView.containerViewPath?.().lastElement().dataDoc) : AclEdit;
return collectionAcl !== AclAdmin && collectionAcl !== AclEdit && GetEffectiveAcl(docView.Document) !== AclAdmin;
});
@@ -703,7 +694,7 @@ export class DocumentDecorations extends ObservableReactComponent 135;
const useRotation = !hideResizers && seldocview.Document.type !== DocumentType.EQUATION && CollectionFreeFormDocumentView.from(seldocview); // when do we want an object to not rotate?
- const rotation = SelectionManager.Views.length === 1 ? seldocview.screenToContentsTransform().inverse().RotateDeg : 0;
+ const rotation = DocumentView.Selected().length === 1 ? seldocview.screenToContentsTransform().inverse().RotateDeg : 0;
// Radius constants
const useRounding = seldocview.ComponentView instanceof ImageBox || seldocview.ComponentView instanceof FormattedTextBox || seldocview.ComponentView instanceof CollectionFreeFormView;
@@ -773,7 +764,7 @@ export class DocumentDecorations extends ObservableReactComponent CollectionFreeFormDocumentView.from(v));
+ const freeformDoc = DocumentView.Selected().some(v => CollectionFreeFormDocumentView.from(v));
return (
- SelectionManager.Views} />
+ DocumentView.Selected()} />
)}
diff --git a/src/client/views/FieldsDropdown.tsx b/src/client/views/FieldsDropdown.tsx
index 3cb7848c2..0ea0ebd83 100644
--- a/src/client/views/FieldsDropdown.tsx
+++ b/src/client/views/FieldsDropdown.tsx
@@ -13,7 +13,7 @@ import Select from 'react-select';
import { Doc } from '../../fields/Doc';
import { DocOptions, FInfo } from '../documents/Documents';
import { SearchUtil } from '../util/SearchUtil';
-import { SettingsManager } from '../util/SettingsManager';
+import { SnappingManager } from '../util/SnappingManager';
import './FilterPanel.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
@@ -68,36 +68,36 @@ export class FieldsDropdown extends ObservableReactComponent ({
...baseStyles,
- color: SettingsManager.userColor,
- background: SettingsManager.userBackgroundColor,
+ color: SnappingManager.userColor,
+ background: SnappingManager.userBackgroundColor,
}),
placeholder: (baseStyles /* , state */) => ({
...baseStyles,
- color: SettingsManager.userColor,
- background: SettingsManager.userBackgroundColor,
+ color: SnappingManager.userColor,
+ background: SnappingManager.userBackgroundColor,
}),
input: (baseStyles /* , state */) => ({
...baseStyles,
padding: 0,
margin: 0,
- color: SettingsManager.userColor,
+ color: SnappingManager.userColor,
background: 'transparent',
}),
option: (baseStyles, state) => ({
...baseStyles,
- color: SettingsManager.userColor,
- background: !state.isFocused ? SettingsManager.userBackgroundColor : SettingsManager.userVariantColor,
+ color: SnappingManager.userColor,
+ background: !state.isFocused ? SnappingManager.userBackgroundColor : SnappingManager.userVariantColor,
}),
menuList: (baseStyles /* , state */) => ({
...baseStyles,
- backgroundColor: SettingsManager.userBackgroundColor,
+ backgroundColor: SnappingManager.userBackgroundColor,
}),
}}
placeholder={typeof this._props.placeholder === 'string' ? this._props.placeholder : this._props.placeholder?.()}
diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx
index ed9fc8dfb..c97edd7f0 100644
--- a/src/client/views/FilterPanel.tsx
+++ b/src/client/views/FilterPanel.tsx
@@ -11,12 +11,12 @@ import { Doc, DocListCast, Field, FieldType, LinkedTo, StrListCast } from '../..
import { Id } from '../../fields/FieldSymbols';
import { List } from '../../fields/List';
import { RichTextField } from '../../fields/RichTextField';
-import { DocumentManager } from '../util/DocumentManager';
import { SearchUtil } from '../util/SearchUtil';
-import { SettingsManager } from '../util/SettingsManager';
+import { SnappingManager } from '../util/SnappingManager';
import { undoable } from '../util/UndoManager';
import { FieldsDropdown } from './FieldsDropdown';
import './FilterPanel.scss';
+import { DocumentView } from './nodes/DocumentView';
import { Handle, Tick, TooltipRail, Track } from './nodes/SliderBox-components';
import { ObservableReactComponent } from './ObservableReactComponent';
@@ -40,7 +40,7 @@ export class FilterPanel extends ObservableReactComponent {
return this._props.Document;
}
@computed get targetDocChildKey() {
- const targetView = DocumentManager.Instance.getFirstDocumentView(this.Document);
+ const targetView = DocumentView.getFirstDocumentView(this.Document);
return targetView?.ComponentView?.annotationKey ?? targetView?.ComponentView?.fieldKey ?? 'data';
}
@computed get targetDocChildren() {
@@ -299,7 +299,7 @@ export class FilterPanel extends ObservableReactComponent {
.find(filter => filter.split(Doc.FilterSep)[0] === facetHeader)
?.split(Doc.FilterSep)[1]
}
- style={{ color: SettingsManager.userColor, background: SettingsManager.userBackgroundColor }}
+ style={{ color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}
onBlur={undoable(e => Doc.setDocFilter(this.Document, facetHeader, e.currentTarget.value, !e.currentTarget.value ? 'remove' : 'match'), 'set text filter')}
onKeyDown={e => e.key === 'Enter' && undoable(() => Doc.setDocFilter(this.Document, facetHeader, e.currentTarget.value, !e.currentTarget.value ? 'remove' : 'match'), 'set text filter')()}
/>
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 0d1573ea3..7246f0ba0 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -65,8 +65,6 @@ export class GestureOverlay extends ObservableReactComponent {
- GestureOverlay.DownDocView = undefined;
+ DocumentView.DownDocView = undefined;
if (this._points.length > 1) {
const B = this.svgBounds;
const points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top }));
@@ -388,7 +386,7 @@ export class GestureOverlay extends ObservableReactComponent KeyControlInfo;
export class KeyManager {
- public static Instance = new KeyManager();
+ // eslint-disable-next-line no-use-before-define
+ public static Instance: KeyManager;
private router = new Map();
constructor() {
+ KeyManager.Instance = this;
const isMac = navigator.platform.toLowerCase().indexOf('mac') >= 0;
// SHIFT CONTROL ALT META
@@ -46,6 +48,16 @@ export class KeyManager {
this.router.set(isMac ? '0100' : '0010', this.alt);
this.router.set(isMac ? '1001' : '1100', this.ctrl_shift);
this.router.set('1000', this.shift);
+
+ window.removeEventListener('keydown', KeyManager.Instance.handleModifiers, true);
+ window.addEventListener('keydown', KeyManager.Instance.handleModifiers, true);
+ window.removeEventListener('keyup', KeyManager.Instance.unhandleModifiers);
+ window.addEventListener('keyup', KeyManager.Instance.unhandleModifiers);
+ 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);
}
public unhandle = action((/* e: KeyboardEvent */) => {
@@ -89,8 +101,8 @@ export class KeyManager {
private handleGreedy = action((/* keyname: string */) => {});
nudge = (x: number, y: number, label: string) => {
- const nudgeable = SelectionManager.Views.some(dv => CollectionFreeFormDocumentView.from(dv)?.nudge);
- nudgeable && UndoManager.RunInBatch(() => SelectionManager.Views.map(dv => CollectionFreeFormDocumentView.from(dv)?.nudge(x, y)), label);
+ const nudgeable = DocumentView.Selected().some(dv => CollectionFreeFormDocumentView.from(dv)?.nudge);
+ nudgeable && UndoManager.RunInBatch(() => DocumentView.Selected().map(dv => CollectionFreeFormDocumentView.from(dv)?.nudge(x, y)), label);
return { stopPropagation: nudgeable, preventDefault: nudgeable };
};
@@ -98,16 +110,16 @@ export class KeyManager {
switch (keyname) {
case 'u':
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
- const ungroupings = SelectionManager.Views;
+ const ungroupings = DocumentView.Selected();
undoable(() => () => ungroupings.forEach(dv => { dv.layoutDoc.group = undefined; }), 'ungroup');
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
}
break;
case 'g':
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
- const selected = SelectionManager.Views;
+ const selected = DocumentView.Selected();
const cv = selected.reduce((col, dv) => (!col || CollectionFreeFormView.from(dv) === col ? CollectionFreeFormView.from(dv) : undefined), undefined as undefined | CollectionFreeFormView);
- cv && undoable(() => cv._marqueeViewRef.current?.collection(e, true, SelectionManager.Docs), 'grouping');
+ cv && undoable(() => cv._marqueeViewRef.current?.collection(e, true, DocumentView.SelectedDocs()), 'grouping');
}
break;
case ' ':
@@ -133,7 +145,7 @@ export class KeyManager {
doDeselect = !ContextMenu.Instance.closeMenu();
}
if (doDeselect) {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
LightboxView.Instance.SetLightboxDoc(undefined);
}
// DictationManager.Controls.stop();
@@ -153,7 +165,7 @@ export class KeyManager {
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
if (LightboxView.LightboxDoc) {
LightboxView.Instance.SetLightboxDoc(undefined);
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
} else if (!window.getSelection()?.toString()) DocumentDecorations.Instance.onCloseClick(true);
return { stopPropagation: true, preventDefault: true };
}
@@ -179,15 +191,15 @@ export class KeyManager {
case 'arrowdown': return this.nudge(0, 10, 'nudge down');
case 'u' :
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
- UndoManager.RunInBatch(() => SelectionManager.Docs.forEach(doc => {doc.group = undefined}), 'unggroup');
- SelectionManager.DeselectAll();
+ UndoManager.RunInBatch(() => DocumentView.Selected().map(dv => dv.Document).forEach(doc => {doc.group = undefined}), 'unggroup');
+ DocumentView.DeselectAll();
}
break;
case 'g':
if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
const randomGroup = random(0, 1000);
- UndoManager.RunInBatch(() => SelectionManager.Docs.forEach(doc => {doc.group = randomGroup}), 'group');
- SelectionManager.DeselectAll();
+ UndoManager.RunInBatch(() => DocumentView.Selected().forEach(dv => {dv.Document.group = randomGroup}), 'group');
+ DocumentView.DeselectAll();
}
break;
default:
@@ -206,7 +218,7 @@ export class KeyManager {
switch (keyname) {
case 'Æ’':
case 'f':
- UndoManager.RunInBatch(() => CollectionFreeFormDocumentView.from(SelectionManager.Views?.[0])?.float(), 'float');
+ UndoManager.RunInBatch(() => CollectionFreeFormDocumentView.from(DocumentView.Selected()?.[0])?.float(), 'float');
break;
default:
}
@@ -259,8 +271,8 @@ export class KeyManager {
}
break;
case 'f':
- if (SelectionManager.Views.length === 1 && SelectionManager.Views[0].ComponentView?.search) {
- SelectionManager.Views[0].ComponentView?.search?.('', false, false);
+ if (DocumentView.Selected().length === 1 && DocumentView.Selected()[0].ComponentView?.search) {
+ DocumentView.Selected()[0].ComponentView?.search?.('', false, false);
} else {
const searchBtn = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MySearcher);
if (searchBtn) {
@@ -279,14 +291,14 @@ export class KeyManager {
break;
case 'y':
if (Doc.ActivePage !== 'home') {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
UndoManager.Redo();
}
stopPropagation = false;
break;
case 'z':
if (Doc.ActivePage !== 'home') {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
UndoManager.Undo();
}
stopPropagation = false;
@@ -302,11 +314,17 @@ export class KeyManager {
preventDefault = false;
break;
case 'x':
- if (SelectionManager.Views.length) {
+ if (DocumentView.Selected().length) {
const bds = DocumentDecorations.Instance.Bounds;
- const pt = SelectionManager.Views[0].screenToViewTransform().transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2);
- const text = `__DashDocId(${pt?.[0] || 0},${pt?.[1] || 0}):` + SelectionManager.Views.map(dv => dv.Document[Id]).join(':');
- SelectionManager.Views.length && navigator.clipboard.writeText(text);
+ const pt = DocumentView.Selected()[0] //
+ .screenToViewTransform()
+ .transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2);
+ const text =
+ `__DashDocId(${pt?.[0] || 0},${pt?.[1] || 0}):` + //
+ DocumentView.Selected()
+ .map(dv => dv.Document[Id])
+ .join(':'); // prettier-ignore
+ DocumentView.Selected().length && navigator.clipboard.writeText(text);
DocumentDecorations.Instance.onCloseClick(true);
stopPropagation = false;
preventDefault = false;
@@ -315,9 +333,15 @@ export class KeyManager {
case 'c':
if ((document.activeElement as any)?.type !== 'text' && !AnchorMenu.Instance.Active && DocumentDecorations.Instance.Bounds.r - DocumentDecorations.Instance.Bounds.x > 2) {
const bds = DocumentDecorations.Instance.Bounds;
- const pt = SelectionManager.Views[0].screenToViewTransform().transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2);
- const text = `__DashCloneId(${pt?.[0] || 0},${pt?.[1] || 0}):` + SelectionManager.Views.map(dv => dv.Document[Id]).join(':');
- SelectionManager.Views.length && navigator.clipboard.writeText(text);
+ const pt = DocumentView.Selected()[0]
+ .screenToViewTransform()
+ .transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2); // prettier-ignore
+ const text =
+ `__DashCloneId(${pt?.[0] || 0},${pt?.[1] || 0}):` +
+ DocumentView.SelectedDocs()
+ .map(doc => doc[Id])
+ .join(':'); // prettier-ignore
+ DocumentView.Selected().length && navigator.clipboard.writeText(text);
stopPropagation = false;
}
preventDefault = false;
@@ -336,7 +360,7 @@ export class KeyManager {
if (!plain) return;
const clone = plain.startsWith('__DashCloneId(');
const docids = plain.split(':'); // hack! docids[0] is the top left of the selection rectangle
- const addDocument = SelectionManager.Views.lastElement()?.ComponentView?.addDocument;
+ const addDocument = DocumentView.Selected().lastElement()?.ComponentView?.addDocument;
if (addDocument && (plain.startsWith('__DashDocId(') || clone)) {
Doc.Paste(docids.slice(1), clone, addDocument);
}
diff --git a/src/client/views/InkControlPtHandles.tsx b/src/client/views/InkControlPtHandles.tsx
index b4fe44733..a49923ffb 100644
--- a/src/client/views/InkControlPtHandles.tsx
+++ b/src/client/views/InkControlPtHandles.tsx
@@ -7,7 +7,6 @@ import { List } from '../../fields/List';
import { listSpec } from '../../fields/Schema';
import { Cast } from '../../fields/Types';
import { returnFalse, setupMoveUpEvents } from '../../ClientUtils';
-import { SelectionManager } from '../util/SelectionManager';
import { UndoManager } from '../util/UndoManager';
import { Colors } from './global/globalEnums';
import { InkingStroke } from './InkingStroke';
@@ -15,6 +14,7 @@ import { InkStrokeProperties } from './InkStrokeProperties';
import { SnappingManager } from '../util/SnappingManager';
import { ObservableReactComponent } from './ObservableReactComponent';
import { PointData } from '../../pen-gestures/GestureTypes';
+import { DocumentView } from './nodes/DocumentView';
export interface InkControlProps {
inkDoc: Doc;
@@ -224,8 +224,8 @@ export class InkEndPtHandles extends ObservableReactComponent {
const v1n = { X: v1.X / v1len, Y: v1.Y / v1len };
const v2n = { X: v2.X / v2len, Y: v2.Y / v2len };
const angle = Math.acos(v1n.X * v2n.X + v1n.Y * v2n.Y) * Math.sign(v1.X * v2.Y - v2.X * v1.Y);
- InkStrokeProperties.Instance.stretchInk(SelectionManager.Views, scaling, p2, v1n, moveEv.shiftKey);
- InkStrokeProperties.Instance.rotateInk(SelectionManager.Views, angle, pt2()); // bcz: call pt2() func here because pt2 will have changed from previous stretchInk call
+ InkStrokeProperties.Instance.stretchInk(DocumentView.Selected(), scaling, p2, v1n, moveEv.shiftKey);
+ InkStrokeProperties.Instance.rotateInk(DocumentView.Selected(), angle, pt2()); // bcz: call pt2() func here because pt2 will have changed from previous stretchInk call
return false;
}),
action(() => {
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts
index 109a9cad4..3920ecc2a 100644
--- a/src/client/views/InkStrokeProperties.ts
+++ b/src/client/views/InkStrokeProperties.ts
@@ -9,7 +9,6 @@ import { Cast, NumCast } from '../../fields/Types';
import { PointData } from '../../pen-gestures/GestureTypes';
import { Point } from '../../pen-gestures/ndollar';
import { DocumentType } from '../documents/DocumentTypes';
-import { DocumentManager } from '../util/DocumentManager';
import { undoBatch } from '../util/UndoManager';
import { FitOneCurve } from '../util/bezierFit';
import { InkingStroke } from './InkingStroke';
@@ -386,7 +385,7 @@ export class InkStrokeProperties {
containingCollection?.childDocs
.filter(doc => doc.type === DocumentType.INK)
.forEach(doc => {
- const testInkView = DocumentManager.Instance.getDocumentView(doc, containingDocView);
+ const testInkView = DocumentView.getDocumentView(doc, containingDocView);
const snapped = testInkView?.ComponentView?.snapPt?.(screenDragPt, doc === inkView.Document ? this.excludeSelfSnapSegs(ink, controlIndex) : []);
if (snapped && snapped.distance < snapData.distance) {
const snappedInkPt = doc === inkView.Document ? snapped.nearestPt : inkView.ComponentView?.ptFromScreen?.(testInkView?.ComponentView?.ptToScreen?.(snapped.nearestPt) ?? { X: 0, Y: 0 }); // convert from snapped ink coordinate system to dragged ink coordinate system by converting to/from screen space
diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx
index 7e2b334af..1ed8de1be 100644
--- a/src/client/views/InkTranscription.tsx
+++ b/src/client/views/InkTranscription.tsx
@@ -6,7 +6,6 @@
// import { Cast, DateCast, NumCast } from '../../fields/Types';
// import { aggregateBounds } from '../../Utils';
// import { DocumentType } from '../documents/DocumentTypes';
-// import { DocumentManager } from '../util/DocumentManager';
// import { CollectionFreeFormView } from './collections/collectionFreeForm';
// import { InkingStroke } from './InkingStroke';
// import './InkTranscription.scss';
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 884512539..62fc73c78 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -44,7 +44,7 @@ import { InkTangentHandles } from './InkTangentHandles';
import { FieldView, FieldViewProps } from './nodes/FieldView';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { PinDocView, PinProps } from './PinFuncs';
-import { StyleProp } from './StyleProvider';
+import { StyleProp } from './StyleProp';
const { INK_MASK_SIZE } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 020525ef8..12d899388 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -13,10 +13,6 @@ import { CreateLinkToActiveAudio, Doc, DocListCast, FieldResult, Opt } from '../
import { Id } from '../../fields/FieldSymbols';
import { InkTool } from '../../fields/InkField';
import { Cast, NumCast, toList } from '../../fields/Types';
-import { DocumentManager } from '../util/DocumentManager';
-import { LinkManager } from '../util/LinkManager';
-import { SelectionManager } from '../util/SelectionManager';
-import { SettingsManager } from '../util/SettingsManager';
import { SnappingManager } from '../util/SnappingManager';
import { Transform } from '../util/Transform';
import { GestureOverlay } from './GestureOverlay';
@@ -24,8 +20,6 @@ import './LightboxView.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider';
import { CollectionDockingView } from './collections/CollectionDockingView';
-import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
-import { TabDocView } from './collections/TabDocView';
import { DocumentView } from './nodes/DocumentView';
import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere';
@@ -90,7 +84,7 @@ export class LightboxView extends ObservableReactComponent {
});
const l = CreateLinkToActiveAudio(() => doc).lastElement();
l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
- CollectionStackedTimeline.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.());
+ DocumentView.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.());
this._history.push({ doc, target });
} else {
this._future = [];
@@ -98,14 +92,14 @@ export class LightboxView extends ObservableReactComponent {
Doc.ActiveTool = InkTool.None;
SnappingManager.SetExploreMode(false);
}
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
if (future) {
this._future.push(
...(this._doc ? [this._doc] : []),
...future
.slice()
.sort((a, b) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow))
- .sort((a, b) => LinkManager.Links(a).length - LinkManager.Links(b).length)
+ .sort((a, b) => Doc.Links(a).length - Doc.Links(b).length)
);
}
this._doc = doc;
@@ -134,11 +128,11 @@ export class LightboxView extends ObservableReactComponent {
const lightDoc = this._doc;
if (!lightDoc) return;
const target = (this._docTarget = this._future.pop());
- const targetDocView = target && DocumentManager.Instance.getLightboxDocumentView(target);
+ const targetDocView = target && DocumentView.getLightboxDocumentView(target);
if (targetDocView && target) {
const l = CreateLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.(true) || target).lastElement();
l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
- DocumentManager.Instance.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
+ DocumentView.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
if (this._history.lastElement().target !== target) this._history.push({ doc: lightDoc, target });
} else if (!target && this._path.length) {
savedKeys.forEach(key => {
@@ -157,10 +151,10 @@ export class LightboxView extends ObservableReactComponent {
return;
}
const { doc, target } = this._history.lastElement();
- const docView = DocumentManager.Instance.getLightboxDocumentView(target || doc);
+ const docView = DocumentView.getLightboxDocumentView(target || doc);
if (docView) {
this._docTarget = target;
- target && DocumentManager.Instance.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
+ target && DocumentView.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
} else {
this.SetLightboxDoc(doc, target);
}
@@ -178,8 +172,8 @@ export class LightboxView extends ObservableReactComponent {
if (this._docTarget) {
const fieldKey = Doc.LayoutFieldKey(this._docTarget);
const contents = [...DocListCast(this._docTarget[fieldKey]), ...DocListCast(this._docTarget[fieldKey + '_annotations'])];
- const links = LinkManager.Links(this._docTarget)
- .map(link => LinkManager.getOppositeAnchor(link, this._docTarget!)!)
+ const links = Doc.Links(this._docTarget)
+ .map(link => Doc.getOppositeAnchor(link, this._docTarget!)!)
.filter(doc => doc);
this.SetLightboxDoc(this._docTarget, undefined, contents.length ? contents : links);
}
@@ -220,7 +214,7 @@ export class LightboxView extends ObservableReactComponent {
{
e.stopPropagation();
click();
@@ -237,8 +231,8 @@ export class LightboxView extends ObservableReactComponent
{
}
@@ -252,7 +246,7 @@ export class LightboxView extends ObservableReactComponent
{
return !this._doc ? null : (
{
downx = e.clientX;
downy = e.clientY;
@@ -266,7 +260,7 @@ export class LightboxView extends ObservableReactComponent
{
width: this.lightboxWidth(),
height: this.lightboxHeight(),
clipPath: `path('${Doc.UserDoc().renderStyle === 'comic' ? wavyBorderPath(this.lightboxWidth(), this.lightboxHeight()) : undefined}')`,
- background: SettingsManager.userBackgroundColor,
+ background: SnappingManager.userBackgroundColor,
}}>
{
removeDocument={undefined}
whenChildContentsActiveChanged={emptyFunction}
addDocTab={this.AddDocTab}
- pinToPres={TabDocView.PinDoc}
+ pinToPres={DocumentView.PinDoc}
focus={emptyFunction}
/>
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 01f3b032e..b6dfed687 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -8,14 +8,17 @@ import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import { AssignAllExtensions } from '../../extensions/Extensions';
import { FieldLoader } from '../../fields/FieldLoader';
+import { BranchingTrailManager } from '../util/BranchingTrailManager';
import { CurrentUserUtils } from '../util/CurrentUserUtils';
import { PingManager } from '../util/PingManager';
import { ReplayMovements } from '../util/ReplayMovements';
import { TrackMovements } from '../util/TrackMovements';
+import { KeyManager } from './GlobalKeyHandler';
+import { MainView } from './MainView';
import { CollectionView } from './collections/CollectionView';
+import { CollectionFreeFormInfoUI } from './collections/collectionFreeForm/CollectionFreeFormInfoUI';
import './global/globalScripts';
-import { MainView } from './MainView';
-import { BranchingTrailManager } from '../util/BranchingTrailManager';
+import { LinkFollower } from '../util/LinkFollower';
dotenv.config();
@@ -58,6 +61,11 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' };
new ReplayMovements();
new BranchingTrailManager({});
new PingManager();
+ new KeyManager();
+
+ // iniitialize plugin apis
+ CollectionFreeFormInfoUI.Init();
+ LinkFollower.Init();
root.render();
}, 0);
})();
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index aec553baa..2c7d3d32a 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -12,7 +12,8 @@ import '../../../node_modules/browndash-components/dist/styles/global.min.css';
import { ClientUtils, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../ClientUtils';
import { emptyFunction } from '../../Utils';
import { Doc, DocListCast, GetDocFromUrl, Opt } from '../../fields/Doc';
-import { DocData } from '../../fields/DocSymbols';
+import { DocData, DocViews } from '../../fields/DocSymbols';
+import { Id } from '../../fields/FieldSymbols';
import { DocCast, StrCast, toList } from '../../fields/Types';
import { DocServer } from '../DocServer';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
@@ -29,7 +30,6 @@ 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';
import { ServerStats } from '../util/ServerStats';
import { SettingsManager } from '../util/SettingsManager';
import { SharingManager } from '../util/SharingManager';
@@ -42,7 +42,6 @@ import { DashboardView } from './DashboardView';
import { DictationOverlay } from './DictationOverlay';
import { DocumentDecorations } from './DocumentDecorations';
import { GestureOverlay } from './GestureOverlay';
-import { KeyManager } from './GlobalKeyHandler';
import { LightboxView } from './LightboxView';
import './MainView.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
@@ -160,7 +159,7 @@ export class MainView extends ObservableReactComponent<{}> {
leftMenuHeight = () => this._dashUIHeight;
leftMenuFlyoutWidth = () => this._leftMenuFlyoutWidth;
leftMenuFlyoutHeight = () => this._dashUIHeight;
- propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, SettingsManager.Instance?.propertiesWidth || 0));
+ propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, SnappingManager.PropertiesWidth || 0));
propertiesHeight = () => this._dashUIHeight;
mainDocViewWidth = () => this._dashUIWidth - this.propertiesWidth() - this.leftMenuWidth() - this.leftMenuFlyoutWidth();
mainDocViewHeight = () => this._dashUIHeight - this.headerBarDocHeight();
@@ -169,7 +168,7 @@ export class MainView extends ObservableReactComponent<{}> {
// 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(),
+ () => DocumentView.Selected().slice(),
views => views.length > 1 && (document.activeElement as any)?.blur !== undefined && (document.activeElement as any)!.blur()
);
const scriptTag = document.createElement('script');
@@ -231,37 +230,29 @@ export class MainView extends ObservableReactComponent<{}> {
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag);
- window.removeEventListener('keydown', KeyManager.Instance.handleModifiers, true);
- window.addEventListener('keydown', KeyManager.Instance.handleModifiers, true);
- window.removeEventListener('keyup', KeyManager.Instance.unhandleModifiers);
- window.addEventListener('keyup', KeyManager.Instance.unhandleModifiers);
- 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 = GetDocFromUrl(e.detail);
- DocServer.GetRefField(id).then(doc => (doc instanceof Doc ? DocumentManager.Instance.showDocument(doc, { willPan: false }) : null));
+ DocServer.GetRefField(id).then(doc => (doc instanceof Doc ? DocumentView.showDocument(doc, { willPan: false }) : 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, true);
- window.removeEventListener('pointermove', this.globalPointerMove, true);
- window.removeEventListener('pointerup', this.globalPointerClick, true);
- window.removeEventListener('paste', KeyManager.Instance.paste as any);
- document.removeEventListener('linkAnnotationToDash', Hypothesis.linkListener);
+ // window.removeEventListener('keyup', KeyManager.Instance.unhandle);
+ // window.removeEventListener('keydown', KeyManager.Instance.handle);
+ // window.removeEventListener('pointerdown', this.globalPointerDown, true);
+ // window.removeEventListener('pointermove', this.globalPointerMove, true);
+ // window.removeEventListener('pointerup', this.globalPointerClick, true);
+ // window.removeEventListener('paste', KeyManager.Instance.paste as any);
+ // document.removeEventListener('linkAnnotationToDash', Hypothesis.linkListener);
}
constructor(props: any) {
super(props);
makeObservable(this);
+ CollectionDockingView.setTabJSXComponent(TabDocView);
DocumentViewInternal.addDocTabFunc = MainView.addDocTabFunc_impl;
MainView.Instance = this;
DashboardView._urlState = HistoryUtil.parseUrl(window.location) || ({} as any);
@@ -592,7 +583,7 @@ export class MainView extends ObservableReactComponent<{}> {
if (!e.cancelBubble) {
const pathstr = (e as any)?.path?.map((p: any) => p.classList?.toString()).join();
if (pathstr?.includes('libraryFlyout')) {
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
}
}
},
@@ -719,14 +710,14 @@ export class MainView extends ObservableReactComponent<{}> {
this,
e,
action(() => {
- SettingsManager.Instance.propertiesWidth = Math.max(0, this._dashUIWidth - e.clientX);
- return !SettingsManager.Instance.propertiesWidth;
+ SnappingManager.SetPropertiesWidth(Math.max(0, this._dashUIWidth - e.clientX));
+ return !SnappingManager.PropertiesWidth;
}),
action(() => {
- SettingsManager.Instance.propertiesWidth < 5 && (SettingsManager.Instance.propertiesWidth = 0);
+ SnappingManager.PropertiesWidth < 5 && SnappingManager.SetPropertiesWidth(0);
}),
action(() => {
- SettingsManager.Instance.propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._dashUIWidth - 50, 250) : 0;
+ SnappingManager.SetPropertiesWidth(this.propertiesWidth() < 15 ? Math.min(this._dashUIWidth - 50, 250) : 0);
}),
false
);
@@ -776,7 +767,7 @@ export class MainView extends ObservableReactComponent<{}> {
Document={this._sidebarContent.proto || this._sidebarContent}
addDocument={undefined}
addDocTab={DocumentViewInternal.addDocTabFunc}
- pinToPres={TabDocView.PinDoc}
+ pinToPres={DocumentView.PinDoc}
containerViewPath={returnEmptyDoclist}
styleProvider={this._sidebarContent.proto === Doc.MyDashboards || this._sidebarContent.proto === Doc.MyFilesystem || this._sidebarContent.proto === Doc.MyTrails ? DashboardStyleProvider : DefaultStyleProvider}
removeDocument={returnFalse}
@@ -799,7 +790,7 @@ export class MainView extends ObservableReactComponent<{}> {
@computed get leftMenuPanel() {
return (
-
+
{
{this.flyout}
-
+
{this.dockingContent}
@@ -864,11 +855,11 @@ export class MainView extends ObservableReactComponent<{}> {
className={`mainView-propertiesDragger${this.propertiesWidth() < 10 ? '-minified' : ''}`}
key="props"
onPointerDown={this.onPropertiesPointerDown}
- style={{ background: SettingsManager.userVariantColor, right: this.propertiesWidth() - 1 }}>
-
+ style={{ background: SnappingManager.userVariantColor, right: this.propertiesWidth() - 1 }}>
+
)}
-
+
@@ -911,11 +902,11 @@ export class MainView extends ObservableReactComponent<{}> {
// setTimeout(action(() => (this._leftMenuFlyoutWidth += 0.5)));
this._sidebarContent.proto = DocCast(button.target);
- SettingsManager.Instance.LastPressedBtn = button;
+ SnappingManager.SetLastPressedBtn(button[Id]);
});
closeFlyout = action(() => {
- SettingsManager.Instance.LastPressedBtn = undefined;
+ SnappingManager.SetLastPressedBtn('');
this._panelContent = 'none';
this._sidebarContent.proto = undefined;
this._leftMenuFlyoutWidth = 0;
@@ -933,7 +924,7 @@ export class MainView extends ObservableReactComponent<{}> {
@computed get docButtons() {
return !Doc.MyDockedBtns ? null : (
-
+
{
);
}
@computed get snapLines() {
- const dragged = DragManager.docsBeingDragged.lastElement() ?? SelectionManager.Docs.lastElement();
- const dragPar = dragged ? CollectionFreeFormView.from(DocumentManager.Instance.getDocumentView(dragged)) : undefined;
+ const dragged = DragManager.docsBeingDragged.lastElement() ?? DocumentView.SelectedDocs().lastElement();
+ const dragPar = dragged ? CollectionFreeFormView.from(Array.from(dragged[DocViews]).lastElement()) : undefined;
return !dragPar?.layoutDoc.freeform_snapLines ? null : (