From b1376d401e709515cee078cc08b05fd3fb89caeb Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 24 Apr 2024 18:12:30 -0400 Subject: completing eslint pass --- src/client/util/GroupMemberView.tsx | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'src/client/util/GroupMemberView.tsx') diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx index 894583711..c703c3f98 100644 --- a/src/client/util/GroupMemberView.tsx +++ b/src/client/util/GroupMemberView.tsx @@ -1,4 +1,7 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Button, IconButton, Size, Type } from 'browndash-components'; import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -8,7 +11,6 @@ import { StrCast } from '../../fields/Types'; import { MainViewModal } from '../views/MainViewModal'; import { GroupManager, UserOptions } from './GroupManager'; import './GroupMemberView.scss'; -import { Button, IconButton, Size, Type } from 'browndash-components'; import { SettingsManager } from './SettingsManager'; interface GroupMemberViewProps { @@ -38,20 +40,23 @@ export class GroupMemberView extends React.Component { className="group-title" style={{ marginLeft: !hasEditAccess ? '-14%' : 0 }} value={StrCast(this.group.title || this.group.groupName)} - onChange={e => (this.group.title = e.currentTarget.value)} - disabled={!hasEditAccess}> -
-
{GroupManager.Instance.hasEditAccess(this.group) ? (
containerDocContext.length && (dv.ComponentView as PresBox).PlayTrail(containerDocContext))) { - PresBox.OpenPresMinimized(target, [0, 0]); + if (!DocumentManager.Instance.AddViewRenderedCb(target, dv => containerDocContext.length && dv.ComponentView?.playTrail?.(containerDocContext))) { + alert('OPEN Pres minimized'); + // PresBox.OpenPresMinimized(target, [0, 0]); } finished?.(); } else { @@ -138,9 +137,6 @@ ScriptingGlobals.add(function followLink(doc: Doc, altKey: boolean) { return LinkFollower.FollowLink(undefined, doc, altKey) ? undefined : { select: true }; }); -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('); } diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx index 05fb849fd..248fda7e3 100644 --- a/src/client/util/RTFMarkup.tsx +++ b/src/client/util/RTFMarkup.tsx @@ -2,7 +2,7 @@ import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { MainViewModal } from '../views/MainViewModal'; -import { SettingsManager } from './SettingsManager'; +import { SnappingManager } from './SnappingManager'; @observer export class RTFMarkup extends React.Component<{}> { @@ -10,6 +10,10 @@ export class RTFMarkup extends React.Component<{}> { static Instance: RTFMarkup; @observable private isOpen = false; // whether the SharingManager modal is open or not + public setOpen = action((status: boolean) => { + this.isOpen = status; + }); + constructor(props: {}) { super(props); makeObservable(this); @@ -21,7 +25,7 @@ export class RTFMarkup extends React.Component<{}> { */ @computed get cheatSheet() { return ( -
+

(@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-')}

-
-
{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.dataDoc.hintDialogueOpen = false)}> + (this.dataDoc.hintDialogueOpen = false)}> Hints {this.selectedQuestion.hints?.map((hint: any, index: number) => ( @@ -1030,12 +1041,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent )} {this.selectedQuestion.answerParts.includes('angle of gravity') && ( @@ -1045,13 +1056,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent )} {this.selectedQuestion.answerParts.includes('normal force') && ( @@ -1061,12 +1072,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent )} {this.selectedQuestion.answerParts.includes('angle of normal force') && ( @@ -1076,13 +1087,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent )} {this.selectedQuestion.answerParts.includes('force of static friction') && ( @@ -1092,12 +1103,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent )} {this.selectedQuestion.answerParts.includes('angle of static friction') && ( @@ -1107,13 +1118,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent )} {this.selectedQuestion.answerParts.includes('coefficient of static friction') && ( @@ -1127,7 +1138,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { this.changeWedgeBasedOnNewAngle(val); this.updateReviewForcesBasedOnAngle(val); }} - radianEquivalent={true} + radianEquivalent showIcon={BoolCast(this.dataDoc.simulation_showIcon)} correctValue={NumListCast(this.dataDoc.answers)[this.selectedQuestion.answerParts.indexOf('wedge angle')]} /> @@ -1158,7 +1169,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)} - {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' && ( - + @@ -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.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.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.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.simulation_paused && this.simulationType !== 'Inclined Plane' && this.simulationType !== 'Circular Motion' && this.simulationType !== 'Pulley' && ( @@ -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')) && ( )}{' '} - {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.simulation_paused || this.simulationType != 'One Weight') && ( - - )}{' '} - {this.dataDoc.simulation_paused && this.simulationType == 'One Weight' && ( + {(!this.dataDoc.simulation_paused || this.simulationType !== 'One Weight') && }{' '} + {this.dataDoc.simulation_paused && this.simulationType === 'One Weight' && ( @@ -1822,14 +1827,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponentAcceleration @@ -1842,7 +1843,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
{this.simulationType == 'Pulley' ? 'Red Weight' : ''}{this.simulationType === 'Pulley' ? 'Red Weight' : ''} X Y
- <>{this.dataDoc.mass1_positionX} m - {this.dataDoc.mass1_positionX + ''} m { 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 {`${NumCast(this.dataDoc.mass1_positionY)} m`} { 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 {`${NumCast(this.dataDoc.mass1_velocityX)} m/s`} { this.dataDoc.mass1_velocityXstart = value; this._simReset++; })} - small={true} + small mode="Freeform" /> - <>{this.dataDoc.mass1_velocityY} m/s - {this.dataDoc.mass1_velocityY + ''} m/s { this.dataDoc.mass1_velocityYstart = -value; }} - small={true} + small mode="Freeform" /> - <> - {this.dataDoc.mass1_accelerationX} m/s2 - + {this.dataDoc.mass1_accelerationX + ''} m/s2 - <> - {this.dataDoc.mass1_accelerationY} m/s2 - + {this.dataDoc.mass1_accelerationY + ''} m/s2
)} - {this.simulationMode == 'Freeform' && this.simulationType == 'Pulley' && ( + {this.simulationMode === 'Freeform' && this.simulationType === 'Pulley' && ( @@ -1869,14 +1870,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponentAcceleration @@ -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

- <> - {this.dataDoc.mass2_accelerationX} m/s2 - + {this.dataDoc.mass2_accelerationX + ''} m/s2 - <> - {this.dataDoc.mass2_accelerationY} m/s2 - + {this.dataDoc.mass2_accelerationY + ''} m/s2