From 380ee1acac1c0b7972d7d423cf804af146dc0edf Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 10 Dec 2023 20:19:27 -0500 Subject: massive changes to use mobx 6 which means not accessing props directly in @computed functions. --- src/client/views/nodes/audio/AudioWaveform.scss | 17 ++++ src/client/views/nodes/audio/AudioWaveform.tsx | 127 ++++++++++++++++++++++++ src/client/views/nodes/audio/WaveCanvas.tsx | 100 +++++++++++++++++++ 3 files changed, 244 insertions(+) create mode 100644 src/client/views/nodes/audio/AudioWaveform.scss create mode 100644 src/client/views/nodes/audio/AudioWaveform.tsx create mode 100644 src/client/views/nodes/audio/WaveCanvas.tsx (limited to 'src/client/views/nodes/audio') diff --git a/src/client/views/nodes/audio/AudioWaveform.scss b/src/client/views/nodes/audio/AudioWaveform.scss new file mode 100644 index 000000000..6cbd1759a --- /dev/null +++ b/src/client/views/nodes/audio/AudioWaveform.scss @@ -0,0 +1,17 @@ +.audioWaveform { + position: relative; + width: 100%; + height: 200%; + overflow: hidden; + z-index: -1000; + bottom: 0; + pointer-events: none; + div { + height: 100% !important; + width: 100% !important; + } + canvas { + height: 100% !important; + width: 100% !important; + } +} diff --git a/src/client/views/nodes/audio/AudioWaveform.tsx b/src/client/views/nodes/audio/AudioWaveform.tsx new file mode 100644 index 000000000..1b1a85800 --- /dev/null +++ b/src/client/views/nodes/audio/AudioWaveform.tsx @@ -0,0 +1,127 @@ +import axios from 'axios'; +import { computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { Doc, NumListCast } from '../../../../fields/Doc'; +import { List } from '../../../../fields/List'; +import { listSpec } from '../../../../fields/Schema'; +import { Cast } from '../../../../fields/Types'; +import { copyProps, numberRange } from '../../../../Utils'; +import { Colors } from './../../global/globalEnums'; +import './AudioWaveform.scss'; +import { WaveCanvas } from './WaveCanvas'; + +/** + * AudioWaveform + * + * Used in CollectionStackedTimeline to render a canvas with a visual of an audio waveform for AudioBox and VideoBox documents. + * Uses react-audio-waveform package. + * Bins the audio data into audioBuckets which are passed to package to render the lines. + * Calculates new buckets each time a new zoom factor or new set of trim bounds is created and stores it in a field on the layout doc with a title indicating the bounds and zoom for that list (see audioBucketField) + */ + +export interface AudioWaveformProps { + duration: number; // length of media clip + rawDuration: number; // length of underlying media data + mediaPath: string; + layoutDoc: Doc; + clipStart: number; + clipEnd: number; + zoomFactor: number; + PanelHeight: number; + PanelWidth: number; + fieldKey: string; + progress?: number; +} + +@observer +export class AudioWaveform extends React.Component { + public static NUMBER_OF_BUCKETS = 100; // number of buckets data is divided into to draw waveform lines + _disposer: IReactionDisposer | undefined; + _prevProps: React.PropsWithChildren; + @observable _props: React.PropsWithChildren; + constructor(props: React.PropsWithChildren) { + super(props); + this._props = this._prevProps = props; + makeObservable(this); + } + + componentDidUpdate() { + copyProps(this); + } + + get waveHeight() { + return Math.max(50, this._props.PanelHeight); + } + + get clipStart() { + return this._props.clipStart; + } + get clipEnd() { + return this._props.clipEnd; + } + get zoomFactor() { + return this._props.zoomFactor; + } + + @computed get audioBuckets() { + return NumListCast(this._props.layoutDoc[this.audioBucketField(this.clipStart, this.clipEnd, this.zoomFactor)]); + } + + audioBucketField = (start: number, end: number, zoomFactor: number) => this._props.fieldKey + '_audioBuckets/' + '/' + start.toFixed(2).replace('.', '_') + '/' + end.toFixed(2).replace('.', '_') + '/' + zoomFactor * 10; + + componentWillUnmount() { + this._disposer?.(); + } + + componentDidMount() { + this._disposer = reaction( + () => ({ clipStart: this.clipStart, clipEnd: this.clipEnd, fieldKey: this.audioBucketField(this.clipStart, this.clipEnd, this.zoomFactor), zoomFactor: this._props.zoomFactor }), + ({ clipStart, clipEnd, fieldKey, zoomFactor }) => { + if (!this._props.layoutDoc[fieldKey] && this._props.layoutDoc.layout_fieldKey != 'layout_icon') { + // setting these values here serves as a "lock" to prevent multiple attempts to create the waveform at nerly the same time. + const waveform = Cast(this._props.layoutDoc[this.audioBucketField(0, this._props.rawDuration, 1)], listSpec('number')); + this._props.layoutDoc[fieldKey] = waveform && new List(waveform.slice((clipStart / this._props.rawDuration) * waveform.length, (clipEnd / this._props.rawDuration) * waveform.length)); + setTimeout(() => this.createWaveformBuckets(fieldKey, clipStart, clipEnd, zoomFactor)); + } + }, + { fireImmediately: true } + ); + } + + // decodes the audio file into peaks for generating the waveform + createWaveformBuckets = (fieldKey: string, clipStart: number, clipEnd: number, zoomFactor: number) => { + axios({ url: this._props.mediaPath, responseType: 'arraybuffer' }).then(response => + new window.AudioContext().decodeAudioData(response.data, buffer => { + const rawDecodedAudioData = buffer.getChannelData(0); + const startInd = clipStart / this._props.rawDuration; + const endInd = clipEnd / this._props.rawDuration; + const decodedAudioData = rawDecodedAudioData.slice(Math.floor(startInd * rawDecodedAudioData.length), Math.floor(endInd * rawDecodedAudioData.length)); + const numBuckets = Math.floor(AudioWaveform.NUMBER_OF_BUCKETS * zoomFactor); + + const bucketDataSize = Math.floor(decodedAudioData.length / numBuckets); + const brange = Array.from(Array(bucketDataSize)); + const bucketList = numberRange(numBuckets).map((i: number) => brange.reduce((p, x, j) => Math.abs(Math.max(p, decodedAudioData[i * bucketDataSize + j])), 0) / 2); + this._props.layoutDoc[fieldKey] = new List(bucketList); + }) + ); + }; + + render() { + return ( +
+ +
+ ); + } +} diff --git a/src/client/views/nodes/audio/WaveCanvas.tsx b/src/client/views/nodes/audio/WaveCanvas.tsx new file mode 100644 index 000000000..d3f5669a2 --- /dev/null +++ b/src/client/views/nodes/audio/WaveCanvas.tsx @@ -0,0 +1,100 @@ +import React from 'react'; + +interface WaveCanvasProps { + barWidth: number; + color: string; + progress: number; + progressColor: string; + gradientColors?: { stopPosition: number; color: string }[]; // stopPosition between 0 and 1 + peaks: number[]; + width: number; + height: number; + pixelRatio: number; +} + +export class WaveCanvas extends React.Component { + // If the first value of peaks is negative, addToIndices will be 1 + posPeaks = (peaks: number[], addToIndices: number) => peaks.filter((_, index) => (index + addToIndices) % 2 == 0); + + drawBars = (waveCanvasCtx: CanvasRenderingContext2D, width: number, halfH: number, peaks: number[]) => { + // Bar wave draws the bottom only as a reflection of the top, + // so we don't need negative values + const posPeaks = peaks.some(val => val < 0) ? this.posPeaks(peaks, peaks[0] < 0 ? 1 : 0) : peaks; + + // A half-pixel offset makes lines crisp + const $ = 0.5 / this.props.pixelRatio; + const bar = this.props.barWidth * this.props.pixelRatio; + const gap = Math.max(this.props.pixelRatio, 2); + + const max = Math.max(...posPeaks); + const scale = posPeaks.length / width; + + for (let i = 0; i < width; i += bar + gap) { + if (i > width * this.props.progress) waveCanvasCtx.fillStyle = this.props.color; + + const h = Math.round((posPeaks[Math.floor(i * scale)] / max) * halfH) || 1; + + waveCanvasCtx.fillRect(i + $, halfH - h, bar + $, h * 2); + } + }; + + addNegPeaks = (peaks: number[]) => + peaks.reduce((reflectedPeaks, peak) => reflectedPeaks.push(peak, -peak) ? reflectedPeaks:[], + [] as number[]); // prettier-ignore + + drawWaves = (waveCanvasCtx: CanvasRenderingContext2D, width: number, halfH: number, peaks: number[]) => { + const allPeaks = peaks.some(val => val < 0) ? peaks : this.addNegPeaks(peaks); // add negative peaks to arrays without negative peaks + + // A half-pixel offset makes lines crisp + const $ = 0.5 / this.props.pixelRatio; + const length = ~~(allPeaks.length / 2); // ~~ is Math.floor for positive numbers. + + const scale = width / length; + const absmax = Math.max(...allPeaks.map(peak => Math.abs(peak))); + + waveCanvasCtx.beginPath(); + waveCanvasCtx.moveTo($, halfH); + + for (var i = 0; i < length; i++) { + var h = Math.round((allPeaks[2 * i] / absmax) * halfH); + waveCanvasCtx.lineTo(i * scale + $, halfH - h); + } + + // Draw the bottom edge going backwards, to make a single closed hull to fill. + for (var i = length - 1; i >= 0; i--) { + var h = Math.round((allPeaks[2 * i + 1] / absmax) * halfH); + waveCanvasCtx.lineTo(i * scale + $, halfH - h); + } + + waveCanvasCtx.fill(); + + // Always draw a median line + waveCanvasCtx.fillRect(0, halfH - $, width, $); + }; + + updateSize = (width: number, height: number, peaks: number[], waveCanvasCtx: CanvasRenderingContext2D) => { + const displayWidth = Math.round(width / this.props.pixelRatio); + const displayHeight = Math.round(height / this.props.pixelRatio); + waveCanvasCtx.canvas.width = width; + waveCanvasCtx.canvas.height = height; + waveCanvasCtx.canvas.style.width = `${displayWidth}px`; + waveCanvasCtx.canvas.style.height = `${displayHeight}px`; + + waveCanvasCtx.clearRect(0, 0, width, height); + + const gradient = this.props.gradientColors && waveCanvasCtx.createLinearGradient(0, 0, width, 0); + gradient && this.props.gradientColors?.forEach(color => gradient.addColorStop(color.stopPosition, color.color)); + waveCanvasCtx.fillStyle = gradient ?? this.props.progressColor; + + const waveDrawer = this.props.barWidth ? this.drawBars : this.drawWaves; + waveDrawer(waveCanvasCtx, width, height / 2, peaks); + }; + + render() { + return this.props.peaks ? ( +
+ (ctx => ctx && this.updateSize(this.props.width, this.props.height, this.props.peaks, ctx))(instance?.getContext('2d'))} /> +
+ ) : null; + } +} -- cgit v1.2.3-70-g09d2 From 1cf241544f8063e3d71406238a584299b6ced794 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 13 Dec 2023 21:17:50 -0500 Subject: cleaned up props/_props handling by inherting from ObservableReactComponent --- .vscode/settings.json | 4 +- src/Utils.ts | 7 ++- src/client/util/DocumentManager.ts | 3 +- src/client/util/SelectionManager.ts | 22 +++---- src/client/views/AntimodeMenu.tsx | 13 +---- src/client/views/ContextMenu.tsx | 5 +- src/client/views/ContextMenuItem.tsx | 15 ++--- src/client/views/DashboardView.tsx | 4 +- src/client/views/DocComponent.tsx | 43 ++++++-------- src/client/views/DocumentButtonBar.tsx | 8 +-- src/client/views/DocumentDecorations.tsx | 6 +- src/client/views/EditableView.tsx | 14 ++--- src/client/views/MainView.tsx | 47 +++++++-------- src/client/views/MarqueeAnnotator.tsx | 20 +++---- src/client/views/ObservableReactComponent.tsx | 21 +++++++ src/client/views/OverlayView.tsx | 18 ++---- src/client/views/PreviewCursor.tsx | 13 +++-- src/client/views/PropertiesDocContextSelector.tsx | 17 ++---- src/client/views/PropertiesView.tsx | 26 ++++----- src/client/views/ScriptingRepl.tsx | 29 +++------- src/client/views/SidebarAnnos.tsx | 25 ++++---- .../views/collections/CollectionCarousel3DView.tsx | 6 +- .../views/collections/CollectionCarouselView.tsx | 7 ++- .../views/collections/CollectionDockingView.tsx | 15 ++--- .../collections/CollectionMasonryViewFieldRow.tsx | 18 +++--- src/client/views/collections/CollectionMenu.tsx | 2 +- .../views/collections/CollectionNoteTakingView.tsx | 8 ++- .../views/collections/CollectionPileView.tsx | 7 ++- .../collections/CollectionStackedTimeline.tsx | 22 ++----- .../views/collections/CollectionStackingView.tsx | 15 ++--- .../CollectionStackingViewFieldColumn.tsx | 20 +++---- src/client/views/collections/CollectionSubView.tsx | 19 +++--- .../views/collections/CollectionTimeView.tsx | 7 ++- .../views/collections/CollectionTreeView.tsx | 16 ++---- src/client/views/collections/CollectionView.tsx | 26 ++++----- src/client/views/collections/TabDocView.tsx | 41 ++++++------- src/client/views/collections/TreeView.tsx | 23 ++++---- .../CollectionFreeFormInfoState.tsx | 20 +++---- .../CollectionFreeFormInfoUI.tsx | 33 ++++------- .../CollectionFreeFormLinkView.tsx | 15 ++--- .../collectionFreeForm/CollectionFreeFormView.tsx | 13 +---- .../collectionFreeForm/MarqueeOptionsMenu.tsx | 1 - .../collections/collectionFreeForm/MarqueeView.tsx | 23 ++++---- .../collectionGrid/CollectionGridView.tsx | 7 ++- .../collectionLinear/CollectionLinearView.tsx | 19 ++---- .../CollectionMulticolumnView.tsx | 11 +++- .../CollectionMultirowView.tsx | 11 +++- .../collectionSchema/CollectionSchemaView.tsx | 37 +++++------- .../collections/collectionSchema/SchemaRowBox.tsx | 14 ++--- .../collectionSchema/SchemaTableCell.tsx | 67 +++++++++------------- src/client/views/linking/LinkMenu.tsx | 9 +-- src/client/views/linking/LinkMenuItem.tsx | 26 ++++----- src/client/views/nodes/AudioBox.tsx | 20 +++---- .../views/nodes/CollectionFreeFormDocumentView.tsx | 29 ++++------ src/client/views/nodes/ComparisonBox.tsx | 20 ++----- src/client/views/nodes/DocumentContentsView.tsx | 32 ++++------- src/client/views/nodes/DocumentIcon.tsx | 26 ++++----- src/client/views/nodes/DocumentLinksButton.tsx | 19 ++---- src/client/views/nodes/DocumentView.tsx | 36 ++++-------- src/client/views/nodes/EquationBox.tsx | 14 +---- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 14 ++--- src/client/views/nodes/FunctionPlotBox.tsx | 14 +---- src/client/views/nodes/ImageBox.tsx | 12 +--- src/client/views/nodes/KeyValueBox.tsx | 27 ++++----- src/client/views/nodes/KeyValuePair.tsx | 29 ++++------ src/client/views/nodes/LabelBox.tsx | 14 ++--- src/client/views/nodes/LinkAnchorBox.tsx | 19 ++---- src/client/views/nodes/LinkBox.tsx | 15 ++--- src/client/views/nodes/LinkDocPreview.tsx | 21 +++---- src/client/views/nodes/MapBox/MapAnchorMenu.tsx | 5 +- src/client/views/nodes/MapBox/MapBox.tsx | 22 +++---- src/client/views/nodes/PDFBox.tsx | 12 +--- src/client/views/nodes/VideoBox.tsx | 13 +---- src/client/views/nodes/WebBox.tsx | 11 +--- src/client/views/nodes/audio/AudioWaveform.tsx | 17 ++---- .../views/nodes/formattedText/DashFieldView.tsx | 18 +++--- .../views/nodes/formattedText/FormattedTextBox.tsx | 15 ++--- .../views/nodes/formattedText/RichTextMenu.tsx | 44 +++++--------- src/client/views/nodes/trails/PresElementBox.tsx | 17 ++---- src/client/views/pdf/AnchorMenu.tsx | 14 ++--- src/client/views/pdf/PDFViewer.tsx | 22 +++---- 81 files changed, 578 insertions(+), 911 deletions(-) create mode 100644 src/client/views/ObservableReactComponent.tsx (limited to 'src/client/views/nodes/audio') diff --git a/.vscode/settings.json b/.vscode/settings.json index 8849f30dd..5239d22c0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,5 +13,7 @@ "editor.defaultFormatter": "esbenp.prettier-vscode", "[typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" - } + }, + "terminal.integrated.shellIntegration.showWelcome": false, + "terminal.integrated.shellIntegration.enabled": true } diff --git a/src/Utils.ts b/src/Utils.ts index d54760100..3a2bbf9a1 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -440,7 +440,12 @@ export namespace Utils { socket.on(message, (room: any) => handler(socket, room)); } } -export function copyProps(thing: { _prevProps: any; props: any; _props: any }) { +export function copyProps(thing: { props: any; _props: any }, prevProps: any) { + Object.keys(prevProps).forEach(action(pkey => + (prevProps)[pkey] !== (thing.props as any)[pkey] && + ((thing._props as any)[pkey] = (thing.props as any)[pkey]))); // prettier-ignore +} +export function copyPropsFull(thing: { _prevProps: any; props: any; _props: any }) { Object.keys(thing._prevProps).forEach(action(pkey => (thing._prevProps as any)[pkey] !== (thing.props as any)[pkey] && ((thing._props as any)[pkey] = (thing.props as any)[pkey]))); // prettier-ignore diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 7fcda75cc..4816f3317 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -1,4 +1,4 @@ -import { action, computed, makeObservable, observable, ObservableSet, observe, reaction } from 'mobx'; +import { action, computed, makeObservable, observable, ObservableSet, observe } from 'mobx'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { AclAdmin, AclEdit, Animation } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; @@ -13,7 +13,6 @@ import { LightboxView } from '../views/LightboxView'; import { DocFocusOptions, DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod } from '../views/nodes/DocumentView'; import { KeyValueBox } from '../views/nodes/KeyValueBox'; import { LinkAnchorBox } from '../views/nodes/LinkAnchorBox'; -import { LoadingBox } from '../views/nodes/LoadingBox'; import { PresBox } from '../views/nodes/trails'; import { ScriptingGlobals } from './ScriptingGlobals'; import { SelectionManager } from './SelectionManager'; diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 7cf0d62d0..4bd6647c0 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -1,4 +1,4 @@ -import { action, makeObservable, observable } from 'mobx'; +import { action, makeObservable, observable, runInAction } from 'mobx'; import { Doc, Opt } from '../../fields/Doc'; import { DocViews } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; @@ -26,13 +26,13 @@ export class SelectionManager { } @action - public static SelectSchemaViewDoc(doc: Opt, deselectAllFirst?: boolean) { + public static SelectSchemaViewDoc = (doc: Opt, deselectAllFirst?: boolean) => { if (deselectAllFirst) this.DeselectAll(); this.Instance.SelectedSchemaDocument = doc; - } + }; @action - public static SelectView(docView: DocumentView, extendSelection: boolean): void { + public static SelectView = (docView: DocumentView | undefined, extendSelection: boolean): void => { if (!docView) this.DeselectAll(); else if (!docView.SELECTED) { if (!extendSelection) this.DeselectAll(); @@ -40,29 +40,29 @@ export class SelectionManager { docView.SELECTED = true; docView._props.whenChildContentsActiveChanged(true); } - } + }; @action - public static DeselectView(docView?: DocumentView): void { + public static DeselectView = (docView?: DocumentView): void => { if (docView && this.Instance.SelectedViews.includes(docView)) { docView.SELECTED = false; this.Instance.SelectedViews.splice(this.Instance.SelectedViews.indexOf(docView), 1); docView._props.whenChildContentsActiveChanged(false); } - } - @action - public static DeselectAll(except?: Doc): void { + }; + + public static DeselectAll = (except?: Doc): void => { const found = this.Instance.SelectedViews.find(dv => dv.Document === except); LinkManager.currentLink = undefined; LinkManager.currentLinkAnchor = undefined; - this.Instance.SelectedSchemaDocument = undefined; + runInAction(() => (this.Instance.SelectedSchemaDocument = undefined)); this.Instance.SelectedViews.forEach(dv => { dv.SELECTED = false; dv._props.whenChildContentsActiveChanged(false); }); this.Instance.SelectedViews.length = 0; if (found) this.SelectView(found, false); - } + }; public static IsSelected = (doc?: Doc) => Array.from(doc?.[DocViews] ?? []).some(dv => dv?.SELECTED); public static get Views() { return this.Instance.SelectedViews; } // prettier-ignore diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index f89624941..4c82b10fd 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -1,32 +1,25 @@ import { action, makeObservable, observable, runInAction } from 'mobx'; import * as React from 'react'; import { SettingsManager } from '../util/SettingsManager'; -import { copyProps } from '../../Utils'; import './AntimodeMenu.scss'; +import { ObservableReactComponent } from './ObservableReactComponent'; export interface AntimodeMenuProps {} /** * This is an abstract class that serves as the base for a PDF-style or Marquee-style * menu. To use this class, look at PDFMenu.tsx or MarqueeOptionsMenu.tsx for an example. */ -export abstract class AntimodeMenu extends React.Component { +export abstract class AntimodeMenu extends ObservableReactComponent { protected _offsetY: number = 0; protected _offsetX: number = 0; protected _mainCont: React.RefObject = React.createRef(); protected _dragging: boolean = false; - _prevProps: React.PropsWithChildren; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } - @observable protected _top: number = -300; @observable protected _left: number = -300; @observable protected _opacity: number = 0; diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 118a2c5f5..e55bf24a1 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -6,9 +6,10 @@ import { StrCast } from '../../fields/Types'; import { SettingsManager } from '../util/SettingsManager'; import './ContextMenu.scss'; import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from './ContextMenuItem'; +import { ObservableReactComponent } from './ObservableReactComponent'; @observer -export class ContextMenu extends React.Component { +export class ContextMenu extends ObservableReactComponent<{}> { static Instance: ContextMenu; private _ignoreUp = false; @@ -36,8 +37,8 @@ export class ContextMenu extends React.Component { constructor(props: any) { super(props); - makeObservable(this); ContextMenu.Instance = this; + makeObservable(this); } public setIgnoreEvents(ignore: boolean) { diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 59b223c14..3c9d821a9 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -5,7 +5,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { UndoManager } from '../util/UndoManager'; import { SettingsManager } from '../util/SettingsManager'; -import { copyProps } from '../../Utils'; +import { ObservableReactComponent } from './ObservableReactComponent'; export interface OriginalMenuProps { description: string; @@ -27,24 +27,17 @@ export interface SubmenuProps { export type ContextMenuProps = OriginalMenuProps | SubmenuProps; @observer -export class ContextMenuItem extends React.Component { +export class ContextMenuItem extends ObservableReactComponent { @observable private _items: Array = []; @observable private overItem = false; - _prevProps: ContextMenuProps & { selected?: boolean }; - @observable _props: ContextMenuProps & { selected?: boolean }; - constructor(props: ContextMenuProps & { selected?: boolean }) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } - componentDidMount() { - runInAction(() => this._items.length = 0); + runInAction(() => (this._items.length = 0)); if ((this.props as SubmenuProps)?.subitems) { (this.props as SubmenuProps).subitems?.forEach(i => runInAction(() => this._items.push(i))); } diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 35c0d617b..85cee83d4 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -27,6 +27,7 @@ import './DashboardView.scss'; import { Colors } from './global/globalEnums'; import { MainViewModal } from './MainViewModal'; import { ButtonType } from './nodes/FontIconBox/FontIconBox'; +import { ObservableReactComponent } from './ObservableReactComponent'; enum DashboardGroup { MyDashboards, @@ -36,9 +37,8 @@ enum DashboardGroup { // DashboardView is the view with the dashboard previews, rendered when the app first loads @observer -export class DashboardView extends React.Component { +export class DashboardView extends ObservableReactComponent<{}> { public static _urlState: HistoryUtil.DocUrl; - constructor(props: any) { super(props); makeObservable(this); diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 2ce0c085a..235b0dc68 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -1,17 +1,17 @@ -import { action, computed, makeObservable, observable, runInAction, untracked } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; +import * as React from 'react'; +import { returnFalse } from '../../Utils'; import { DateField } from '../../fields/DateField'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; -import { Cast } from '../../fields/Types'; import { GetEffectiveAcl, inheritParentAcls } from '../../fields/util'; -import { returnFalse } from '../../Utils'; -import { DocUtils } from '../documents/Documents'; import { DocumentType } from '../documents/DocumentTypes'; -import { DocumentView } from './nodes/DocumentView'; -import * as React from 'react'; +import { DocUtils } from '../documents/Documents'; import { DocumentManager } from '../util/DocumentManager'; +import { ObservableReactComponent } from './ObservableReactComponent'; import { CollectionFreeFormView } from './collections/collectionFreeForm'; +import { DocumentView } from './nodes/DocumentView'; /// DocComponent returns a generic React base class used by views that don't have 'fieldKey' props (e.g.,CollectionFreeFormDocumentView, DocumentView) export interface DocComponentProps { @@ -20,18 +20,14 @@ export interface DocComponentProps { LayoutTemplateString?: string; } export function DocComponent

() { - class Component extends React.Component> { - @observable _props!: React.PropsWithChildren

; - constructor(props: React.PropsWithChildren

) { + class Component extends ObservableReactComponent> { + constructor(props: any) { super(props); - this._props = props; makeObservable(this); } - componentDidUpdate() { - // untracked(() => (this._props = this.props)); - } + //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then - @computed get Document() { + get Document() { return this._props.Document; } // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info @@ -57,24 +53,18 @@ interface ViewBoxBaseProps { renderDepth: number; } export function ViewBoxBaseComponent

() { - class Component extends React.Component> { - @observable _props: React.PropsWithChildren

; - constructor(props: React.PropsWithChildren

) { - super(props); - this._props = props; - makeObservable(this); - } + class Component extends ObservableReactComponent> { //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then //@computed get Document(): T { return schemaCtor(this.props.Document); } get Document() { return this._props.Document; } // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info - get layoutDoc() { + @computed get layoutDoc() { return Doc.Layout(this.Document); } // This is the data part of a document -- ie, the data that is constant across all views of the document - get dataDoc() { + @computed get dataDoc() { return this.Document.isTemplateForField || this.Document.isTemplateDoc ? this._props.TemplateDataDocument ?? this.Document[DocData] : this.Document[DocData]; } // key where data is stored @@ -99,13 +89,12 @@ export interface ViewBoxAnnotatableProps { isAnnotationOverlay?: boolean; } export function ViewBoxAnnotatableComponent

() { - class Component extends React.Component> { - @observable _props: React.PropsWithChildren

; - constructor(props: React.PropsWithChildren

) { + class Component extends ObservableReactComponent> { + constructor(props: any) { super(props); - this._props = props; makeObservable(this); } + @observable _annotationKeySuffix = () => 'annotations'; @observable _isAnyChildContentActive = false; //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index a8ad4150e..50ca3af06 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -28,6 +28,7 @@ import { GoogleRef } from './nodes/formattedText/FormattedTextBox'; import { PinProps } from './nodes/trails'; import { TemplateMenu } from './TemplateMenu'; import * as React from 'react'; +import { ObservableReactComponent } from './ObservableReactComponent'; // import * as higflyout from '@hig/flyout'; // export const { anchorPoints } = higflyout; // export const Flyout = higflyout.default; @@ -42,12 +43,11 @@ enum UtilityButtonState { } @observer -export class DocumentButtonBar extends React.Component<{ views: () => (DocumentView | undefined)[]; stack?: any }, {}> { +export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (DocumentView | undefined)[]; stack?: any }> { private _dragRef = React.createRef(); private _pullAnimating = false; private _pushAnimating = false; private _pullColorAnimating = false; - @observable private pushIcon: IconProp = 'arrow-alt-circle-up'; @observable private pullIcon: IconProp = 'arrow-alt-circle-down'; @observable private pullColor: string = 'white'; @@ -60,12 +60,10 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV public static hasPushedHack = false; public static hasPulledHack = false; - @observable _props: { views: () => (DocumentView | undefined)[] }; constructor(props: { views: () => (DocumentView | undefined)[] }) { super(props); - this._props = props; + DocumentButtonBar.Instance = this; makeObservable(this); - runInAction(() => (DocumentButtonBar.Instance = this)); } public startPullOutcome = action((success: boolean) => { diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 8bcc1cb56..7003485d2 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -34,6 +34,7 @@ import { DocumentView, OpenWhereMod } from './nodes/DocumentView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { ImageBox } from './nodes/ImageBox'; import * as React from 'react'; +import { ObservableReactComponent } from './ObservableReactComponent'; interface DocumentDecorationsProps { PanelWidth: number; @@ -42,7 +43,7 @@ interface DocumentDecorationsProps { boundsTop: number; } @observer -export class DocumentDecorations extends React.Component { +export class DocumentDecorations extends ObservableReactComponent { static Instance: DocumentDecorations; private _resizeHdlId = ''; private _keyinput = React.createRef(); @@ -66,11 +67,10 @@ export class DocumentDecorations extends React.Component; constructor(props: React.PropsWithChildren) { super(props); - this._props = props; makeObservable(this); + DocumentDecorations.Instance = this; document.addEventListener('pointermove', // show decorations whenever pointer moves outside of selection bounds. action(e => { diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 3db77be71..836a184eb 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -1,13 +1,13 @@ -import * as React from 'react'; import { action, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import * as Autosuggest from 'react-autosuggest'; import { ObjectField } from '../../fields/ObjectField'; import './EditableView.scss'; import { DocumentIconContainer } from './nodes/DocumentIcon'; -import { OverlayView } from './OverlayView'; -import { copyProps } from '../../Utils'; import { FieldView, FieldViewProps } from './nodes/FieldView'; +import { ObservableReactComponent } from './ObservableReactComponent'; +import { OverlayView } from './OverlayView'; export interface EditableProps { /** @@ -60,18 +60,15 @@ export interface EditableProps { * of the content, and set the value based on the entered string. */ @observer -export class EditableView extends React.Component { +export class EditableView extends ObservableReactComponent { private _ref = React.createRef(); private _inputref: HTMLInputElement | HTMLTextAreaElement | null = null; _overlayDisposer?: () => void; _editingDisposer?: IReactionDisposer; @observable _editing: boolean = false; - _prevProps: EditableProps; - @observable _props: EditableProps; constructor(props: EditableProps) { super(props); - this._props = this._prevProps = props; makeObservable(this); this._editing = this._props.editing ? true : false; } @@ -96,8 +93,7 @@ export class EditableView extends React.Component { ); } - componentDidUpdate() { - copyProps(this); + componentDidUpdate(prevProps: Readonly) { if (this._editing && this._props.editing === false) { this._inputref?.value && this.finalizeEdit(this._inputref.value, false, true, false); } else if (this._props.editing !== undefined) { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 4f96b9234..f65675792 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -8,20 +8,19 @@ import { observer } from 'mobx-react'; import 'normalize.css'; import * as React from 'react'; import '../../../node_modules/browndash-components/dist/styles/global.min.css'; +import { Utils, emptyFunction, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../Utils'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { DocCast, StrCast } from '../../fields/Types'; -import { emptyFunction, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents, Utils } from '../../Utils'; -import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager'; import { DocServer } from '../DocServer'; -import { Docs } from '../documents/Documents'; +import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager'; import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; +import { Docs } from '../documents/Documents'; import { CaptureManager } from '../util/CaptureManager'; import { DocumentManager } from '../util/DocumentManager'; import { DragManager } from '../util/DragManager'; import { GroupManager } from '../util/GroupManager'; import { HistoryUtil } from '../util/History'; import { Hypothesis } from '../util/HypothesisUtils'; -import { ReportManager } from '../util/reportManager/ReportManager'; import { RTFMarkup } from '../util/RTFMarkup'; import { ScriptingGlobals } from '../util/ScriptingGlobals'; import { SelectionManager } from '../util/SelectionManager'; @@ -30,13 +29,7 @@ import { SettingsManager } from '../util/SettingsManager'; import { SharingManager } from '../util/SharingManager'; import { SnappingManager } from '../util/SnappingManager'; import { Transform } from '../util/Transform'; -import { TimelineMenu } from './animationtimeline/TimelineMenu'; -import { CollectionDockingView } from './collections/CollectionDockingView'; -import { MarqueeOptionsMenu } from './collections/collectionFreeForm/MarqueeOptionsMenu'; -import { CollectionLinearView } from './collections/collectionLinear'; -import { CollectionMenu } from './collections/CollectionMenu'; -import { TabDocView } from './collections/TabDocView'; -import './collections/TreeView.scss'; +import { ReportManager } from '../util/reportManager/ReportManager'; import { ComponentDecorations } from './ComponentDecorations'; import { ContextMenu } from './ContextMenu'; import { DashboardView } from './DashboardView'; @@ -45,15 +38,24 @@ import { DocumentDecorations } from './DocumentDecorations'; import { GestureOverlay } from './GestureOverlay'; import { KeyManager } from './GlobalKeyHandler'; import { LightboxView } from './LightboxView'; -import { LinkMenu } from './linking/LinkMenu'; import './MainView.scss'; +import { ObservableReactComponent } from './ObservableReactComponent'; +import { OverlayView } from './OverlayView'; +import { PreviewCursor } from './PreviewCursor'; +import { PropertiesView } from './PropertiesView'; +import { DashboardStyleProvider, DefaultStyleProvider } from './StyleProvider'; +import { TimelineMenu } from './animationtimeline/TimelineMenu'; +import { CollectionDockingView } from './collections/CollectionDockingView'; +import { CollectionMenu } from './collections/CollectionMenu'; +import { TabDocView } from './collections/TabDocView'; +import './collections/TreeView.scss'; +import { CollectionFreeFormLinksView } 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 { DocButtonState } from './nodes/DocumentLinksButton'; import { DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod } from './nodes/DocumentView'; -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 { ImageBox } from './nodes/ImageBox'; import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup'; import { LinkDocPreview, LinkInfo } from './nodes/LinkDocPreview'; @@ -61,20 +63,19 @@ import { MapAnchorMenu } from './nodes/MapBox/MapAnchorMenu'; import { MapBox } from './nodes/MapBox/MapBox'; import { RadialMenu } from './nodes/RadialMenu'; 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 { OverlayView } from './OverlayView'; import { AnchorMenu } from './pdf/AnchorMenu'; import { GPTPopup } from './pdf/GPTPopup/GPTPopup'; -import { PreviewCursor } from './PreviewCursor'; -import { PropertiesView } from './PropertiesView'; -import { DashboardStyleProvider, DefaultStyleProvider } from './StyleProvider'; import { TopBar } from './topbar/TopBar'; -import { CollectionFreeFormLinksView } from './collections/collectionFreeForm'; const { default: { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } } = require('./global/globalCssVariables.module.scss'); // prettier-ignore const _global = (window /* browser */ || global) /* node */ as any; @observer -export class MainView extends React.Component { +export class MainView extends ObservableReactComponent<{}> { public static Instance: MainView; public static Live: boolean = false; private _docBtnRef = React.createRef(); @@ -1064,7 +1065,7 @@ export class MainView extends React.Component { - {this.mapBoxHack} + {/* {this.mapBoxHack} */} {/* */} diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index 3f0db4258..2e27d1f70 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -15,6 +15,7 @@ import './MarqueeAnnotator.scss'; import { DocumentView } from './nodes/DocumentView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { AnchorMenu } from './pdf/AnchorMenu'; +import { ObservableReactComponent } from './ObservableReactComponent'; const _global = (window /* browser */ || global) /* node */ as any; export interface MarqueeAnnotatorProps { @@ -38,23 +39,18 @@ export interface MarqueeAnnotatorProps { highlightDragSrcColor?: string; } @observer -export class MarqueeAnnotator extends React.Component { +export class MarqueeAnnotator extends ObservableReactComponent { private _start: { x: number; y: number } = { x: 0, y: 0 }; - @observable private _width: number = 0; - @observable private _height: number = 0; - @computed get top() { return Math.min(this._start.y, this._start.y + this._height); } // prettier-ignore - @computed get left() { return Math.min(this._start.x, this._start.x + this._width);} // prettier-ignore - _prevProps: React.PropsWithChildren; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidMount() { - copyProps(this); - } + + @observable private _width: number = 0; + @observable private _height: number = 0; + @computed get top() { return Math.min(this._start.y, this._start.y + this._height); } // prettier-ignore + @computed get left() { return Math.min(this._start.x, this._start.x + this._width);} // prettier-ignore @action static clearAnnotations(savedAnnotations: ObservableMap) { diff --git a/src/client/views/ObservableReactComponent.tsx b/src/client/views/ObservableReactComponent.tsx new file mode 100644 index 000000000..2d8dc9af9 --- /dev/null +++ b/src/client/views/ObservableReactComponent.tsx @@ -0,0 +1,21 @@ +import { makeObservable, observable } from 'mobx'; +import * as React from 'react'; +import { copyProps } from '../../Utils'; +import './AntimodeMenu.scss'; +export interface AntimodeMenuProps {} + +/** + * This is an abstract class that serves as the base for a PDF-style or Marquee-style + * menu. To use this class, look at PDFMenu.tsx or MarqueeOptionsMenu.tsx for an example. + */ +export abstract class ObservableReactComponent extends React.Component { + @observable _props: React.PropsWithChildren; + constructor(props: React.PropsWithChildren) { + super(props); + this._props = props; + makeObservable(this); + } + componentDidUpdate(prevProps: Readonly): void { + copyProps(this, prevProps); + } +} diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 673432a60..915c3c18f 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -1,9 +1,9 @@ -import { action, computed, makeObservable, observable, toJS } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; import * as React from 'react'; import ReactLoading from 'react-loading'; -import { Utils, copyProps, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnTrue, setupMoveUpEvents } from '../../Utils'; +import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnTrue, setupMoveUpEvents } from '../../Utils'; import { Doc } from '../../fields/Doc'; import { Height, Width } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; @@ -12,6 +12,7 @@ import { DocumentType } from '../documents/DocumentTypes'; import { DragManager } from '../util/DragManager'; import { Transform } from '../util/Transform'; import { LightboxView } from './LightboxView'; +import { ObservableReactComponent } from './ObservableReactComponent'; import './OverlayView.scss'; import { DefaultStyleProvider } from './StyleProvider'; import { DocumentView, DocumentViewInternal } from './nodes/DocumentView'; @@ -34,19 +35,14 @@ export interface OverlayWindowProps { } @observer -export class OverlayWindow extends React.Component { +export class OverlayWindow extends ObservableReactComponent { @observable x: number = 0; @observable y: number = 0; @observable width: number = 0; @observable height: number = 0; - - _prevProps: OverlayWindowProps; - @observable _props: OverlayWindowProps; constructor(props: OverlayWindowProps) { super(props); - this._props = this._prevProps = props; makeObservable(this); - const opts = props.overlayOptions; this.x = opts.x; this.y = opts.y; @@ -54,10 +50,6 @@ export class OverlayWindow extends React.Component { this.height = opts.height || 200; } - componentDidUpdate() { - copyProps(this); - } - onPointerDown = (_: React.PointerEvent) => { document.removeEventListener('pointermove', this.onPointerMove); document.removeEventListener('pointerup', this.onPointerUp); @@ -115,7 +107,7 @@ export class OverlayWindow extends React.Component { } @observer -export class OverlayView extends React.Component { +export class OverlayView extends ObservableReactComponent<{}> { public static Instance: OverlayView; @observable.shallow _elements: JSX.Element[] = []; diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 6e1a2cfb1..5ec9a7d46 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -1,17 +1,18 @@ import { action, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, Opt } from '../../fields/Doc'; import { lightOrDark, returnFalse } from '../../Utils'; -import { Docs, DocumentOptions, DocUtils } from '../documents/Documents'; +import { Doc, Opt } from '../../fields/Doc'; +import { DocUtils, Docs, DocumentOptions } from '../documents/Documents'; import { ImageUtils } from '../util/Import & Export/ImageUtils'; import { Transform } from '../util/Transform'; -import { undoBatch, UndoManager } from '../util/UndoManager'; -import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; +import { UndoManager, undoBatch } from '../util/UndoManager'; +import { ObservableReactComponent } from './ObservableReactComponent'; import './PreviewCursor.scss'; +import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; @observer -export class PreviewCursor extends React.Component<{}> { +export class PreviewCursor extends ObservableReactComponent<{}> { static _instance: PreviewCursor; public static get Instance() { return PreviewCursor._instance; @@ -28,8 +29,8 @@ export class PreviewCursor extends React.Component<{}> { public Doc: Opt; constructor(props: any) { super(props); - PreviewCursor._instance = this; makeObservable(this); + PreviewCursor._instance = this; this._clickPoint = observable([0, 0]); document.addEventListener('keydown', this.onKeyPress); document.addEventListener('paste', this.paste, true); diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx index 5bde9d3c4..a710e7816 100644 --- a/src/client/views/PropertiesDocContextSelector.tsx +++ b/src/client/views/PropertiesDocContextSelector.tsx @@ -1,14 +1,14 @@ -import { computed, makeObservable, observable } from 'mobx'; +import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../fields/Doc'; import { Id } from '../../fields/FieldSymbols'; import { Cast, StrCast } from '../../fields/Types'; import { DocFocusOrOpen } from '../util/DocumentManager'; +import { ObservableReactComponent } from './ObservableReactComponent'; +import './PropertiesDocContextSelector.scss'; import { CollectionDockingView } from './collections/CollectionDockingView'; import { DocumentView, OpenWhere } from './nodes/DocumentView'; -import './PropertiesDocContextSelector.scss'; -import { copyProps } from '../../Utils'; type PropertiesDocContextSelectorProps = { DocView?: DocumentView; @@ -18,17 +18,12 @@ type PropertiesDocContextSelectorProps = { }; @observer -export class PropertiesDocContextSelector extends React.Component { - _prevProps: PropertiesDocContextSelectorProps; - @observable _props: PropertiesDocContextSelectorProps; - constructor(props: PropertiesDocContextSelectorProps) { +export class PropertiesDocContextSelector extends ObservableReactComponent { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } + @computed get _docs() { if (!this._props.DocView) return []; const target = this._props.DocView._props.Document; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 442d09739..c857c2d6b 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1,14 +1,15 @@ -import * as React from 'react'; import { IconLookup } from '@fortawesome/fontawesome-svg-core'; import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox, Tooltip } from '@mui/material'; import { Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components'; import { concat } from 'lodash'; -import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; +import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { ColorResult, SketchPicker } from 'react-color'; import * as Icons from 'react-icons/bs'; //{BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs" +import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils'; import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc'; import { AclAdmin, DocAcl, DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; @@ -16,8 +17,7 @@ import { InkField } from '../../fields/InkField'; import { List } from '../../fields/List'; import { ComputedField } from '../../fields/ScriptField'; import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types'; -import { GetEffectiveAcl, normalizeEmail, SharingPermissions } from '../../fields/util'; -import { copyProps, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../Utils'; +import { GetEffectiveAcl, SharingPermissions, normalizeEmail } from '../../fields/util'; import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; import { DocumentManager } from '../util/DocumentManager'; import { GroupManager } from '../util/GroupManager'; @@ -26,19 +26,20 @@ import { SelectionManager } from '../util/SelectionManager'; import { SettingsManager } from '../util/SettingsManager'; import { SharingManager } from '../util/SharingManager'; import { Transform } from '../util/Transform'; -import { undoable, undoBatch, UndoManager } from '../util/UndoManager'; +import { UndoManager, undoBatch, undoable } from '../util/UndoManager'; import { EditableView } from './EditableView'; import { FilterPanel } from './FilterPanel'; import { InkStrokeProperties } from './InkStrokeProperties'; -import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView'; -import { KeyValueBox } from './nodes/KeyValueBox'; -import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails'; +import { ObservableReactComponent } from './ObservableReactComponent'; import { PropertiesButtons } from './PropertiesButtons'; import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector'; import { PropertiesDocContextSelector } from './PropertiesDocContextSelector'; import { PropertiesSection } from './PropertiesSection'; import './PropertiesView.scss'; import { DefaultStyleProvider } from './StyleProvider'; +import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView'; +import { KeyValueBox } from './nodes/KeyValueBox'; +import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails'; const _global = (window /* browser */ || global) /* node */ as any; interface PropertiesViewProps { @@ -49,15 +50,12 @@ interface PropertiesViewProps { } @observer -export class PropertiesView extends React.Component { +export class PropertiesView extends ObservableReactComponent { private _widthUndo?: UndoManager.Batch; public static Instance: PropertiesView | undefined; - _prevProps: React.PropsWithChildren; - @observable _props: React.PropsWithChildren; constructor(props: React.PropsWithChildren) { super(props); - this._props = this._prevProps = props; makeObservable(this); PropertiesView.Instance = this; } @@ -120,10 +118,6 @@ export class PropertiesView extends React.Component { ); } - componentDidUpdate() { - copyProps(this); - } - componentWillUnmount() { Object.values(this._disposers).forEach(disposer => disposer?.()); } diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx index 8251d20dc..5f20bc745 100644 --- a/src/client/views/ScriptingRepl.tsx +++ b/src/client/views/ScriptingRepl.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, observable, makeObservable } from 'mobx'; +import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { DocumentManager } from '../util/DocumentManager'; @@ -7,29 +7,23 @@ import { CompileScript, Transformer, ts } from '../util/Scripting'; import { ScriptingGlobals } from '../util/ScriptingGlobals'; import { SettingsManager } from '../util/SettingsManager'; import { undoable } from '../util/UndoManager'; -import { DocumentIconContainer } from './nodes/DocumentIcon'; +import { ObservableReactComponent } from './ObservableReactComponent'; import { OverlayView } from './OverlayView'; import './ScriptingRepl.scss'; -import { copyProps } from '../../Utils'; +import { DocumentIconContainer } from './nodes/DocumentIcon'; interface ReplProps { scrollToBottom: () => void; value: { [key: string]: any }; name?: string; } -export class ScriptingObjectDisplay extends React.Component { +export class ScriptingObjectDisplay extends ObservableReactComponent { @observable collapsed = true; - _prevProps: ReplProps; - @observable _props: ReplProps; - constructor(props: ReplProps) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate(): void { - copyProps(this); - } @action toggle = () => { @@ -84,17 +78,12 @@ interface replValueProps { name?: string; } @observer -export class ScriptingValueDisplay extends React.Component { - _prevProps: replValueProps; - @observable _props: replValueProps; - constructor(props: replValueProps) { +export class ScriptingValueDisplay extends ObservableReactComponent { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } + render() { const val = this._props.name ? this._props.value[this._props.name] : this._props.value; if (typeof val === 'object') { @@ -126,7 +115,7 @@ export class ScriptingValueDisplay extends React.Component { } @observer -export class ScriptingRepl extends React.Component { +export class ScriptingRepl extends ObservableReactComponent<{}> { constructor(props: any) { super(props); makeObservable(this); diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index 19473de2b..0f4a4260c 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -1,22 +1,23 @@ -import { computed, makeObservable, observable } from 'mobx'; +import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { emptyFunction, returnAll, returnFalse, returnOne, returnZero } from '../../Utils'; import { Doc, DocListCast, Field, FieldResult, StrListCast } from '../../fields/Doc'; import { Id } from '../../fields/FieldSymbols'; import { List } from '../../fields/List'; import { RichTextField } from '../../fields/RichTextField'; import { DocCast, NumCast, StrCast } from '../../fields/Types'; -import { copyProps, emptyFunction, returnAll, returnFalse, returnOne, returnTrue, returnZero } from '../../Utils'; -import { Docs, DocUtils } from '../documents/Documents'; import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; +import { DocUtils, Docs } from '../documents/Documents'; import { LinkManager } from '../util/LinkManager'; import { SearchUtil } from '../util/SearchUtil'; import { Transform } from '../util/Transform'; +import { ObservableReactComponent } from './ObservableReactComponent'; +import './SidebarAnnos.scss'; +import { StyleProp } from './StyleProvider'; import { CollectionStackingView } from './collections/CollectionStackingView'; import { FieldViewProps } from './nodes/FieldView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; -import './SidebarAnnos.scss'; -import { StyleProp } from './StyleProvider'; -import * as React from 'react'; interface ExtraProps { fieldKey: string; @@ -34,18 +35,12 @@ interface ExtraProps { moveDocument: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean, annotationKey?: string) => boolean; } @observer -export class SidebarAnnos extends React.Component { - _prevProps: FieldViewProps & ExtraProps; - @observable _props: FieldViewProps & ExtraProps; - constructor(props: FieldViewProps & ExtraProps) { +export class SidebarAnnos extends ObservableReactComponent { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); - // this._props.dataDoc[this.sidebarKey] = new List(); // bcz: can't do this here. it blows away existing things and isn't a robust solution for making sure the field exists -- instead this should happen when the document is created and/or shared - } - componentDidUpdate() { - copyProps(this); } + _stackRef = React.createRef(); @computed get allMetadata() { const keys = new Map>(); diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index f03e38850..a11c53d4d 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { computed } from 'mobx'; +import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Utils, returnFalse, returnZero } from '../../../Utils'; @@ -19,6 +19,10 @@ export class CollectionCarousel3DView extends CollectionSubView() { @computed get scrollSpeed() { return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; //default scroll speed } + constructor(props: any) { + super(props); + makeObservable(this); + } private _dropDisposer?: DragManager.DragDropDisposer; diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 299a4d5d3..5d09f14ef 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { computed } from 'mobx'; +import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { StopEvent, emptyFunction, returnFalse, returnOne, returnZero } from '../../../Utils'; @@ -16,6 +16,11 @@ import { CollectionSubView } from './CollectionSubView'; export class CollectionCarouselView extends CollectionSubView() { private _dropDisposer?: DragManager.DragDropDisposer; + constructor(props: any) { + super(props); + makeObservable(this); + } + componentWillUnmount() { this._dropDisposer?.(); } diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 4ddf9e69b..0d3ff8bba 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -1,5 +1,6 @@ -import { action, IReactionDisposer, makeObservable, observable, override, reaction, runInAction, untracked } from 'mobx'; +import { action, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; import * as GoldenLayout from '../../../client/goldenLayout'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; @@ -10,7 +11,7 @@ import { List } from '../../../fields/List'; import { ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { GetEffectiveAcl, inheritParentAcls } from '../../../fields/util'; -import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, copyProps, emptyFunction, incrementTitleCopy } from '../../../Utils'; +import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, incrementTitleCopy } from '../../../Utils'; import { DocServer } from '../../DocServer'; import { Docs } from '../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; @@ -19,6 +20,7 @@ import { DragManager } from '../../util/DragManager'; import { InteractionUtils } from '../../util/InteractionUtils'; import { ScriptingGlobals } from '../../util/ScriptingGlobals'; import { SelectionManager } from '../../util/SelectionManager'; +import { SettingsManager } from '../../util/SettingsManager'; import { undoable, undoBatch, UndoManager } from '../../util/UndoManager'; import { DashboardView } from '../DashboardView'; import { LightboxView } from '../LightboxView'; @@ -30,8 +32,6 @@ import './CollectionDockingView.scss'; import { CollectionFreeFormView } from './collectionFreeForm'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { TabDocView } from './TabDocView'; -import * as React from 'react'; -import { SettingsManager } from '../../util/SettingsManager'; const _global = (window /* browser */ || global) /* node */ as any; @observer @@ -63,11 +63,8 @@ export class CollectionDockingView extends CollectionSubView() { private _goldenLayout: any = null; static _highlightStyleSheet: any = addStyleSheet(); - _prevProps: SubCollectionViewProps; - @override _props: SubCollectionViewProps; constructor(props: SubCollectionViewProps) { super(props); - this._props = this._prevProps = props; makeObservable(this); if (this._props.renderDepth < 0) runInAction(() => (CollectionDockingView.Instance = this)); //Why is this here? @@ -77,10 +74,6 @@ export class CollectionDockingView extends CollectionSubView() { this.Document.myTrails; // this is equivalent to having a prefetchProxy for myTrails which is needed for the My Trails button in the UI which assumes that Doc.ActiveDashboard.myTrails is legit... } - componentDidUpdate() { - copyProps(this); - } - /** * Switches from dragging a document around a freeform canvas to dragging it as a tab to be docked. * diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index 0905aa078..5dba9e72a 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -1,12 +1,12 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { emptyFunction, numberRange, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../../Utils'; import { Doc, DocListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField'; import { ScriptField } from '../../../fields/ScriptField'; -import { emptyFunction, numberRange, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../../Utils'; import { Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { CompileScript } from '../../util/Scripting'; @@ -14,6 +14,7 @@ import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { undoBatch } from '../../util/UndoManager'; import { EditableView } from '../EditableView'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { CollectionStackingView } from './CollectionStackingView'; import './CollectionStackingView.scss'; @@ -41,19 +42,18 @@ interface CMVFieldRowProps { } @observer -export class CollectionMasonryViewFieldRow extends React.Component { +export class CollectionMasonryViewFieldRow extends ObservableReactComponent { + constructor(props: any) { + super(props); + makeObservable(this); + } + @observable private _background = 'inherit'; @observable private _createEmbeddingSelected: boolean = false; @observable private heading: string = ''; @observable private color: string = '#f1efeb'; @observable private collapsed: boolean = false; @observable private _paletteOn = false; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { - super(props); - this._props = props; - makeObservable(this); - } private set _heading(value: string) { runInAction(() => this._props.headingObject && (this._props.headingObject.heading = this.heading = value)); } diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 08fcd544e..3ade2ab56 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -9,7 +9,7 @@ import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; import { RichTextField } from '../../../fields/RichTextField'; import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types'; -import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../../Utils'; +import { copyProps, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../../Utils'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; import { DragManager } from '../../util/DragManager'; import { SelectionManager } from '../../util/SelectionManager'; diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx index 702775307..f9d258490 100644 --- a/src/client/views/collections/CollectionNoteTakingView.tsx +++ b/src/client/views/collections/CollectionNoteTakingView.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, Field, Opt } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; @@ -44,6 +44,12 @@ export class CollectionNoteTakingView extends CollectionSubView() { public DividerWidth = 16; @observable docsDraggedRowCol: number[] = []; @observable _scroll = 0; + + constructor(props: any) { + super(props); + makeObservable(this); + } + @computed get chromeHidden() { return BoolCast(this.layoutDoc.chromeHidden) || this.props.onBrowseClick?.() ? true : false; } diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index a0f8b9c89..170b1f1ec 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -1,4 +1,4 @@ -import { action, computed, IReactionDisposer } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, DocListCast } from '../../../fields/Doc'; import { ScriptField } from '../../../fields/ScriptField'; @@ -19,6 +19,11 @@ export class CollectionPileView extends CollectionSubView() { _originalChrome: any = ''; _disposers: { [name: string]: IReactionDisposer } = {}; + constructor(props: any) { + super(props); + makeObservable(this); + } + componentDidMount() { if (this.layoutEngine() !== computePassLayout.name && this.layoutEngine() !== computeStarburstLayout.name) { this.Document._freeform_pileEngine = computePassLayout.name; diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 1b14b31ac..d37a942d0 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -1,4 +1,4 @@ -import { action, computed, IReactionDisposer, makeObservable, observable, override, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; import * as React from 'react'; @@ -9,7 +9,7 @@ import { listSpec } from '../../../fields/Schema'; import { ComputedField, ScriptField } from '../../../fields/ScriptField'; import { Cast, NumCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; -import { copyProps, emptyFunction, formatTime, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnTrue, returnZero, setupMoveUpEvents, smoothScrollHorizontal, StopEvent } from '../../../Utils'; +import { emptyFunction, formatTime, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnTrue, returnZero, setupMoveUpEvents, smoothScrollHorizontal, StopEvent } from '../../../Utils'; import { Docs } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; @@ -26,6 +26,7 @@ import { AudioWaveform } from '../nodes/audio/AudioWaveform'; import { DocFocusFunc, DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from '../nodes/DocumentView'; import { LabelBox } from '../nodes/LabelBox'; import { VideoBox } from '../nodes/VideoBox'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import './CollectionStackedTimeline.scss'; export type CollectionStackedTimelineProps = { @@ -56,17 +57,10 @@ export enum TrimScope { export class CollectionStackedTimeline extends CollectionSubView() { @observable static SelectingRegion: CollectionStackedTimeline | undefined = undefined; @observable public static CurrentlyPlaying: DocumentView[]; - - _prevProps: React.PropsWithChildren; - @override _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } static LabelScript: ScriptField; static LabelPlayScript: ScriptField; @@ -697,21 +691,15 @@ interface StackedTimelineAnchorProps { } @observer -class StackedTimelineAnchor extends React.Component { +class StackedTimelineAnchor extends ObservableReactComponent { _lastTimecode: number; _disposer: IReactionDisposer | undefined; - _prevProps: React.PropsWithChildren; - @observable _props: React.PropsWithChildren; constructor(props: React.PropsWithChildren) { super(props); - this._props = this._prevProps = props; makeObservable(this); this._lastTimecode = this._props.currentTimecode(); } - componentDidUpdate() { - copyProps(this); - } // updates marker document title to reflect correct timecodes computeTitle = () => { diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index d6105c184..16adf4b96 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -1,8 +1,8 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import * as CSS from 'csstype'; -import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction, untracked } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, Opt } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; @@ -11,7 +11,7 @@ import { listSpec } from '../../../fields/Schema'; import { SchemaHeaderField } from '../../../fields/SchemaHeaderField'; import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { copyProps, emptyFunction, returnEmptyDoclist, returnFalse, returnNone, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnFalse, returnNone, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { CollectionViewType } from '../../documents/DocumentTypes'; import { DragManager, dropActionType } from '../../util/DragManager'; @@ -31,7 +31,7 @@ import { StyleProp } from '../StyleProvider'; import { CollectionMasonryViewFieldRow } from './CollectionMasonryViewFieldRow'; import './CollectionStackingView.scss'; import { CollectionStackingViewFieldColumn } from './CollectionStackingViewFieldColumn'; -import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; +import { CollectionSubView } from './CollectionSubView'; const _global = (window /* browser */ || global) /* node */ as any; export type collectionStackingViewProps = { @@ -115,22 +115,15 @@ export class CollectionStackingView extends CollectionSubView>; - _props: React.PropsWithChildren>; constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); - if (this.colHeaderData === undefined) { // TODO: what is a layout doc? Is it literally how this document is supposed to be layed out? // here we're making an empty list of column headers (again, what Mehek showed us) this.dataDoc['_' + this.fieldKey + '_columnHeaders'] = new List(); } } - componentDidUpdate() { - copyProps(this); - } // TODO: plj - these are the children children = (docs: Doc[]) => { diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 7ea146479..2302bfbc3 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -1,15 +1,15 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction, untracked } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { RichTextField } from '../../../fields/RichTextField'; import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField'; import { ScriptField } from '../../../fields/ScriptField'; -import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types'; +import { BoolCast, NumCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, setupMoveUpEvents, returnFalse, returnEmptyString } from '../../../Utils'; +import { emptyFunction, returnEmptyString, setupMoveUpEvents } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; import { DragManager } from '../../util/DragManager'; @@ -19,9 +19,9 @@ import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { EditableView } from '../EditableView'; -import './CollectionStackingView.scss'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; -import { Id } from '../../../fields/FieldSymbols'; +import './CollectionStackingView.scss'; +import { ObservableReactComponent } from '../ObservableReactComponent'; // So this is how we are storing a column interface CSVFieldColumnProps { @@ -49,7 +49,7 @@ interface CSVFieldColumnProps { } @observer -export class CollectionStackingViewFieldColumn extends React.Component { +export class CollectionStackingViewFieldColumn extends ObservableReactComponent { private dropDisposer?: DragManager.DragDropDisposer; private _disposers: { [name: string]: IReactionDisposer } = {}; private _headerRef: React.RefObject = React.createRef(); @@ -58,10 +58,8 @@ export class CollectionStackingViewFieldColumn extends React.Component (this._props = this.props)); - } - @action componentDidMount() { this._disposers.collapser = reaction( diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 79b15fdb1..0131af6f2 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -1,5 +1,7 @@ -import { action, computed, makeObservable, observable, override, runInAction, untracked } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; +import * as React from 'react'; import * as rp from 'request-promise'; +import { Utils, returnFalse } from '../../../Utils'; import CursorField from '../../../fields/CursorField'; import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc'; import { AclPrivate } from '../../../fields/DocSymbols'; @@ -10,21 +12,19 @@ import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types'; import { WebField } from '../../../fields/URLField'; import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; -import { returnFalse, Utils } from '../../../Utils'; import { DocServer } from '../../DocServer'; -import { Docs, DocumentOptions, DocUtils } from '../../documents/Documents'; -import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; import { Networking } from '../../Network'; +import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; +import { DocUtils, Docs, DocumentOptions } from '../../documents/Documents'; import { DragManager, dropActionType } from '../../util/DragManager'; import { ImageUtils } from '../../util/Import & Export/ImageUtils'; import { SelectionManager } from '../../util/SelectionManager'; import { SnappingManager } from '../../util/SnappingManager'; -import { undoBatch, UndoManager } from '../../util/UndoManager'; +import { UndoManager, undoBatch } from '../../util/UndoManager'; import { ViewBoxBaseComponent } from '../DocComponent'; -import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { LoadingBox } from '../nodes/LoadingBox'; +import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { CollectionView, CollectionViewProps } from './CollectionView'; -import * as React from 'react'; export interface SubCollectionViewProps extends CollectionViewProps { isAnyChildContentActive: () => boolean; @@ -35,16 +35,11 @@ export function CollectionSubView(moreProps?: X) { private dropDisposer?: DragManager.DragDropDisposer; private gestureDisposer?: GestureUtils.GestureEventDisposer; protected _mainCont?: HTMLDivElement; - @override _props: X & SubCollectionViewProps; constructor(props: any) { super(props); - this._props = props; makeObservable(this); } - componentDidUpdate() { - // untracked(() => (this._props = this.props)); - } @observable _focusFilters: Opt; // childFilters that are overridden when previewing a link to an anchor which has childFilters set on it @observable _focusRangeFilters: Opt; // childFiltersByRanges that are overridden when previewing a link to an anchor which has childFiltersByRanges set on it diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index e65f24702..c440a7e3f 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -1,5 +1,5 @@ import { toUpper } from 'lodash'; -import { action, computed, observable, runInAction } from 'mobx'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, Opt, StrListCast } from '../../../fields/Doc'; import { List } from '../../../fields/List'; @@ -32,6 +32,11 @@ export class CollectionTimeView extends CollectionSubView() { @observable _viewDefDivClick: Opt; @observable _focusPivotField: Opt; + constructor(props: any) { + super(props); + makeObservable(this); + } + async componentDidMount() { this.props.setContentView?.(this); runInAction(() => { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 658d60523..7f8d42088 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -1,5 +1,6 @@ -import { action, computed, IReactionDisposer, makeObservable, observable, override, reaction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; @@ -7,7 +8,7 @@ import { listSpec } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { copyProps, emptyFunction, returnAll, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnOne, returnTrue, returnZero } from '../../../Utils'; +import { emptyFunction, returnAll, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnOne, returnTrue, returnZero } from '../../../Utils'; import { DocUtils } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from '../../util/DragManager'; @@ -23,10 +24,9 @@ import { FieldViewProps } from '../nodes/FieldView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { StyleProp } from '../StyleProvider'; import { CollectionFreeFormView } from './collectionFreeForm'; -import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; +import { CollectionSubView } from './CollectionSubView'; import './CollectionTreeView.scss'; import { TreeView } from './TreeView'; -import * as React from 'react'; const _global = (window /* browser */ || global) /* node */ as any; export type collectionTreeViewProps = { @@ -59,16 +59,10 @@ export class CollectionTreeView extends CollectionSubView = new Set(); // list of tree view items to monitor for height changes private observer: any; // observer for monitoring tree view items. - _prevProps: React.PropsWithChildren>; - @override _props: React.PropsWithChildren>; - constructor(props: React.PropsWithChildren>) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } get dataDoc() { return this._props.TemplateDataDocument || this.Document; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index e84c12e02..f1ef52e60 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -1,14 +1,14 @@ -import { IReactionDisposer, makeObservable, observable, override, reaction, runInAction, untracked } from 'mobx'; +import { IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { returnEmptyString } from '../../../Utils'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { ObjectField } from '../../../fields/ObjectField'; import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { copyProps, returnEmptyString } from '../../../Utils'; -import { DocUtils } from '../../documents/Documents'; import { CollectionViewType } from '../../documents/DocumentTypes'; +import { DocUtils } from '../../documents/Documents'; import { dropActionType } from '../../util/DragManager'; import { ImageUtils } from '../../util/Import & Export/ImageUtils'; import { ContextMenu } from '../ContextMenu'; @@ -19,19 +19,19 @@ import { FieldView, FieldViewProps } from '../nodes/FieldView'; import { CollectionCarousel3DView } from './CollectionCarousel3DView'; import { CollectionCarouselView } from './CollectionCarouselView'; import { CollectionDockingView } from './CollectionDockingView'; -import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; -import { CollectionGridView } from './collectionGrid/CollectionGridView'; -import { CollectionLinearView } from './collectionLinear'; -import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView'; -import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; import { CollectionNoteTakingView } from './CollectionNoteTakingView'; import { CollectionPileView } from './CollectionPileView'; -import { CollectionSchemaView } from './collectionSchema/CollectionSchemaView'; import { CollectionStackingView } from './CollectionStackingView'; import { SubCollectionViewProps } from './CollectionSubView'; import { CollectionTimeView } from './CollectionTimeView'; import { CollectionTreeView } from './CollectionTreeView'; import './CollectionView.scss'; +import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; +import { CollectionGridView } from './collectionGrid/CollectionGridView'; +import { CollectionLinearView } from './collectionLinear'; +import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView'; +import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; +import { CollectionSchemaView } from './collectionSchema/CollectionSchemaView'; const path = require('path'); interface CollectionViewProps_ extends FieldViewProps { @@ -78,16 +78,10 @@ export class CollectionView extends ViewBoxAnnotatableComponent; - @override _props: React.PropsWithChildren; constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); - runInAction(() => (this._annotationKeySuffix = returnEmptyString)); - } - componentDidUpdate() { - copyProps(this); + this._annotationKeySuffix = returnEmptyString; } componentDidMount() { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 8bc0f62dc..2eb13fd2f 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -2,40 +2,41 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Popup, Type } from 'browndash-components'; import { clamp } from 'lodash'; -import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx'; +import { IReactionDisposer, ObservableSet, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; +import { DashColor, Utils, emptyFunction, lightOrDark, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../../Utils'; import { Doc, Opt } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { FieldId } from '../../../fields/RefField'; +import { ComputedField } from '../../../fields/ScriptField'; import { Cast, DocCast, NumCast, StrCast } from '../../../fields/Types'; -import { copyProps, DashColor, emptyFunction, lightOrDark, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick, Utils } from '../../../Utils'; import { DocServer } from '../../DocServer'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; +import { Docs } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from '../../util/DragManager'; import { SelectionManager } from '../../util/SelectionManager'; import { SettingsManager } from '../../util/SettingsManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; -import { undoable, UndoManager } from '../../util/UndoManager'; +import { UndoManager, undoable } from '../../util/UndoManager'; import { DashboardView } from '../DashboardView'; -import { Colors } from '../global/globalEnums'; import { LightboxView } from '../LightboxView'; +import { ObservableReactComponent } from '../ObservableReactComponent'; +import { DefaultStyleProvider, StyleProp } from '../StyleProvider'; +import { Colors } from '../global/globalEnums'; import { DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere, OpenWhereMod } from '../nodes/DocumentView'; -import { DashFieldView } from '../nodes/formattedText/DashFieldView'; import { KeyValueBox } from '../nodes/KeyValueBox'; +import { DashFieldView } from '../nodes/formattedText/DashFieldView'; import { PinProps, PresBox, PresMovement } from '../nodes/trails'; -import { DefaultStyleProvider, StyleProp } from '../StyleProvider'; import { CollectionDockingView } from './CollectionDockingView'; -import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import { CollectionView } from './CollectionView'; import './TabDocView.scss'; -import * as React from 'react'; -import { Docs } from '../../documents/Documents'; -import { ComputedField } from '../../../fields/ScriptField'; +import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; const _global = (window /* browser */ || global) /* node */ as any; interface TabDocViewProps { @@ -44,16 +45,13 @@ interface TabDocViewProps { glContainer: any; } @observer -export class TabDocView extends React.Component { +export class TabDocView extends ObservableReactComponent { static _allTabs = new ObservableSet(); _mainCont: HTMLDivElement | null = null; _tabReaction: IReactionDisposer | undefined; - _prevProps: React.PropsWithChildren; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } @@ -341,9 +339,8 @@ export class TabDocView extends React.Component { // { fireImmediately: true }); runInAction(() => TabDocView._allTabs.add(this)); } - componentDidUpdate() { + componentDidUpdate(prevProps: Readonly) { this._view && DocumentManager.Instance.AddView(this._view); - copyProps(this); } componentWillUnmount() { @@ -521,14 +518,14 @@ interface TabMiniThumbProps { miniTop: () => number; miniLeft: () => number; } -@observer + class TabMiniThumb extends React.Component { render() { return

; } } @observer -export class TabMinimapView extends React.Component { +export class TabMinimapView extends ObservableReactComponent { static miniStyleProvider = (doc: Opt, props: Opt, property: string): any => { if (doc) { switch (property.split(':')[0]) { @@ -556,12 +553,6 @@ export class TabMinimapView extends React.Component { } }; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { - super(props); - this._props = props; - makeObservable(this); - } @computed get renderBounds() { const compView = this._props.tabView()?.ComponentView as CollectionFreeFormView; const bounds = compView?.freeformData?.(true)?.bounds; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 224d74882..52ecdfbec 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -1,8 +1,10 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IconButton, Size } from 'browndash-components'; -import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; +import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { Utils, emptyFunction, lightOrDark, return18, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, simulateMouseClick } from '../../../Utils'; import { Doc, DocListCast, Field, FieldResult, Opt, StrListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; @@ -12,9 +14,8 @@ import { listSpec } from '../../../fields/Schema'; import { ComputedField, ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { copyProps, emptyFunction, lightOrDark, return18, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, simulateMouseClick, Utils } from '../../../Utils'; -import { Docs, DocUtils } from '../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; +import { DocUtils, Docs } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from '../../util/DragManager'; import { LinkManager } from '../../util/LinkManager'; @@ -22,19 +23,19 @@ import { ScriptingGlobals } from '../../util/ScriptingGlobals'; import { SettingsManager } from '../../util/SettingsManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; -import { undoable, undoBatch, UndoManager } from '../../util/UndoManager'; +import { UndoManager, undoBatch, undoable } from '../../util/UndoManager'; import { EditableView } from '../EditableView'; +import { ObservableReactComponent } from '../ObservableReactComponent'; +import { StyleProp } from '../StyleProvider'; import { DocumentView, DocumentViewInternal, DocumentViewProps, OpenWhere, StyleProviderFunc } from '../nodes/DocumentView'; import { FieldViewProps } from '../nodes/FieldView'; +import { KeyValueBox } from '../nodes/KeyValueBox'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; -import { KeyValueBox } from '../nodes/KeyValueBox'; -import { StyleProp } from '../StyleProvider'; import { CollectionTreeView, TreeViewType } from './CollectionTreeView'; import { CollectionView } from './CollectionView'; import { TreeSort } from './TreeSort'; import './TreeView.scss'; -import * as React from 'react'; const { default: { TREE_BULLET_WIDTH } } = require('../global/globalCssVariables.module.scss'); // prettier-ignore export interface TreeViewProps { @@ -86,7 +87,7 @@ const treeBulletWidth = function () { * treeView_ExpandedView : name of field whose contents are being displayed as the document's subtree */ @observer -export class TreeView extends React.Component { +export class TreeView extends ObservableReactComponent { static _editTitleOnLoad: Opt<{ id: string; parent: TreeView | CollectionTreeView | undefined }>; static _openTitleScript: Opt; static _openLevelScript: Opt; @@ -254,11 +255,8 @@ export class TreeView extends React.Component { static GetRunningChildren = new Map(); static ToggleChildrenRun = new Map void>(); - _prevProps: TreeViewProps; - @observable _props: TreeViewProps; constructor(props: TreeViewProps) { super(props); - this._props = this._prevProps = props; makeObservable(this); if (!TreeView._openLevelScript) { TreeView._openTitleScript = ScriptField.MakeScript('scriptContext.setEditTitle(documentView)', { scriptContext: 'any', documentView: 'any' }); @@ -297,8 +295,7 @@ export class TreeView extends React.Component { this._props.hierarchyIndex !== undefined && this._props.RemFromMap?.(this.Document, this._props.hierarchyIndex); } - componentDidUpdate() { - copyProps(this); + componentDidUpdate(prevProps: Readonly) { this._disposers.opening = reaction( () => this.treeViewOpen, open => !open && (this._renderCount = 20) diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx index dd7e12e41..0d5fcdaeb 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx @@ -1,8 +1,9 @@ -import { IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; +import { IReactionDisposer, makeObservable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { copyProps } from '../../../../Utils'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; import './CollectionFreeFormView.scss'; +import { copyProps } from '../../../../Utils'; /** * An Fsa Arc. The first array element is a test condition function that will be observed. @@ -47,14 +48,11 @@ export interface CollectionFreeFormInfoStateProps { } @observer -export class CollectionFreeFormInfoState extends React.Component { +export class CollectionFreeFormInfoState extends ObservableReactComponent { _disposers: IReactionDisposer[] = []; - _prevProps: React.PropsWithChildren; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } @@ -62,7 +60,7 @@ export class CollectionFreeFormInfoState extends React.Component this.State[key]); + return Object.keys(this.State ?? []).map(key => this.State?.[key]); } clearState = () => this._disposers.map(disposer => disposer()); @@ -84,8 +82,8 @@ export class CollectionFreeFormInfoState extends React.Component) { + copyProps(this, prevProps); this.clearState(); this.initState(); } @@ -93,6 +91,6 @@ export class CollectionFreeFormInfoState extends React.Component{this.State[StateMessage]}
; + return
{this.State?.[StateMessage]}
; } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx index f0a052c1d..4d3752c02 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx @@ -1,21 +1,13 @@ -import { IReactionDisposer, computed, observable, reaction, action, runInAction, makeObservable } from 'mobx'; +import { IReactionDisposer, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; -import { Doc } from '../../../../fields/Doc'; -import { ScriptField } from '../../../../fields/ScriptField'; -import { PresBox } from '../../nodes/trails/PresBox'; -import './CollectionFreeFormView.scss'; import * as React from 'react'; -import { CollectionFreeFormView } from './CollectionFreeFormView'; -import { NumCast } from '../../../../fields/Types'; +import { Doc } from '../../../../fields/Doc'; import { LinkManager } from '../../../util/LinkManager'; -import { InkTool } from '../../../../fields/InkField'; -import { LinkDocPreview } from '../../nodes/LinkDocPreview'; -import { DocumentLinksButton, DocButtonState } from '../../nodes/DocumentLinksButton'; -import { DocumentManager } from '../../../util/DocumentManager'; -import { CollectionFreeFormInfoState, infoState, StateMessage, infoArc, StateEntryFunc, InfoState } from './CollectionFreeFormInfoState'; -import { string32 } from 'pdfjs-dist/types/src/shared/util'; -import { any } from 'bluebird'; -import { copyProps } from '../../../../Utils'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; +import { DocButtonState } from '../../nodes/DocumentLinksButton'; +import { CollectionFreeFormInfoState, InfoState, StateEntryFunc, infoState } from './CollectionFreeFormInfoState'; +import { CollectionFreeFormView } from './CollectionFreeFormView'; +import './CollectionFreeFormView.scss'; export interface CollectionFreeFormInfoUIProps { Document: Doc; @@ -23,7 +15,7 @@ export interface CollectionFreeFormInfoUIProps { } @observer -export class CollectionFreeFormInfoUI extends React.Component { +export class CollectionFreeFormInfoUI extends ObservableReactComponent { private _disposers: { [name: string]: IReactionDisposer } = {}; @observable _currState: infoState | undefined = undefined; @@ -33,17 +25,12 @@ export class CollectionFreeFormInfoUI extends React.Component; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + + constructor(props: any) { super(props); - this._props = this._prevProps = this.props; makeObservable(this); this.currState = this.setupStates(); } - componentDidUpdate() { - copyProps(this); - } setCurrState = (state: infoState) => { if (state) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index be3d2439c..6337c8d34 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -1,19 +1,20 @@ import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, Field } from '../../../../fields/Doc'; import { Brushed, DocCss } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; import { Cast, NumCast, StrCast } from '../../../../fields/Types'; -import { copyProps, emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; +import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; import { LinkManager } from '../../../util/LinkManager'; import { SelectionManager } from '../../../util/SelectionManager'; import { SettingsManager } from '../../../util/SettingsManager'; import { SnappingManager } from '../../../util/SnappingManager'; import { Colors } from '../../global/globalEnums'; import { DocumentView } from '../../nodes/DocumentView'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; import './CollectionFreeFormLinkView.scss'; -import * as React from 'react'; export interface CollectionFreeFormLinkViewProps { A: DocumentView; @@ -24,22 +25,16 @@ export interface CollectionFreeFormLinkViewProps { // props.screentolocatransform @observer -export class CollectionFreeFormLinkView extends React.Component { +export class CollectionFreeFormLinkView extends ObservableReactComponent { @observable _opacity: number = 0; @observable _start = 0; _anchorDisposer: IReactionDisposer | undefined; _timeout: NodeJS.Timeout | undefined; - _prevProps: CollectionFreeFormLinkViewProps; - @observable _props: CollectionFreeFormLinkViewProps; - constructor(props: CollectionFreeFormLinkViewProps) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } componentWillUnmount() { this._anchorDisposer?.(); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index aa40fb809..1f4688729 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,6 +1,6 @@ import { Bezier } from 'bezier-js'; import { Colors } from 'browndash-components'; -import { action, computed, IReactionDisposer, makeObservable, observable, override, reaction, runInAction, toJS } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction, toJS } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; import * as React from 'react'; @@ -16,7 +16,7 @@ import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../ import { ImageField } from '../../../../fields/URLField'; import { TraceMobx } from '../../../../fields/util'; import { GestureUtils } from '../../../../pen-gestures/GestureUtils'; -import { aggregateBounds, copyProps, DashColor, emptyFunction, intersectRect, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils'; +import { aggregateBounds, DashColor, emptyFunction, intersectRect, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils'; import { CognitiveServices } from '../../../cognitive_services/CognitiveServices'; import { Docs, DocUtils } from '../../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; @@ -43,7 +43,7 @@ import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { PinProps, PresBox } from '../../nodes/trails/PresBox'; import { CreateImage } from '../../nodes/WebBoxRenderer'; import { StyleProp } from '../../StyleProvider'; -import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; +import { CollectionSubView } from '../CollectionSubView'; import { TreeViewType } from '../CollectionTreeView'; import { CollectionFreeFormBackgroundGrid } from './CollectionFreeFormBackgroundGrid'; import { CollectionFreeFormInfoUI } from './CollectionFreeFormInfoUI'; @@ -72,17 +72,10 @@ export class CollectionFreeFormView extends CollectionSubView>; - @override _props: React.PropsWithChildren>; constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } - @observable public static ShowPresPaths = false; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index 825bd5f19..7aa68b0d9 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -20,7 +20,6 @@ export class MarqueeOptionsMenu extends AntimodeMenu { public isShown = () => this._opacity > 0; constructor(props: Readonly<{}>) { super(props); - MarqueeOptionsMenu.Instance = this; } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 10beb120a..2c65726b2 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -1,5 +1,7 @@ import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { Utils, intersectRect, lightOrDark, returnFalse } from '../../../../Utils'; import { Doc, Opt } from '../../../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit, DocData } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; @@ -7,25 +9,24 @@ import { InkData, InkField, InkTool } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; import { RichTextField } from '../../../../fields/RichTextField'; import { Cast, FieldValue, NumCast, StrCast } from '../../../../fields/Types'; -import { ImageField, nullAudio } from '../../../../fields/URLField'; +import { ImageField } from '../../../../fields/URLField'; import { GetEffectiveAcl } from '../../../../fields/util'; -import { intersectRect, lightOrDark, returnFalse, Utils } from '../../../../Utils'; import { CognitiveServices } from '../../../cognitive_services/CognitiveServices'; -import { Docs, DocumentOptions, DocUtils } from '../../../documents/Documents'; import { DocumentType } from '../../../documents/DocumentTypes'; +import { DocUtils, Docs, DocumentOptions } from '../../../documents/Documents'; import { SelectionManager } from '../../../util/SelectionManager'; +import { freeformScrollMode } from '../../../util/SettingsManager'; import { Transform } from '../../../util/Transform'; -import { undoBatch, UndoManager } from '../../../util/UndoManager'; +import { UndoManager, undoBatch } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; +import { PreviewCursor } from '../../PreviewCursor'; import { DocumentView, OpenWhere } from '../../nodes/DocumentView'; -import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { pasteImageBitmap } from '../../nodes/WebBoxRenderer'; -import { PreviewCursor } from '../../PreviewCursor'; +import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { SubCollectionViewProps } from '../CollectionSubView'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './MarqueeView.scss'; -import * as React from 'react'; -import { freeformScrollMode } from '../../../util/SettingsManager'; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -51,16 +52,14 @@ export interface MarqueeViewBounds { } @observer -export class MarqueeView extends React.Component { +export class MarqueeView extends ObservableReactComponent { public static CurViewBounds(pinDoc: Doc, panelWidth: number, panelHeight: number) { const ps = NumCast(pinDoc._freeform_scale, 1); return { left: NumCast(pinDoc._freeform_panX) - panelWidth / 2 / ps, top: NumCast(pinDoc._freeform_panY) - panelHeight / 2 / ps, width: panelWidth / ps, height: panelHeight / ps }; } - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = props; makeObservable(this); } diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 697a11ccc..1e19964d7 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -1,4 +1,4 @@ -import { action, computed, Lambda, observable, reaction } from 'mobx'; +import { action, computed, Lambda, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, Opt } from '../../../../fields/Doc'; @@ -27,6 +27,11 @@ export class CollectionGridView extends CollectionSubView() { @observable private _scroll: number = 0; // required to make sure the decorations box container updates on scroll private dropLocation: object = {}; // sets the drop location for external drops + constructor(props: any) { + super(props); + makeObservable(this); + } + onChildClickHandler = () => ScriptCast(this.Document.onChildClick); @computed get numCols() { diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index a9782f699..f1fb68003 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -1,26 +1,26 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { Toggle, ToggleType, Type } from 'browndash-components'; -import { action, IReactionDisposer, makeObservable, observable, override, reaction, runInAction, untracked } from 'mobx'; +import { IReactionDisposer, action, makeObservable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { Utils, emptyFunction, returnEmptyDoclist, returnTrue } from '../../../../Utils'; import { Doc, Opt } from '../../../../fields/Doc'; import { Height, Width } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; -import { copyProps, emptyFunction, returnEmptyDoclist, returnTrue, Utils } from '../../../../Utils'; import { CollectionViewType } from '../../../documents/DocumentTypes'; import { BranchingTrailManager } from '../../../util/BranchingTrailManager'; import { DocumentManager } from '../../../util/DocumentManager'; import { DragManager, dropActionType } from '../../../util/DragManager'; import { SettingsManager } from '../../../util/SettingsManager'; import { Transform } from '../../../util/Transform'; +import { UndoStack } from '../../UndoStack'; import { DocumentLinksButton } from '../../nodes/DocumentLinksButton'; import { DocumentView } from '../../nodes/DocumentView'; import { LinkDescriptionPopup } from '../../nodes/LinkDescriptionPopup'; -import { UndoStack } from '../../UndoStack'; import { CollectionStackedTimeline } from '../CollectionStackedTimeline'; -import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; +import { CollectionSubView } from '../CollectionSubView'; import './CollectionLinearView.scss'; /** @@ -33,24 +33,15 @@ import './CollectionLinearView.scss'; */ @observer export class CollectionLinearView extends CollectionSubView() { - @observable public addMenuToggle = React.createRef(); - @observable private _selectedIndex = -1; private _dropDisposer?: DragManager.DragDropDisposer; private _widthDisposer?: IReactionDisposer; private _selectedDisposer?: IReactionDisposer; - _prevProps: SubCollectionViewProps; - @override _props: SubCollectionViewProps; - constructor(props: SubCollectionViewProps) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } - componentWillUnmount() { this._dropDisposer?.(); this._widthDisposer?.(); diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 037786abf..b951a4b17 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { Button } from 'browndash-components'; -import { action, computed } from 'mobx'; +import { action, computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../../fields/Doc'; @@ -37,6 +37,11 @@ const resizerWidth = 8; @observer export class CollectionMulticolumnView extends CollectionSubView() { + constructor(props: any) { + super(props); + makeObservable(this); + } + /** * @returns the list of layout documents whose width unit is * *, denoting that it will be displayed with a ratio, not fixed pixel, value @@ -238,8 +243,8 @@ export class CollectionMulticolumnView extends CollectionSubView() { return this.props.isContentActive?.() === false || childDocsActive === false ? false // : this.props.isDocumentActive?.() && childDocsActive - ? true - : undefined; + ? true + : undefined; }; getDisplayDoc = (childLayout: Doc) => { const width = () => this.lookupPixels(childLayout); diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index bbf3481dd..f1c6c6e1e 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -1,4 +1,4 @@ -import { action, computed } from 'mobx'; +import { action, computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../../fields/Doc'; @@ -33,6 +33,11 @@ const resizerHeight = 8; @observer export class CollectionMultirowView extends CollectionSubView() { + constructor(props: any) { + super(props); + makeObservable(this); + } + /** * @returns the list of layout documents whose width unit is * *, denoting that it will be displayed with a ratio, not fixed pixel, value @@ -234,8 +239,8 @@ export class CollectionMultirowView extends CollectionSubView() { return this.props.isContentActive?.() === false || childDocsActive === false ? false // : this.props.isDocumentActive?.() && childDocsActive - ? true - : undefined; + ? true + : undefined; }; getDisplayDoc = (layout: Doc) => { const height = () => this.lookupPixels(layout); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 276415d56..2546f5b02 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -1,13 +1,13 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, makeObservable, observable, ObservableMap, observe, override } from 'mobx'; +import { action, computed, makeObservable, observable, ObservableMap, observe } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast, Field, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; import { listSpec } from '../../../../fields/Schema'; import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types'; -import { copyProps, emptyFunction, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils'; import { Docs, DocumentOptions, DocUtils, FInfo } from '../../../documents/Documents'; import { DocumentManager } from '../../../util/DocumentManager'; import { DragManager } from '../../../util/DragManager'; @@ -18,8 +18,9 @@ import { EditableView } from '../../EditableView'; import { Colors } from '../../global/globalEnums'; import { DocFocusOptions, DocumentView, DocumentViewProps } from '../../nodes/DocumentView'; import { KeyValueBox } from '../../nodes/KeyValueBox'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DefaultStyleProvider, StyleProp } from '../../StyleProvider'; -import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; +import { CollectionSubView } from '../CollectionSubView'; import './CollectionSchemaView.scss'; import { SchemaColumnHeader } from './SchemaColumnHeader'; import { SchemaRowBox } from './SchemaRowBox'; @@ -57,6 +58,11 @@ export class CollectionSchemaView extends CollectionSubView() { private _tableContentRef: HTMLDivElement | null = null; private _menuTarget = React.createRef(); + constructor(props: any) { + super(props); + makeObservable(this); + } + static _rowHeight: number = 50; static _rowSingleLineHeight: number = 32; public static _minColWidth: number = 25; @@ -79,18 +85,6 @@ export class CollectionSchemaView extends CollectionSubView() { @observable _filterSearchValue: string = ''; @observable _selectedCell: [Doc, number] | undefined = undefined; - _prevProps: SubCollectionViewProps; - @override _props: SubCollectionViewProps; - constructor(props: SubCollectionViewProps) { - super(props); - this._props = this._prevProps = props; - makeObservable(this); - } - - componentDidUpdate() { - copyProps(this); - } - // target HTMLelement portal for showing a popup menu to edit cell values. public get MenuTarget() { return this._menuTarget.current; @@ -959,17 +953,12 @@ interface CollectionSchemaViewDocProps { } @observer -class CollectionSchemaViewDoc extends React.Component { - _prevProps: CollectionSchemaViewDocProps; - @observable _props; - constructor(props: CollectionSchemaViewDocProps) { +class CollectionSchemaViewDoc extends ObservableReactComponent { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } + tableWidthFunc = () => this._props.schema.tableWidth; screenToLocalXf = () => this._props.schema._props.ScreenToLocalTransform().translate(0, -this._props.rowHeight() - this._props.index * this._props.rowHeight()); noOpacityStyleProvider = (doc: Opt, props: Opt, property: string) => { diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 737d7e0f4..5a3be826b 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -1,13 +1,13 @@ -import * as React from 'react'; import { IconButton, Size } from 'browndash-components'; -import { computed, makeObservable, override } from 'mobx'; +import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; +import * as React from 'react'; import { CgClose } from 'react-icons/cg'; import { FaExternalLinkAlt } from 'react-icons/fa'; +import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../../Utils'; import { Doc } from '../../../../fields/Doc'; import { BoolCast } from '../../../../fields/Types'; -import { copyProps, emptyFunction, returnFalse, setupMoveUpEvents } from '../../../../Utils'; import { DragManager } from '../../../util/DragManager'; import { SnappingManager } from '../../../util/SnappingManager'; import { Transform } from '../../../util/Transform'; @@ -30,16 +30,10 @@ export class SchemaRowBox extends ViewBoxBaseComponent this._ref?.getBoundingClientRect(); diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index bcfe2c232..85269028b 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -1,27 +1,28 @@ -import * as React from 'react'; -import Select, { MenuPlacement } from 'react-select'; import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import { extname } from 'path'; +import * as React from 'react'; import DatePicker from 'react-datepicker'; +import Select from 'react-select'; +import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../../Utils'; import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast, Field } from '../../../../fields/Doc'; import { RichTextField } from '../../../../fields/RichTextField'; import { BoolCast, Cast, DateCast, DocCast, FieldValue, StrCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; -import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero, Utils } from '../../../../Utils'; import { FInfo } from '../../../documents/Documents'; import { DocFocusOrOpen } from '../../../util/DocumentManager'; import { Transform } from '../../../util/Transform'; -import { undoable, undoBatch } from '../../../util/UndoManager'; +import { undoBatch, undoable } from '../../../util/UndoManager'; import { EditableView } from '../../EditableView'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; +import { DefaultStyleProvider } from '../../StyleProvider'; import { Colors } from '../../global/globalEnums'; import { OpenWhere } from '../../nodes/DocumentView'; -import { FieldView, FieldViewProps } from '../../nodes/FieldView'; -import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; +import { FieldViewProps } from '../../nodes/FieldView'; import { KeyValueBox } from '../../nodes/KeyValueBox'; -import { DefaultStyleProvider } from '../../StyleProvider'; -import { CollectionSchemaView, ColumnType, FInfotoColType } from './CollectionSchemaView'; +import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; +import { ColumnType, FInfotoColType } from './CollectionSchemaView'; import './CollectionSchemaView.scss'; export interface SchemaTableCellProps { @@ -47,7 +48,12 @@ export interface SchemaTableCellProps { } @observer -export class SchemaTableCell extends React.Component { +export class SchemaTableCell extends ObservableReactComponent { + constructor(props: any) { + super(props); + makeObservable(this); + } + static addFieldDoc = (doc: Doc, where: OpenWhere) => { DocFocusOrOpen(doc); return true; @@ -95,12 +101,6 @@ export class SchemaTableCell extends React.Component { return { color, textDecoration, fieldProps, cursor, pointerEvents }; } - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { - super(props); - this._props = props; - } - @computed get selected() { const selected: [Doc, number] | undefined = this._props.selectedCell(); return this._props.isRowActive() && selected?.[0] === this._props.Document && selected[1] === this._props.col; @@ -182,16 +182,14 @@ export class SchemaTableCell extends React.Component { // mj: most of this is adapted from old schema code so I'm not sure what it does tbh @observer -export class SchemaImageCell extends React.Component { - @observable _previewRef: HTMLImageElement | undefined = undefined; - - _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { +export class SchemaImageCell extends ObservableReactComponent { + constructor(props: any) { super(props); - this._props = props; makeObservable(this); } + @observable _previewRef: HTMLImageElement | undefined = undefined; + choosePath(url: URL) { if (url.protocol === 'data') return url.href; // if the url ises the data protocol, just return the href if (url.href.indexOf(window.location.origin) === -1) return Utils.CorsProxy(url.href); // otherwise, put it through the cors proxy erver @@ -251,16 +249,13 @@ export class SchemaImageCell extends React.Component { } @observer -export class SchemaDateCell extends React.Component { - @observable _pickingDate: boolean = false; - - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { +export class SchemaDateCell extends ObservableReactComponent { + constructor(props: any) { super(props); - this._props = props; makeObservable(this); } + @observable _pickingDate: boolean = false; @computed get date(): DateField { // if the cell is a date field, cast then contents to a date. Otherrwwise, make the contents undefined. return DateCast(this._props.Document[this._props.fieldKey]); @@ -282,11 +277,9 @@ export class SchemaDateCell extends React.Component { } } @observer -export class SchemaRTFCell extends React.Component { - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { +export class SchemaRTFCell extends ObservableReactComponent { + constructor(props: any) { super(props); - this._props = props; makeObservable(this); } @@ -306,11 +299,9 @@ export class SchemaRTFCell extends React.Component { } } @observer -export class SchemaBoolCell extends React.Component { - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { +export class SchemaBoolCell extends ObservableReactComponent { + constructor(props: any) { super(props); - this._props = props; makeObservable(this); } @@ -352,11 +343,9 @@ export class SchemaBoolCell extends React.Component { } } @observer -export class SchemaEnumerationCell extends React.Component { - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { +export class SchemaEnumerationCell extends ObservableReactComponent { + constructor(props: any) { super(props); - this._props = props; makeObservable(this); } diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index af22f41e1..b7376e901 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -1,13 +1,14 @@ import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc } from '../../../fields/Doc'; import { LinkManager } from '../../util/LinkManager'; +import { SettingsManager } from '../../util/SettingsManager'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import { DocumentView } from '../nodes/DocumentView'; import { LinkInfo } from '../nodes/LinkDocPreview'; import './LinkMenu.scss'; import { LinkMenuGroup } from './LinkMenuGroup'; -import * as React from 'react'; -import { SettingsManager } from '../../util/SettingsManager'; interface Props { docView: DocumentView; @@ -20,10 +21,10 @@ interface Props { * the outermost component for the link menu of a node that contains a list of its linked nodes */ @observer -export class LinkMenu extends React.Component { +export class LinkMenu extends ObservableReactComponent { _editorRef = React.createRef(); @observable _linkMenuRef = React.createRef(); - constructor(props: Props) { + constructor(props: any) { super(props); makeObservable(this); } diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index d77525e04..06073b52c 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -1,23 +1,24 @@ -import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, observable, makeObservable } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils'; import { Doc } from '../../../fields/Doc'; import { Cast, DocCast, StrCast } from '../../../fields/Types'; import { WebField } from '../../../fields/URLField'; -import { emptyFunction, returnFalse, setupMoveUpEvents, copyProps } from '../../../Utils'; -import { DocumentType } from '../../documents/DocumentTypes'; import { DragManager } from '../../util/DragManager'; import { LinkFollower } from '../../util/LinkFollower'; import { LinkManager } from '../../util/LinkManager'; 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 { LinkDocPreview, LinkInfo } from '../nodes/LinkDocPreview'; +import { LinkInfo } from '../nodes/LinkDocPreview'; import './LinkMenuItem.scss'; -import * as React from 'react'; +import { undoBatch } from '../../util/UndoManager'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; +import { DocumentType } from '../../documents/DocumentTypes'; interface LinkMenuItemProps { groupType: string; @@ -50,20 +51,13 @@ export async function StartLinkTargetsDrag(dragEle: HTMLElement, docView: Docume } @observer -export class LinkMenuItem extends React.Component { +export class LinkMenuItem extends ObservableReactComponent { private _drag = React.createRef(); _editRef = React.createRef(); - - _prevProps: React.PropsWithChildren; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } @observable private _showMore: boolean = false; @action toggleShowMore(e: React.PointerEvent) { diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 0c671f7e3..567cf193e 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -1,14 +1,14 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, IReactionDisposer, makeObservable, observable, override, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { DateField } from '../../../fields/DateField'; import { Doc } from '../../../fields/Doc'; import { ComputedField } from '../../../fields/ScriptField'; import { Cast, DateCast, NumCast } from '../../../fields/Types'; import { AudioField, nullAudio } from '../../../fields/URLField'; -import { copyProps, emptyFunction, formatTime, returnFalse, setupMoveUpEvents } from '../../../Utils'; +import { emptyFunction, formatTime, returnFalse, setupMoveUpEvents } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { Networking } from '../../Network'; import { DragManager } from '../../util/DragManager'; @@ -17,7 +17,7 @@ import { undoBatch } from '../../util/UndoManager'; import { CollectionStackedTimeline, TrimScope } from '../collections/CollectionStackedTimeline'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; -import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent'; +import { ViewBoxAnnotatableComponent } from '../DocComponent'; import './AudioBox.scss'; import { DocFocusOptions } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; @@ -54,19 +54,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent() { return FieldView.LayoutString(AudioBox, fieldKey); } - _prevProps: React.PropsWithChildren; - @override _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + public static Enabled = false; + + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } - public static Enabled = false; - static topControlsHeight = 30; // height of upper controls above timeline static bottomControlsHeight = 20; // height of lower controls below timeline diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 8e7a6914f..c97c879af 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -1,21 +1,21 @@ -import { action, computed, observable, makeObservable, reaction, runInAction, override } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { OmitKeys, numberRange } from '../../../Utils'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; import { ComputedField } from '../../../fields/ScriptField'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { copyProps, numberRange, OmitKeys } from '../../../Utils'; import { DocumentManager } from '../../util/DocumentManager'; +import { ScriptingGlobals } from '../../util/ScriptingGlobals'; import { SelectionManager } from '../../util/SelectionManager'; -import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { DocComponent } from '../DocComponent'; import { StyleProp } from '../StyleProvider'; +import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import './CollectionFreeFormDocumentView.scss'; import { DocumentView, DocumentViewProps, OpenWhere } from './DocumentView'; -import * as React from 'react'; -import { ScriptingGlobals } from '../../util/ScriptingGlobals'; export interface CollectionFreeFormDocumentViewWrapperProps extends DocumentViewProps { x: number; @@ -37,11 +37,8 @@ export interface CollectionFreeFormDocumentViewWrapperProps extends DocumentView } @observer export class CollectionFreeFormDocumentViewWrapper extends DocComponent() implements CollectionFreeFormDocumentViewProps { - _prevProps: React.PropsWithChildren; - @override _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } @observable X = this.props.x; @@ -79,7 +76,7 @@ export class CollectionFreeFormDocumentViewWrapper extends DocComponent this.Highlight; // prettier-ignore w_Width = () => this.Width; // prettier-ignore w_Height = () => this.Height; // prettier-ignore - w_AutoDim = () => this.AutoDim; + w_AutoDim = () => this.AutoDim; // prettier-ignore w_Transition = () => this.Transition; // prettier-ignore w_DataTransition = () => this.DataTransition; // prettier-ignore @@ -87,7 +84,6 @@ export class CollectionFreeFormDocumentViewWrapper extends DocComponent this._props.autoDim ? this._props.PanelHeight?.() : this.Height; // prettier-ignore componentDidUpdate() { - copyProps(this); this.WrapperKeys.forEach(action(keys => ((this as any)[keys.upper] = (this.props as any)[keys.lower]))); } render() { @@ -124,6 +120,10 @@ export interface CollectionFreeFormDocumentViewProps { @observer export class CollectionFreeFormDocumentView extends DocComponent() { + constructor(props: any) { + super(props); + makeObservable(this); + } get displayName() { // this makes mobx trace() statements more descriptive return 'CollectionFreeFormDocumentView(' + this.Document.title + ')'; } // prettier-ignore @@ -143,13 +143,6 @@ export class CollectionFreeFormDocumentView extends DocComponent (Doc.LayoutFieldKey(doc) ? [Doc.LayoutFieldKey(doc)] : []); // fields that are configured to be animatable using animation frames - _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { - super(props); - this._props = Object.assign({}, props); - makeObservable(this); - } - get CollectionFreeFormView() { return this._props.CollectionFreeFormView; } diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 62523ba00..de382fca5 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -1,10 +1,11 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, makeObservable, observable, override } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { emptyFunction, returnFalse, returnNone, returnZero, setupMoveUpEvents } from '../../../Utils'; import { Doc, Opt } from '../../../fields/Doc'; import { DocCast, NumCast, StrCast } from '../../../fields/Types'; -import { copyProps, emptyFunction, returnFalse, returnNone, returnZero, setupMoveUpEvents } from '../../../Utils'; -import { Docs, DocUtils } from '../../documents/Documents'; +import { DocUtils, Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { undoBatch } from '../../util/UndoManager'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent'; @@ -13,7 +14,6 @@ import './ComparisonBox.scss'; import { DocumentView, DocumentViewProps } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import { PinProps, PresBox } from './trails'; -import * as React from 'react'; @observer export class ComparisonBox extends ViewBoxAnnotatableComponent() { @@ -21,20 +21,12 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { } @observer -export class DocumentContentsView extends React.Component< +export class DocumentContentsView extends ObservableReactComponent< DocumentViewProps & FieldViewProps & { setHeight?: (height: number) => void; layout_fieldKey: string; } > { - @observable _props!: DocumentViewProps & - FieldViewProps & { - setHeight?: (height: number) => void; - layout_fieldKey: string; - }; constructor(props: any) { super(props); - this._props = props; makeObservable(this); } - componentDidUpdate(prevProps: Readonly void) | undefined; layout_fieldKey: string }>, prevState: Readonly<{}>, snapshot?: any): void { - // untracked(() => (this._props = this.props)); - // Object.keys(prevProps).forEach(pkey => (prevProps as any)[pkey] !== (this._props as any)[pkey] && console.log(pkey + ' ' + (prevProps as any)[pkey] + ' ' + (this._props as any)[pkey])); - } - @computed get layout(): string { TraceMobx(); if (this._props.LayoutTemplateString) return this._props.LayoutTemplateString; diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx index 9ec4d8c13..dfd610581 100644 --- a/src/client/views/nodes/DocumentIcon.tsx +++ b/src/client/views/nodes/DocumentIcon.tsx @@ -1,34 +1,28 @@ +import { Tooltip } from '@mui/material'; +import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { DocumentView } from './DocumentView'; -import { DocumentManager } from '../../util/DocumentManager'; -import { Transformer, ts } from '../../util/Scripting'; +import { factory } from 'typescript'; import { Field } from '../../../fields/Doc'; -import { Tooltip } from '@mui/material'; -import { action, makeObservable, observable } from 'mobx'; import { Id } from '../../../fields/FieldSymbols'; -import { factory } from 'typescript'; -import { LightboxView } from '../LightboxView'; +import { DocumentManager } from '../../util/DocumentManager'; +import { Transformer, ts } from '../../util/Scripting'; import { SettingsManager } from '../../util/SettingsManager'; -import { copyProps } from '../../../Utils'; +import { LightboxView } from '../LightboxView'; +import { ObservableReactComponent } from '../ObservableReactComponent'; +import { DocumentView } from './DocumentView'; interface DocumentIconProps { view: DocumentView; index: number; } @observer -export class DocumentIcon extends React.Component { +export class DocumentIcon extends ObservableReactComponent { @observable _hovered = false; - _prevProps: DocumentIconProps; - @observable _props: DocumentIconProps; - constructor(props: DocumentIconProps) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } static get DocViews() { return LightboxView.LightboxDoc ? DocumentManager.Instance.DocumentViews.filter(v => LightboxView.IsLightboxDocView(v._props.docViewPath())) : DocumentManager.Instance.DocumentViews; diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 19b43fd52..165057d21 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -2,20 +2,21 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { StopEvent, emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils'; import { Doc } from '../../../fields/Doc'; import { StrCast } from '../../../fields/Types'; -import { copyProps, emptyFunction, returnFalse, setupMoveUpEvents, StopEvent } from '../../../Utils'; import { DocUtils } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { Hypothesis } from '../../util/HypothesisUtils'; import { LinkManager } from '../../util/LinkManager'; -import { undoBatch, UndoManager } from '../../util/UndoManager'; +import { UndoManager, undoBatch } from '../../util/UndoManager'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import './DocumentLinksButton.scss'; import { DocumentView } from './DocumentView'; import { LinkDescriptionPopup } from './LinkDescriptionPopup'; import { TaskCompletionBox } from './TaskCompletedBox'; import { PinProps } from './trails'; -import * as React from 'react'; interface DocumentLinksButtonProps { View: DocumentView; @@ -44,26 +45,18 @@ export class DocButtonState { } } @observer -export class DocumentLinksButton extends React.Component { +export class DocumentLinksButton extends ObservableReactComponent { private _linkButton = React.createRef(); public static get StartLink() { return DocButtonState.Instance.StartLink; } // prettier-ignore public static set StartLink(value) { runInAction(() => (DocButtonState.Instance.StartLink = value)); } // prettier-ignore @observable public static StartLinkView: DocumentView | undefined = undefined; @observable public static AnnotationId: string | undefined = undefined; @observable public static AnnotationUri: string | undefined = undefined; - - _prevProps: React.PropsWithChildren; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } - @undoBatch onLinkButtonMoved = (e: PointerEvent) => { if (this._props.InMenu && this._props.StartLink) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 08ee708f7..343f770d5 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,9 +1,11 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { Dropdown, DropdownType, Type } from 'browndash-components'; -import { action, computed, IReactionDisposer, makeObservable, observable, override, reaction, runInAction, untracked } from 'mobx'; +import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; // import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal'; +import * as React from 'react'; +import { Utils, emptyFunction, isTargetChildOf as isParentOf, lightOrDark, returnEmptyString, returnFalse, returnTrue, returnVal, simulateMouseClick } from '../../../Utils'; import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc'; import { AclPrivate, Animation, AudioPlay, DocViews } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; @@ -15,12 +17,11 @@ import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, ImageCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { AudioField } from '../../../fields/URLField'; import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; -import { copyProps, emptyFunction, isTargetChildOf as isParentOf, lightOrDark, returnEmptyString, returnFalse, returnTrue, returnVal, simulateMouseClick, Utils } from '../../../Utils'; -import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { DocServer } from '../../DocServer'; -import { DocOptions, Docs, DocUtils, FInfo } from '../../documents/Documents'; -import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; import { Networking } from '../../Network'; +import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; +import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; +import { DocOptions, DocUtils, Docs, FInfo } from '../../documents/Documents'; import { DictationManager } from '../../util/DictationManager'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from '../../util/DragManager'; @@ -32,13 +33,14 @@ import { SettingsManager } from '../../util/SettingsManager'; import { SharingManager } from '../../util/SharingManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; -import { undoBatch, UndoManager } from '../../util/UndoManager'; +import { UndoManager, undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { DocComponent } from '../DocComponent'; import { EditableView } from '../EditableView'; import { GestureOverlay } from '../GestureOverlay'; import { LightboxView } from '../LightboxView'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import { StyleProp } from '../StyleProvider'; import { UndoStack } from '../UndoStack'; import { CollectionFreeFormDocumentView } from './CollectionFreeFormDocumentView'; @@ -46,12 +48,11 @@ import { DocumentContentsView, ObserverJsxParser } from './DocumentContentsView' import { DocumentLinksButton } from './DocumentLinksButton'; import './DocumentView.scss'; import { FieldViewProps } from './FieldView'; -import { FormattedTextBox } from './formattedText/FormattedTextBox'; import { KeyValueBox } from './KeyValueBox'; import { LinkAnchorBox } from './LinkAnchorBox'; +import { FormattedTextBox } from './formattedText/FormattedTextBox'; import { PresEffect, PresEffectDirection } from './trails'; import { PinProps, PresBox } from './trails/PresBox'; -import * as React from 'react'; const { Howl } = require('howler'); interface Window { @@ -253,20 +254,11 @@ export class DocumentViewInternal extends DocComponent(); private _titleRef = React.createRef(); private _dropDisposer?: DragManager.DragDropDisposer; - - @override _props: DocumentViewInternalProps; - _prevProps: DocumentViewInternalProps; - - constructor(props: DocumentViewInternalProps) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - // untracked(() => (this._props = this._props)); - } - @observable _componentView: Opt; // needs to be accessed from DocumentView wrapper class @observable _animateScaleTime: Opt; // milliseconds for animating between views. defaults to 300 if not uset @observable _animateScalingTo = 0; @@ -1329,19 +1321,13 @@ export class DocumentViewInternal extends DocComponent { +export class DocumentView extends ObservableReactComponent { public static ROOT_DIV = 'documentView-effectsWrapper'; - @observable _props: DocumentViewProps; - _prevProps: DocumentViewProps; constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } @observable _selected = false; public get SELECTED() { diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index 02ed56333..ff92c701f 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -1,5 +1,4 @@ -import EquationEditor from './formattedText/EquationEditor'; -import { action, makeObservable, override, reaction } from 'mobx'; +import { action, makeObservable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Id } from '../../../fields/FieldSymbols'; @@ -11,7 +10,7 @@ import { ViewBoxBaseComponent } from '../DocComponent'; import { LightboxView } from '../LightboxView'; import './EquationBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; -import { copyProps } from '../../../Utils'; +import EquationEditor from './formattedText/EquationEditor'; @observer export class EquationBox extends ViewBoxBaseComponent() { @@ -21,18 +20,11 @@ export class EquationBox extends ViewBoxBaseComponent() { public static SelectOnLoad: string = ''; _ref: React.RefObject = React.createRef(); - _prevProps: React.PropsWithChildren; - @override _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } - componentDidMount() { this._props.setContentView?.(this); if (EquationBox.SelectOnLoad === this.Document[Id] && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this._props.docViewPath()))) { diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index d8b1f125c..5a8665aaf 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -1,13 +1,13 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button, ColorPicker, Dropdown, DropdownType, EditableText, IconButton, IListItemProps, MultiToggle, NumberDropdown, NumberDropdownType, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components'; -import { computed, makeObservable, observable, override } from 'mobx'; +import { computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc'; import { ScriptField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; -import { copyProps, emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; +import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { SelectionManager } from '../../../util/SelectionManager'; import { SettingsManager } from '../../../util/SettingsManager'; @@ -45,16 +45,11 @@ export class FontIconBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FontIconBox, fieldKey); } - _prevProps: React.PropsWithChildren; - @override _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } // // This controls whether fontIconButtons will display labels under their icons or not // @@ -64,6 +59,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { public static set ShowIconLabels(show: boolean) { Doc.UserDoc()._showLabel = show; } + @observable noTooltip = false; showTemplate = (): void => { const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null); diff --git a/src/client/views/nodes/FunctionPlotBox.tsx b/src/client/views/nodes/FunctionPlotBox.tsx index a04c27e01..29bffb583 100644 --- a/src/client/views/nodes/FunctionPlotBox.tsx +++ b/src/client/views/nodes/FunctionPlotBox.tsx @@ -1,15 +1,12 @@ import functionPlot from 'function-plot'; -import { action, computed, makeObservable, override, reaction } from 'mobx'; +import { computed, makeObservable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; -import { documentSchema } from '../../../fields/documentSchemas'; -import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; -import { createSchema, listSpec, makeInterface } from '../../../fields/Schema'; +import { listSpec } from '../../../fields/Schema'; import { Cast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { copyProps } from '../../../Utils'; import { Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { undoBatch } from '../../util/UndoManager'; @@ -27,19 +24,12 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent _plotId = ''; _plotEle: any; - _prevProps: React.PropsWithChildren; - @override _props: React.PropsWithChildren; constructor(props: React.PropsWithChildren) { super(props); - this._props = this._prevProps = props; makeObservable(this); this._plotId = 'graph' + FunctionPlotBox.GraphCount++; } - componentDidUpdate() { - copyProps(this); - } - componentDidMount() { this._props.setContentView?.(this); reaction( diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 091c1a32f..b1ccd38ba 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,6 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, override, reaction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { extname } from 'path'; import * as React from 'react'; @@ -12,7 +12,7 @@ import { ObjectField } from '../../../fields/ObjectField'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; -import { copyProps, DashColor, emptyFunction, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils'; +import { DashColor, emptyFunction, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; @@ -55,19 +55,11 @@ export class ImageBox extends ViewBoxAnnotatableComponent(); @observable _curSuffix = ''; - _prevProps: ViewBoxAnnotatableProps & FieldViewProps; - @override _props: ViewBoxAnnotatableProps & FieldViewProps; constructor(props: ViewBoxAnnotatableProps & FieldViewProps) { super(props); - this._props = this._prevProps = props; - makeObservable(this); this._props.setContentView?.(this); } - componentDidUpdate() { - copyProps(this); - } - protected createDropTarget = (ele: HTMLDivElement) => { this._dropDisposer?.(); ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.Document)); diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 9aab53daf..73fdc3a23 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -1,26 +1,27 @@ import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { returnAlways, returnTrue } from '../../../Utils'; import { Doc, Field, FieldResult } 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 { copyProps, returnAll, returnAlways, returnTrue } from '../../../Utils'; import { Docs } from '../../documents/Documents'; import { SetupDrag } from '../../util/DragManager'; -import { CompiledScript, CompileScript, ScriptOptions } from '../../util/Scripting'; +import { CompileScript, CompiledScript, ScriptOptions } from '../../util/Scripting'; import { undoBatch } from '../../util/UndoManager'; 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 { FormattedTextBox } from './formattedText/FormattedTextBox'; import { ImageBox } from './ImageBox'; import './KeyValueBox.scss'; import { KeyValuePair } from './KeyValuePair'; -import * as React from 'react'; +import { FormattedTextBox } from './formattedText/FormattedTextBox'; export type KVPScript = { script: CompiledScript; @@ -28,28 +29,20 @@ export type KVPScript = { onDelegate: boolean; }; @observer -export class KeyValueBox extends React.Component { +export class KeyValueBox extends ObservableReactComponent { public static LayoutString() { return FieldView.LayoutString(KeyValueBox, 'data'); } + constructor(props: any) { + super(props); + makeObservable(this); + } private _mainCont = React.createRef(); private _keyHeader = React.createRef(); private _keyInput = React.createRef(); private _valInput = React.createRef(); - _prevProps: FieldViewProps; - @observable _props: FieldViewProps; - constructor(props: FieldViewProps) { - super(props); - this._props = this._prevProps = props; - makeObservable(this); - } - - componentDidUpdate() { - copyProps(this); - } - componentDidMount() { this._props.setContentView?.(this); } diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 40991f371..fd8d8ef56 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -1,21 +1,23 @@ -import { action, makeObservable, observable, toJS } from 'mobx'; +import { Tooltip } from '@mui/material'; +import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; +import { ObservableGroupMap } from 'mobx-utils'; +import * as React from 'react'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../Utils'; import { Doc, Field } from '../../../fields/Doc'; -import { copyProps, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../Utils'; +import { DocCast } from '../../../fields/Types'; +import { DocumentOptions, FInfo } from '../../documents/Documents'; import { Transform } from '../../util/Transform'; import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { EditableView } from '../EditableView'; import { DefaultStyleProvider } from '../StyleProvider'; -import { OpenWhere, OpenWhereMod } from './DocumentView'; -import { FieldView, FieldViewProps } from './FieldView'; +import { OpenWhere } from './DocumentView'; +import { FieldViewProps } from './FieldView'; import { KeyValueBox } from './KeyValueBox'; import './KeyValueBox.scss'; import './KeyValuePair.scss'; -import * as React from 'react'; -import { DocCast } from '../../../fields/Types'; -import { Tooltip } from '@mui/material'; -import { DocumentOptions, FInfo } from '../../documents/Documents'; +import { ObservableReactComponent } from '../ObservableReactComponent'; // Represents one row in a key value plane @@ -29,22 +31,15 @@ export interface KeyValuePairProps { addDocTab: (doc: Doc, where: OpenWhere) => boolean; } @observer -export class KeyValuePair extends React.Component { +export class KeyValuePair extends ObservableReactComponent { @observable private isPointerOver = false; @observable public isChecked = false; private checkbox = React.createRef(); - - _prevProps: KeyValuePairProps; - @observable _props: KeyValuePairProps; - constructor(props: KeyValuePairProps) { + constructor(props:any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } @action handleCheck = (e: React.ChangeEvent) => { diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index 52ca8b5b1..934bce448 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -1,11 +1,10 @@ -import { action, computed, makeObservable, observable, override } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; -import { Cast, StrCast, NumCast, BoolCast } from '../../../fields/Types'; -import { copyProps } from '../../../Utils'; +import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types'; import { DragManager } from '../../util/DragManager'; import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; @@ -31,16 +30,11 @@ export class LabelBox extends ViewBoxBaseComponent; - @override _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } + componentDidMount() { this._props.setContentView?.(this); } diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index a7e905fca..b86ba72a0 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -1,9 +1,9 @@ -import { action, computed, makeObservable, observable, override } from 'mobx'; -import { observer } from 'mobx-react'; +import { action, computed, makeObservable } from 'mobx'; +import * as React from 'react'; +import { Utils, emptyFunction, setupMoveUpEvents } from '../../../Utils'; import { Doc } from '../../../fields/Doc'; import { NumCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, setupMoveUpEvents, Utils } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; import { LinkFollower } from '../../util/LinkFollower'; import { SelectionManager } from '../../util/SelectionManager'; @@ -12,11 +12,7 @@ import { StyleProp } from '../StyleProvider'; import { FieldView, FieldViewProps } from './FieldView'; import './LinkAnchorBox.scss'; import { LinkInfo } from './LinkDocPreview'; -import * as React from 'react'; -const { - default: { MEDIUM_GRAY }, -} = require('../global/globalCssVariables.module.scss'); -@observer +const { default: { MEDIUM_GRAY }, } = require('../global/globalCssVariables.module.scss'); // prettier-ignore export class LinkAnchorBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(LinkAnchorBox, fieldKey); @@ -26,14 +22,9 @@ export class LinkAnchorBox extends ViewBoxBaseComponent() { _ref = React.createRef(); _isOpen = false; _timeout: NodeJS.Timeout | undefined; - @observable _x = 0; - @observable _y = 0; - _prevProps: FieldViewProps; - @override _props: FieldViewProps; - constructor(props: FieldViewProps) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index acafd6d09..134f2e14a 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -1,10 +1,10 @@ -import * as React from 'react'; import { Bezier } from 'bezier-js'; -import { computed, IReactionDisposer, makeObservable, observable, override, reaction } from 'mobx'; +import { computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Id } from '../../../fields/FieldSymbols'; import { DocCast, NumCast, StrCast } from '../../../fields/Types'; -import { aggregateBounds, copyProps, emptyFunction, returnAlways, returnFalse, Utils } from '../../../Utils'; +import { aggregateBounds, emptyFunction, returnAlways, returnFalse, Utils } from '../../../Utils'; import { DocumentManager } from '../../util/DocumentManager'; import { Transform } from '../../util/Transform'; import { CollectionFreeFormView } from '../collections/collectionFreeForm'; @@ -20,18 +20,11 @@ export class LinkBox extends ViewBoxBaseComponent() { return FieldView.LayoutString(LinkBox, fieldKey); } - _prevProps: FieldViewProps; - @override _props: FieldViewProps; - constructor(props: FieldViewProps) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } - onClickScriptDisable = returnAlways; @computed get anchor1() { const anchor1 = DocCast(this.dataDoc.link_anchor_1); diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 108930ad9..fa7a55bc7 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -19,6 +19,7 @@ import { Transform } from '../../util/Transform'; import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView'; import './LinkDocPreview.scss'; import * as React from 'react'; +import { ObservableReactComponent } from '../ObservableReactComponent'; export class LinkInfo { private static _instance: Opt; @@ -49,15 +50,7 @@ interface LinkDocPreviewProps { noPreview?: boolean; } @observer -export class LinkDocPreview extends React.Component { - _prevProps: LinkDocPreviewProps; - @observable _props: LinkDocPreviewProps; - constructor(props: LinkDocPreviewProps) { - super(props); - this._props = this._prevProps = props; - makeObservable(this); - } - +export class LinkDocPreview extends ObservableReactComponent { _infoRef = React.createRef(); _linkDocRef = React.createRef(); @observable _targetDoc: Opt = undefined; @@ -66,6 +59,10 @@ export class LinkDocPreview extends React.Component { @observable _linkSrc: Opt = undefined; @observable _toolTipText = ''; @observable _hrefInd = 0; + constructor(props: any) { + super(props); + makeObservable(this); + } @action init() { @@ -84,9 +81,9 @@ export class LinkDocPreview extends React.Component { this._toolTipText = ''; this.updateHref(); } - componentDidUpdate(props: any) { - copyProps(this); - if (props.linkSrc !== this._props.linkSrc || props.linkDoc !== this._props.linkDoc || props.hrefs !== this._props.hrefs) this.init(); + componentDidUpdate(prevProps: Readonly) { + copyProps(this, prevProps); + if (prevProps.linkSrc !== this._props.linkSrc || prevProps.linkDoc !== this._props.linkDoc || prevProps.hrefs !== this._props.hrefs) this.init(); } componentDidMount() { this.init(); diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx index ee1ea3ceb..b458e5a28 100644 --- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx +++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx @@ -1,9 +1,9 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IReactionDisposer, ObservableMap, reaction } from 'mobx'; import { observer } from 'mobx-react'; -import { Doc, Opt } from '../../../../fields/Doc'; +import * as React from 'react'; import { returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../../Utils'; +import { Doc, Opt } from '../../../../fields/Doc'; import { SelectionManager } from '../../../util/SelectionManager'; import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; // import { GPTPopup, GPTPopupMode } from './../../GPTPopup/GPTPopup'; @@ -36,7 +36,6 @@ export class MapAnchorMenu extends AntimodeMenu { constructor(props: Readonly<{}>) { super(props); - MapAnchorMenu.Instance = this; MapAnchorMenu.Instance._canFade = false; } diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 98a302834..a420e0101 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1,24 +1,24 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import BingMapsReact from 'bingmaps-react'; import { Button, EditableText, IconButton, Type } from 'browndash-components'; -import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, override, reaction, runInAction } from 'mobx'; +import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, setupMoveUpEvents } from '../../../../Utils'; import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc'; import { DocCss, Highlight } from '../../../../fields/DocSymbols'; import { DocCast, NumCast, StrCast } from '../../../../fields/Types'; -import { copyProps, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils'; -import { Docs, DocUtils } from '../../../documents/Documents'; import { DocumentType } from '../../../documents/DocumentTypes'; +import { DocUtils, 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 { undoable, UndoManager } from '../../../util/UndoManager'; -import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; +import { UndoManager, undoable } from '../../../util/UndoManager'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent'; -import { Colors } from '../../global/globalEnums'; import { SidebarAnnos } from '../../SidebarAnnos'; +import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; +import { Colors } from '../../global/globalEnums'; import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; import { FormattedTextBox } from '../formattedText/FormattedTextBox'; @@ -67,18 +67,12 @@ export class MapBox extends ViewBoxAnnotatableComponent = React.createRef(); private _disposers: { [key: string]: IReactionDisposer } = {}; - _unmounting = false; - _prevProps: ViewBoxAnnotatableProps & FieldViewProps; - @override _props: ViewBoxAnnotatableProps & FieldViewProps; - constructor(props: ViewBoxAnnotatableProps & FieldViewProps) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } + _unmounting = false; @observable private _savedAnnotations = new ObservableMap(); @computed get allSidebarDocs() { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index a453210eb..213f88177 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -1,8 +1,9 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, IReactionDisposer, makeObservable, observable, override, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as Pdfjs from 'pdfjs-dist'; import 'pdfjs-dist/web/pdf_viewer.css'; +import * as React from 'react'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; @@ -10,7 +11,7 @@ import { ComputedField } from '../../../fields/ScriptField'; import { Cast, FieldValue, ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField, PdfField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; -import { copyProps, emptyFunction, returnFalse, setupMoveUpEvents, Utils } from '../../../Utils'; +import { emptyFunction, returnFalse, setupMoveUpEvents, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; @@ -31,7 +32,6 @@ import { FieldView, FieldViewProps } from './FieldView'; import { ImageBox } from './ImageBox'; import './PDFBox.scss'; import { PinProps, PresBox } from './trails'; -import * as React from 'react'; @observer export class PDFBox extends ViewBoxAnnotatableComponent() { @@ -58,11 +58,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent (this._pdf = pdf))); } } - componentDidUpdate() { - copyProps(this); - } replaceCanvases = (oldDiv: HTMLElement, newDiv: HTMLElement) => { if (oldDiv.childNodes) { diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index a4f4897ba..ebe86318d 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -1,15 +1,15 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, override, reaction, runInAction, untracked } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction, untracked } from 'mobx'; import { observer } from 'mobx-react'; import { basename } from 'path'; +import * as React from 'react'; import { Doc, StrListCast } from '../../../fields/Doc'; import { InkTool } from '../../../fields/InkField'; import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { AudioField, ImageField, VideoField } from '../../../fields/URLField'; -import { copyProps, emptyFunction, formatTime, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils'; +import { emptyFunction, formatTime, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; import { Networking } from '../../Network'; @@ -68,19 +68,12 @@ export class VideoBox extends ViewBoxAnnotatableComponent(); diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 995f9f6e0..2f92f1edb 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, override, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import * as WebRequest from 'web-request'; @@ -13,7 +13,7 @@ import { listSpec } from '../../../fields/Schema'; import { Cast, NumCast, StrCast, WebCast } from '../../../fields/Types'; import { ImageField, WebField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; -import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, copyProps, emptyFunction, getWordAtPoint, lightOrDark, returnFalse, returnOne, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils'; +import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, getWordAtPoint, lightOrDark, returnFalse, returnOne, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { ScriptingGlobals } from '../../util/ScriptingGlobals'; @@ -98,19 +98,12 @@ export class WebBox extends ViewBoxAnnotatableComponent { if (!this._searching && !clear) { diff --git a/src/client/views/nodes/audio/AudioWaveform.tsx b/src/client/views/nodes/audio/AudioWaveform.tsx index 1b1a85800..01392c4a5 100644 --- a/src/client/views/nodes/audio/AudioWaveform.tsx +++ b/src/client/views/nodes/audio/AudioWaveform.tsx @@ -1,15 +1,16 @@ import axios from 'axios'; -import { computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; +import { computed, IReactionDisposer, makeObservable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, NumListCast } from '../../../../fields/Doc'; import { List } from '../../../../fields/List'; import { listSpec } from '../../../../fields/Schema'; import { Cast } from '../../../../fields/Types'; -import { copyProps, numberRange } from '../../../../Utils'; +import { numberRange } from '../../../../Utils'; import { Colors } from './../../global/globalEnums'; import './AudioWaveform.scss'; import { WaveCanvas } from './WaveCanvas'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; /** * AudioWaveform @@ -35,21 +36,15 @@ export interface AudioWaveformProps { } @observer -export class AudioWaveform extends React.Component { +export class AudioWaveform extends ObservableReactComponent { public static NUMBER_OF_BUCKETS = 100; // number of buckets data is divided into to draw waveform lines _disposer: IReactionDisposer | undefined; - _prevProps: React.PropsWithChildren; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } - get waveHeight() { return Math.max(50, this._props.PanelHeight); } diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index e2cceb906..555b752f0 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -2,22 +2,23 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { action, computed, IReactionDisposer, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; import { Doc } from '../../../../fields/Doc'; import { List } from '../../../../fields/List'; import { listSpec } from '../../../../fields/Schema'; import { SchemaHeaderField } from '../../../../fields/SchemaHeaderField'; -import { Cast, StrCast } from '../../../../fields/Types'; -import { copyProps, emptyFunction, returnFalse, returnZero, setupMoveUpEvents } from '../../../../Utils'; +import { Cast } from '../../../../fields/Types'; +import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents } from '../../../../Utils'; import { DocServer } from '../../../DocServer'; import { CollectionViewType } from '../../../documents/DocumentTypes'; +import { Transform } from '../../../util/Transform'; import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; import { SchemaTableCell } from '../../collections/collectionSchema/SchemaTableCell'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; import { OpenWhere } from '../DocumentView'; import './DashFieldView.scss'; import { FormattedTextBox } from './FormattedTextBox'; -import * as React from 'react'; -import { Transform } from '../../../util/Transform'; export class DashFieldView { dom: HTMLDivElement; // container for label and value @@ -92,7 +93,7 @@ interface IDashFieldViewInternal { } @observer -export class DashFieldViewInternal extends React.Component { +export class DashFieldViewInternal extends ObservableReactComponent { _reactionDisposer: IReactionDisposer | undefined; _textBoxDoc: Doc; _fieldKey: string; @@ -100,11 +101,8 @@ export class DashFieldViewInternal extends React.Component, prevState: Readonly<{}>, snapshot?: any): void { - copyProps(this); - } + componentWillUnmount() { this._reactionDisposer?.(); } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 56bf15b09..997c3f86d 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -2,7 +2,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { isEqual } from 'lodash'; -import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, override, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { baseKeymap, selectAll } from 'prosemirror-commands'; import { history } from 'prosemirror-history'; @@ -14,7 +14,7 @@ import { EditorView } from 'prosemirror-view'; import { BsMarkdownFill } from 'react-icons/bs'; import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast, Field, Opt } from '../../../../fields/Doc'; -import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, DocData, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols'; +import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { InkTool } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; @@ -24,7 +24,7 @@ import { RichTextUtils } from '../../../../fields/RichTextUtils'; import { ComputedField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util'; -import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, copyProps, emptyFunction, numberRange, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, unimplementedFunction, Utils } from '../../../../Utils'; +import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, unimplementedFunction, Utils } from '../../../../Utils'; import { GoogleApiClientUtils, Pulls, Pushes } from '../../../apis/google_docs/GoogleApiClientUtils'; import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT'; import { DocServer } from '../../../DocServer'; @@ -55,7 +55,7 @@ import { StyleProp } from '../../StyleProvider'; import { media_state } from '../AudioBox'; import { DocFocusOptions, DocumentView, DocumentViewInternal, OpenWhere } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; -import { LinkDocPreview, LinkInfo } from '../LinkDocPreview'; +import { LinkInfo } from '../LinkDocPreview'; import { PinProps, PresBox } from '../trails'; import { DashDocCommentView } from './DashDocCommentView'; import { DashDocView } from './DashDocView'; @@ -208,20 +208,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent; - @override _props: React.PropsWithChildren; constructor(props: React.PropsWithChildren) { super(props); - this._props = this._prevProps = props; makeObservable(this); FormattedTextBox.Instance = this; this._recordingStart = Date.now(); } - componentDidUpdate() { - copyProps(this); - } - // removes all hyperlink anchors for the removed linkDoc // TODO: bcz: Argh... if a section of text has multiple anchors, this should just remove the intended one. // but since removing one anchor from the list of attr anchors isn't implemented, this will end up removing nothing. diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 7de1eb717..4881070fd 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -1,21 +1,22 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, IReactionDisposer, makeObservable, observable, override, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { lift, wrapIn } from 'prosemirror-commands'; import { Mark, MarkType, Node as ProsNode, ResolvedPos } from 'prosemirror-model'; import { wrapInList } from 'prosemirror-schema-list'; import { EditorState, NodeSelection, TextSelection } from 'prosemirror-state'; import { EditorView } from 'prosemirror-view'; +import * as React from 'react'; import { Doc } from '../../../../fields/Doc'; import { BoolCast, Cast, StrCast } from '../../../../fields/Types'; -import { copyProps, numberRange } from '../../../../Utils'; +import { numberRange } from '../../../../Utils'; import { DocServer } from '../../../DocServer'; import { LinkManager } from '../../../util/LinkManager'; import { SelectionManager } from '../../../util/SelectionManager'; import { undoBatch, UndoManager } from '../../../util/UndoManager'; import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; import { EquationBox } from '../EquationBox'; import { FieldViewProps } from '../FieldView'; import { FormattedTextBox } from './FormattedTextBox'; @@ -63,18 +64,13 @@ export class RichTextMenu extends AntimodeMenu { @observable private showLinkDropdown: boolean = false; _reaction: IReactionDisposer | undefined; - _prevProps: AntimodeMenuProps; - @override _props: AntimodeMenuProps; constructor(props: AntimodeMenuProps) { super(props); - this._props = this._prevProps = props; makeObservable(this); - runInAction(() => { - RichTextMenu.Instance = this; - this.updateMenu(undefined, undefined, props, this.layoutDoc); - this._canFade = false; - this.Pinned = true; - }); + RichTextMenu.Instance = this; + this.updateMenu(undefined, undefined, props, this.layoutDoc); + this._canFade = false; + this.Pinned = true; } @computed get noAutoLink() { @@ -111,9 +107,6 @@ export class RichTextMenu extends AntimodeMenu { return BoolCast(this.layoutDoc?.layout_centered); } _disposer: IReactionDisposer | undefined; - componentDidUpdate() { - copyProps(this); - } componentDidMount() { this._disposer = reaction( () => SelectionManager.Views.slice(), @@ -368,7 +361,7 @@ export class RichTextMenu extends AntimodeMenu { } else if (SelectionManager.Views.some(dv => dv.ComponentView instanceof EquationBox)) { SelectionManager.Views.forEach(dv => (dv.Document._text_fontSize = fontSize)); } else Doc.UserDoc().fontSize = fontSize; - this.updateMenu(this.view, undefined, this._props, this.layoutDoc); + this.updateMenu(this.view, undefined, this.props, this.layoutDoc); }; setFontFamily = (family: string) => { @@ -377,7 +370,7 @@ export class RichTextMenu extends AntimodeMenu { this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true); this.view.focus(); } else Doc.UserDoc().fontFamily = family; - this.updateMenu(this.view, undefined, this._props, this.layoutDoc); + this.updateMenu(this.view, undefined, this.props, this.layoutDoc); }; setHighlight(color: string) { @@ -386,7 +379,7 @@ export class RichTextMenu extends AntimodeMenu { this.setMark(highlightMark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(highlightMark)), true); this.view.focus(); } else Doc.UserDoc()._fontHighlight = color; - this.updateMenu(this.view, undefined, this._props, this.layoutDoc); + this.updateMenu(this.view, undefined, this.props, this.layoutDoc); } setColor(color: string) { @@ -395,7 +388,7 @@ export class RichTextMenu extends AntimodeMenu { this.setMark(colorMark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(colorMark)), true); this.view.focus(); } else Doc.UserDoc().fontColor = color; - this.updateMenu(this.view, undefined, this._props, this.layoutDoc); + this.updateMenu(this.view, undefined, this.props, this.layoutDoc); } // TODO: remove doesn't work @@ -436,7 +429,7 @@ export class RichTextMenu extends AntimodeMenu { } } this.view.focus(); - this.updateMenu(this.view, undefined, this._props, this.layoutDoc); + this.updateMenu(this.view, undefined, this.props, this.layoutDoc); }; insertSummarizer(state: EditorState, dispatch: any) { @@ -818,22 +811,15 @@ interface ButtonDropdownProps { } @observer -export class ButtonDropdown extends React.Component { +export class ButtonDropdown extends ObservableReactComponent { @observable private showDropdown: boolean = false; private ref: HTMLDivElement | null = null; - _prevProps: React.PropsWithChildren; - @observable _props: React.PropsWithChildren; - constructor(props: React.PropsWithChildren) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } - componentDidMount() { document.addEventListener('pointerdown', this.onBlur); } diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 9fcb496b8..ec5d090dd 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -1,12 +1,13 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, IReactionDisposer, makeObservable, observable, override, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types'; -import { copyProps, emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils'; import { Docs } from '../../../documents/Documents'; import { CollectionViewType } from '../../../documents/DocumentTypes'; import { DocumentManager } from '../../../util/DocumentManager'; @@ -24,7 +25,6 @@ import { StyleProp } from '../../StyleProvider'; import { PresBox } from './PresBox'; import './PresElementBox.scss'; import { PresMovement } from './PresEnums'; -import * as React from 'react'; /** * This class models the view a document added to presentation will have in the presentation. * It involves some functionality for its buttons and options. @@ -41,19 +41,12 @@ export class PresElementBox extends ViewBoxBaseComponent() { readonly expandViewHeight = 100; readonly collapsedHeight = 35; - @observable _dragging = false; - - _prevProps: FieldViewProps; - @override _props: FieldViewProps; - constructor(props: FieldViewProps) { + constructor(props: any) { super(props); - this._props = this._prevProps = props; makeObservable(this); } - componentDidUpdate() { - copyProps(this); - } + @observable _dragging = false; // the presentation view that renders this slide @computed get presBoxView() { diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index 0627876fa..a8c83ded6 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -1,12 +1,12 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components'; -import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, override, reaction } from 'mobx'; +import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { ColorResult } from 'react-color'; +import { Utils, returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../Utils'; import { Doc, Opt } from '../../../fields/Doc'; -import { copyProps, returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from '../../../Utils'; -import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT'; +import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT'; import { DocumentType } from '../../documents/DocumentTypes'; import { SelectionManager } from '../../util/SelectionManager'; import { SettingsManager } from '../../util/SettingsManager'; @@ -23,18 +23,12 @@ export class AnchorMenu extends AntimodeMenu { private _commentRef = React.createRef(); private _cropRef = React.createRef(); - _prevProps: AntimodeMenuProps; - @override _props: AntimodeMenuProps; constructor(props: AntimodeMenuProps) { super(props); - this._props = this._prevProps = props; makeObservable(this); AnchorMenu.Instance = this; AnchorMenu.Instance._canFade = false; } - componentDidUpdate() { - copyProps(this); - } @observable private highlightColor: string = 'rgba(245, 230, 95, 0.616)'; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index a581e9df6..e342c25b3 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -1,13 +1,16 @@ import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +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 { 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 { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, copyProps, emptyFunction, returnAll, returnFalse, returnNone, returnZero, smoothScroll, Utils } from '../../../Utils'; +import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, returnAll, returnFalse, returnNone, returnZero, smoothScroll, Utils } from '../../../Utils'; import { DocUtils } from '../../documents/Documents'; import { SelectionManager } from '../../util/SelectionManager'; import { SnappingManager } from '../../util/SnappingManager'; @@ -16,15 +19,13 @@ import { CollectionFreeFormView } from '../collections/collectionFreeForm/Collec import { MarqueeAnnotator } from '../MarqueeAnnotator'; import { DocFocusOptions, DocumentViewProps } from '../nodes/DocumentView'; import { FieldViewProps } from '../nodes/FieldView'; -import { LinkDocPreview, LinkInfo } from '../nodes/LinkDocPreview'; +import { LinkInfo } from '../nodes/LinkDocPreview'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import { StyleProp } from '../StyleProvider'; import { AnchorMenu } from './AnchorMenu'; import { Annotation } from './Annotation'; import { GPTPopup } from './GPTPopup/GPTPopup'; import './PDFViewer.scss'; -import * as React from 'react'; -import * as Pdfjs from 'pdfjs-dist'; -import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs'; const _global = (window /* browser */ || global) /* node */ as any; //pdfjsLib.GlobalWorkerOptions.workerSrc = `/assets/pdf.worker.js`; @@ -49,14 +50,11 @@ interface IViewerProps extends FieldViewProps { * Handles rendering and virtualization of the pdf */ @observer -export class PDFViewer extends React.Component { +export class PDFViewer extends ObservableReactComponent { static _annotationStyle: any = addStyleSheet(); - _prevProps: IViewerProps; - @observable _props: IViewerProps; - constructor(props: IViewerProps) { + constructor(props: any) { super(props); - this._prevProps = this._props = props; makeObservable(this); } @@ -66,10 +64,6 @@ export class PDFViewer extends React.Component { @observable _showWaiting = true; @observable Index: number = -1; - componentDidUpdate() { - copyProps(this); - } - private _pdfViewer: any; private _styleRule: any; // stylesheet rule for making hyperlinks clickable private _retries = 0; // number of times tried to create the PDF viewer -- cgit v1.2.3-70-g09d2 From df2fc3f11e3b474144db5062620c9f65ca857203 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 28 Dec 2023 13:39:23 -0500 Subject: fixed youtube uploads, cleaned up a bunch of imports and added some typings files. --- package-lock.json | 58 +++++---- package.json | 9 +- src/client/documents/Documents.ts | 30 ++--- src/client/util/DocumentManager.ts | 2 +- src/client/util/convertToCSSPTValue.js | 12 +- src/client/util/jsx-decl.d.ts | 1 - src/client/views/OCRUtils.ts | 7 -- src/client/views/collections/CollectionView.tsx | 4 +- src/client/views/nodes/DocumentContentsView.tsx | 3 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/MapBox/MarkerIcons.tsx | 109 ++++++++++------- src/client/views/nodes/WebBox.tsx | 2 +- src/client/views/nodes/audio/AudioWaveform.tsx | 1 - src/server/ApiManagers/SearchManager.ts | 4 +- src/server/ApiManagers/UploadManager.ts | 50 ++++---- src/server/DashStats.ts | 150 ++++++++++++------------ src/server/DashUploadUtils.ts | 31 ++--- src/typings/index.d.ts | 8 +- 18 files changed, 252 insertions(+), 231 deletions(-) delete mode 100644 src/client/util/jsx-decl.d.ts delete mode 100644 src/client/views/OCRUtils.ts (limited to 'src/client/views/nodes/audio') diff --git a/package-lock.json b/package-lock.json index dce4955bb..cdeefa8c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,15 +33,19 @@ "@react-google-maps/api": "^2.19.2", "@turf/turf": "^6.5.0", "@types/bezier-js": "^4.1.3", + "@types/brotli": "^1.3.4", "@types/cors": "^2.8.17", "@types/d3-axis": "^3.0.6", "@types/d3-color": "^3.1.3", "@types/d3-scale": "^4.0.8", "@types/d3-selection": "^3.0.10", "@types/dom-speech-recognition": "0.0.4", + "@types/find-in-files": "^0.5.3", + "@types/fluent-ffmpeg": "^2.1.24", "@types/formidable": "3.4.5", "@types/google-maps": "^3.2.6", "@types/mapbox-gl": "^2.7.19", + "@types/pdf-parse": "^1.1.4", "@types/reveal": "^4.2.0", "@types/supercluster": "^7.1.3", "@types/web": "^0.0.131", @@ -226,18 +230,17 @@ "@types/bcrypt-nodejs": "0.0.31", "@types/bluebird": "^3.5.42", "@types/body-parser": "^1.19.5", - "@types/brotli": "^1.3.4", "@types/chai": "^4.3.11", "@types/color": "^3.0.6", - "@types/connect-flash": "0.0.40", "@types/cookie-parser": "^1.4.6", "@types/cookie-session": "^2.0.48", "@types/d3": "^7.4.3", "@types/exif": "^0.6.5", "@types/express": "^4.17.21", - "@types/express-flash": "0.0.5", "@types/express-session": "^1.17.10", "@types/file-saver": "^2.0.7", + "@types/howler": "^2.2.11", + "@types/html-to-text": "^9.0.4", "@types/jquery": "^3.5.29", "@types/libxmljs": "^0.18.12", "@types/lodash": "^4.14.202", @@ -8662,7 +8665,6 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/@types/brotli/-/brotli-1.3.4.tgz", "integrity": "sha512-cKYjgaS2DMdCKF7R0F5cgx1nfBYObN2ihIuPGQ4/dlIY6RpV7OWNwe9L8V4tTVKL2eZqOkNM9FM/rgTvLf4oXw==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -8723,15 +8725,6 @@ "@types/node": "*" } }, - "node_modules/@types/connect-flash": { - "version": "0.0.40", - "resolved": "https://registry.npmjs.org/@types/connect-flash/-/connect-flash-0.0.40.tgz", - "integrity": "sha512-vqGDzZ85Kyu/tKdDwXP6JCz4i2Xp3o4bYHSCXbF7XiL1HohogtGXG5pgbgypVbdO3DYqCOHIiZhp2Gh5fP2dDw==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, "node_modules/@types/connect-history-api-fallback": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", @@ -9081,15 +9074,6 @@ "@types/serve-static": "*" } }, - "node_modules/@types/express-flash": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@types/express-flash/-/express-flash-0.0.5.tgz", - "integrity": "sha512-lz8xxkEev6JHEyHeDNb45tUkhUnPERim9td+Ov7kBDCq6+dFHlu+BvTKYz7DcLh02a3ZK+tg2mze4tZ8DgJyLw==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, "node_modules/@types/express-serve-static-core": { "version": "4.17.41", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", @@ -9117,6 +9101,19 @@ "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==", "dev": true }, + "node_modules/@types/find-in-files": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@types/find-in-files/-/find-in-files-0.5.3.tgz", + "integrity": "sha512-IGKtSn0Lonfx3HdK6KMcfd5GUc1xdeLtjW1n7ZSA5Tmn1n2gj878q6IC0s4MbF9KtBpXIRqjRQxBzi2kF4WvGw==" + }, + "node_modules/@types/fluent-ffmpeg": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.24.tgz", + "integrity": "sha512-g5oQO8Jgi2kFS3tTub7wLvfLztr1s8tdXmRd8PiL/hLMLzTIAyMR2sANkTggM/rdEDAg3d63nYRRVepwBiCw5A==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/formidable": { "version": "3.4.5", "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-3.4.5.tgz", @@ -9161,11 +9158,23 @@ "@types/unist": "*" } }, + "node_modules/@types/howler": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/@types/howler/-/howler-2.2.11.tgz", + "integrity": "sha512-7aBoUL6RbSIrqKnpEgfa1wSNUBK06mn08siP2QI0zYk7MXfEJAaORc4tohamQYqCqVESoDyRWSdQn2BOKWj2Qw==", + "dev": true + }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" }, + "node_modules/@types/html-to-text": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@types/html-to-text/-/html-to-text-9.0.4.tgz", + "integrity": "sha512-pUY3cKH/Nm2yYrEmDlPR1mR7yszjGx4DrwPjQ702C4/D5CwHuZTgZdIdwPkRbcuhs7BAh2L5rg3CL5cbRiGTCQ==", + "dev": true + }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", @@ -9400,6 +9409,11 @@ "@types/passport": "*" } }, + "node_modules/@types/pdf-parse": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/pdf-parse/-/pdf-parse-1.1.4.tgz", + "integrity": "sha512-+gbBHbNCVGGYw1S9lAIIvrHW47UYOhMIFUsJcMkMrzy1Jf0vulBN3XQIjPgnoOXveMuHnF3b57fXROnY/Or7eg==" + }, "node_modules/@types/prop-types": { "version": "15.7.11", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", diff --git a/package.json b/package.json index 4176593c5..f16b16e7b 100644 --- a/package.json +++ b/package.json @@ -27,18 +27,17 @@ "@types/bcrypt-nodejs": "0.0.31", "@types/bluebird": "^3.5.42", "@types/body-parser": "^1.19.5", - "@types/brotli": "^1.3.4", "@types/chai": "^4.3.11", "@types/color": "^3.0.6", - "@types/connect-flash": "0.0.40", "@types/cookie-parser": "^1.4.6", "@types/cookie-session": "^2.0.48", "@types/d3": "^7.4.3", "@types/exif": "^0.6.5", "@types/express": "^4.17.21", - "@types/express-flash": "0.0.5", "@types/express-session": "^1.17.10", "@types/file-saver": "^2.0.7", + "@types/howler": "^2.2.11", + "@types/html-to-text": "^9.0.4", "@types/jquery": "^3.5.29", "@types/libxmljs": "^0.18.12", "@types/lodash": "^4.14.202", @@ -117,15 +116,19 @@ "@react-google-maps/api": "^2.19.2", "@turf/turf": "^6.5.0", "@types/bezier-js": "^4.1.3", + "@types/brotli": "^1.3.4", "@types/cors": "^2.8.17", "@types/d3-axis": "^3.0.6", "@types/d3-color": "^3.1.3", "@types/d3-scale": "^4.0.8", "@types/d3-selection": "^3.0.10", "@types/dom-speech-recognition": "0.0.4", + "@types/find-in-files": "^0.5.3", + "@types/fluent-ffmpeg": "^2.1.24", "@types/formidable": "3.4.5", "@types/google-maps": "^3.2.6", "@types/mapbox-gl": "^2.7.19", + "@types/pdf-parse": "^1.1.4", "@types/reveal": "^4.2.0", "@types/supercluster": "^7.1.3", "@types/web": "^0.0.131", diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ff14eb101..0a4d3a294 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -59,9 +59,7 @@ import { WebBox } from '../views/nodes/WebBox'; import { SearchBox } from '../views/search/SearchBox'; import { CollectionViewType, DocumentType } from './DocumentTypes'; import { CalendarBox } from '../views/nodes/calendarBox/CalendarBox'; -const { - default: { DFLT_IMAGE_NATIVE_DIM }, -} = require('../views/global/globalCssVariables.module.scss'); +const { default: { DFLT_IMAGE_NATIVE_DIM } } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', '')); class EmptyBox { @@ -179,7 +177,7 @@ export class DocumentOptions { longitude?: NUMt = new NumInfo('longitude coordinate for map views', false); routeCoordinates?: STRt = new StrInfo("stores a route's/direction's coordinates (stringified version)"); // for a route document, this stores the route's coordinates markerType?: STRt = new StrInfo('Defines the marker type for a pushpin document'); - markerColor?: STRt= new StrInfo('Defines the marker color for a pushpin document'); + markerColor?: STRt = new StrInfo('Defines the marker color for a pushpin document'); map?: STRt = new StrInfo('text location of map'); map_type?: STRt = new StrInfo('type of map view', false); map_zoom?: NUMt = new NumInfo('zoom of a map view', false); @@ -790,8 +788,8 @@ export namespace Docs { { layout: { view: CalendarBox, dataField: defaultDataKey }, options: {}, - } - ] + }, + ], ]); const suffix = 'Proto'; @@ -1032,7 +1030,6 @@ export namespace Docs { export function LoadingDocument(file: File | string, options: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.LOADING), undefined, { _height: 150, _width: 200, title: typeof file == 'string' ? file : file.name, ...options }, undefined, ''); } - export function RTFDocument(field: RichTextField, options: DocumentOptions = {}, fieldKey: string = 'text') { return InstanceFromProto(Prototypes.get(DocumentType.RTF), field, options, undefined, fieldKey); @@ -1139,14 +1136,7 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.MAP), new List(documents), options); } - export function PushpinDocument( - latitude: number, - longitude: number, - infoWindowOpen: boolean, - documents: Array, - options: DocumentOptions, - id?: string) { - + export function PushpinDocument(latitude: number, longitude: number, infoWindowOpen: boolean, documents: Array, options: DocumentOptions, id?: string) { return InstanceFromProto(Prototypes.get(DocumentType.PUSHPIN), new List(documents), { latitude, longitude, infoWindowOpen, ...options }, id); } @@ -1154,8 +1144,8 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.MAPROUTE), new List(documents), { infoWindowOpen, ...options }, id); } - export function CalendarDocument(options: DocumentOptions, documents: Array){ - return InstanceFromProto(Prototypes.get(DocumentType.CALENDAR), new List(documents), {...options}) + export function CalendarDocument(options: DocumentOptions, documents: Array) { + return InstanceFromProto(Prototypes.get(DocumentType.CALENDAR), new List(documents), { ...options }); } // shouldn't ever need to create a KVP document-- instead set the LayoutTemplateString to be a KeyValueBox for the DocumentView (see addDocTab in TabDocView) @@ -1212,8 +1202,8 @@ export namespace Docs { return doc; } - export function CalendarCollectionDocument(documents: Array, options: DocumentOptions){ - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), {...options, _type_collection: CollectionViewType.Calendar}); + export function CalendarCollectionDocument(documents: Array, options: DocumentOptions) { + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Calendar }); } export function StackingDocument(documents: Array, options: DocumentOptions, id?: string, protoId?: string) { @@ -2022,4 +2012,4 @@ ScriptingGlobals.add(function generateLinkTitle(link: Doc) { const link_anchor_2title = link.link_anchor_2 && link.link_anchor_2 !== link ? Cast(link.link_anchor_2, Doc, null)?.title : ''; const relation = link.link_relationship || 'to'; return `${link_anchor_1title} (${relation}) ${link_anchor_2title}`; -}); \ No newline at end of file +}); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 4816f3317..0101c2bcb 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -16,7 +16,7 @@ import { LinkAnchorBox } from '../views/nodes/LinkAnchorBox'; import { PresBox } from '../views/nodes/trails'; import { ScriptingGlobals } from './ScriptingGlobals'; import { SelectionManager } from './SelectionManager'; -const { Howl } = require('howler'); +import { Howl } from 'howler'; export class DocumentManager { private static _instance: DocumentManager; diff --git a/src/client/util/convertToCSSPTValue.js b/src/client/util/convertToCSSPTValue.js index 179557953..66f8db5a1 100644 --- a/src/client/util/convertToCSSPTValue.js +++ b/src/client/util/convertToCSSPTValue.js @@ -1,18 +1,16 @@ 'use strict'; -Object.defineProperty(exports, "__esModule", { - value: true +Object.defineProperty(exports, '__esModule', { + value: true, }); exports.PT_TO_PX_RATIO = exports.PX_TO_PT_RATIO = undefined; exports.default = convertToCSSPTValue; exports.toClosestFontPtSize = toClosestFontPtSize; -// var _FontSizeCommandMenuButton = require('./ui/FontSizeCommandMenuButton'); - var SIZE_PATTERN = /([\d\.]+)(px|pt)/i; -var PX_TO_PT_RATIO = exports.PX_TO_PT_RATIO = 0.7518796992481203; // 1 / 1.33. -var PT_TO_PX_RATIO = exports.PT_TO_PX_RATIO = 1.33; +var PX_TO_PT_RATIO = (exports.PX_TO_PT_RATIO = 0.7518796992481203); // 1 / 1.33. +var PT_TO_PX_RATIO = (exports.PT_TO_PX_RATIO = 1.33); function convertToCSSPTValue(styleValue) { var matches = styleValue.match(SIZE_PATTERN); @@ -40,4 +38,4 @@ function toClosestFontPtSize(styleValue) { return _FontSizeCommandMenuButton.FONT_PT_SIZES.reduce(function (prev, curr) { return Math.abs(curr - originalPTValue) < Math.abs(prev - originalPTValue) ? curr : prev; }, Number.NEGATIVE_INFINITY); -} \ No newline at end of file +} diff --git a/src/client/util/jsx-decl.d.ts b/src/client/util/jsx-decl.d.ts deleted file mode 100644 index 532f06178..000000000 --- a/src/client/util/jsx-decl.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'react-jsx-parser'; diff --git a/src/client/views/OCRUtils.ts b/src/client/views/OCRUtils.ts deleted file mode 100644 index 282ec770e..000000000 --- a/src/client/views/OCRUtils.ts +++ /dev/null @@ -1,7 +0,0 @@ -// import tesseract from "node-tesseract-ocr"; -// const tesseract = require("node-tesseract"); - - -export namespace OCRUtils { - -} diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 0237ec95e..0656843cb 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -28,13 +28,11 @@ import { CollectionTreeView } from './CollectionTreeView'; import './CollectionView.scss'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import { CollectionGridView } from './collectionGrid/CollectionGridView'; -import { CollectionCalendarView} from './CollectionCalendarView'; +import { CollectionCalendarView } from './CollectionCalendarView'; import { CollectionLinearView } from './collectionLinear'; import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView'; import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; import { CollectionSchemaView } from './collectionSchema/CollectionSchemaView'; -const path = require('path'); - interface CollectionViewProps_ extends FieldViewProps { isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc) isAnnotationOverlayScrollable?: boolean; // whether the annotation overlay can be vertically scrolled (just for tree views, currently) diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 5b2bf4774..fa472312e 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -47,8 +47,7 @@ import { WebBox } from './WebBox'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; import { ImportElementBox } from './importBox/ImportElementBox'; import { PresBox } from './trails/PresBox'; - -const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? +import JsxParser from 'react-jsx-parser'; type BindingProps = Without; export interface JsxBindings { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 2d5f68a69..2752fa7f5 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -53,7 +53,7 @@ import { LinkAnchorBox } from './LinkAnchorBox'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; import { PresEffect, PresEffectDirection } from './trails'; import { PinProps, PresBox } from './trails/PresBox'; -const { Howl } = require('howler'); +import { Howl } from 'howler'; interface Window { MediaRecorder: MediaRecorder; diff --git a/src/client/views/nodes/MapBox/MarkerIcons.tsx b/src/client/views/nodes/MapBox/MarkerIcons.tsx index 146f296c1..a580fcaa0 100644 --- a/src/client/views/nodes/MapBox/MarkerIcons.tsx +++ b/src/client/views/nodes/MapBox/MarkerIcons.tsx @@ -1,11 +1,42 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { faShopify } from '@fortawesome/free-brands-svg-icons'; -import { faBasketball, faBicycle, faBowlFood, faBus, faCameraRetro, faCar, faCartShopping, faFilm, faFootball, faFutbol, faHockeyPuck, faHospital, faHotel, faHouse, faLandmark, faLocationDot, faLocationPin, faMapPin, faMasksTheater, faMugSaucer, faPersonHiking, faPlane, faSchool, faShirt, faShop, faSquareParking, faStar, faTrainSubway, faTree, faUtensils, faVolleyball } from '@fortawesome/free-solid-svg-icons'; +import { + faBasketball, + faBicycle, + faBowlFood, + faBus, + faCameraRetro, + faCar, + faCartShopping, + faFilm, + faFootball, + faFutbol, + faHockeyPuck, + faHospital, + faHotel, + faHouse, + faLandmark, + faLocationDot, + faLocationPin, + faMapPin, + faMasksTheater, + faMugSaucer, + faPersonHiking, + faPlane, + faSchool, + faShirt, + faShop, + faSquareParking, + faStar, + faTrainSubway, + faTree, + faUtensils, + faVolleyball, +} from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import React = require('react'); +import * as React from 'react'; export class MarkerIcons { - // static getMapboxIcon = (color: string) => { // return ( // @@ -34,43 +65,39 @@ export class MarkerIcons { iconProps.color = color; } - return (); - - - } - - static FAMarkerIconsMap: {[key: string]: IconProp} = { - 'MAP_PIN': faLocationDot, - 'RESTAURANT_ICON': faUtensils, - 'HOTEL_ICON': faHotel, - 'HOUSE_ICON': faHouse, - 'AIRPLANE_ICON': faPlane, - 'CAR_ICON': faCar, - 'BUS_ICON': faBus, - 'TRAIN_ICON': faTrainSubway, - 'BICYCLE_ICON': faBicycle, - 'PARKING_ICON': faSquareParking, - 'PHOTO_ICON': faCameraRetro, - 'CAFE_ICON': faMugSaucer, - 'STAR_ICON': faStar, - 'SHOPPING_CART_ICON': faCartShopping, - 'SHOPIFY_ICON': faShopify, - 'SHOP_ICON': faShop, - 'SHIRT_ICON': faShirt, - 'FOOD_ICON': faBowlFood, - 'LANDMARK_ICON': faLandmark, - 'HOSPITAL_ICON': faHospital, - 'NATURE_ICON': faTree, - 'HIKING_ICON': faPersonHiking, - 'SOCCER_ICON': faFutbol, - 'VOLLEYBALL_ICON': faVolleyball, - 'BASKETBALL_ICON': faBasketball, - 'HOCKEY_ICON': faHockeyPuck, - 'FOOTBALL_ICON': faFootball, - 'SCHOOL_ICON': faSchool, - 'THEATER_ICON': faMasksTheater, - 'FILM_ICON': faFilm + return ; } - -} \ No newline at end of file + static FAMarkerIconsMap: { [key: string]: IconProp } = { + MAP_PIN: faLocationDot, + RESTAURANT_ICON: faUtensils, + HOTEL_ICON: faHotel, + HOUSE_ICON: faHouse, + AIRPLANE_ICON: faPlane, + CAR_ICON: faCar, + BUS_ICON: faBus, + TRAIN_ICON: faTrainSubway, + BICYCLE_ICON: faBicycle, + PARKING_ICON: faSquareParking, + PHOTO_ICON: faCameraRetro, + CAFE_ICON: faMugSaucer, + STAR_ICON: faStar, + SHOPPING_CART_ICON: faCartShopping, + SHOPIFY_ICON: faShopify, + SHOP_ICON: faShop, + SHIRT_ICON: faShirt, + FOOD_ICON: faBowlFood, + LANDMARK_ICON: faLandmark, + HOSPITAL_ICON: faHospital, + NATURE_ICON: faTree, + HIKING_ICON: faPersonHiking, + SOCCER_ICON: faFutbol, + VOLLEYBALL_ICON: faVolleyball, + BASKETBALL_ICON: faBasketball, + HOCKEY_ICON: faHockeyPuck, + FOOTBALL_ICON: faFootball, + SCHOOL_ICON: faSchool, + THEATER_ICON: faMasksTheater, + FILM_ICON: faFilm, + }; +} diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 57045e2af..2522a674d 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -1,4 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { htmlToText } from 'html-to-text'; import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -39,7 +40,6 @@ import { PinProps, PresBox } from './trails'; import './WebBox.scss'; const { CreateImage } = require('./WebBoxRenderer'); const _global = (window /* browser */ || global) /* node */ as any; -const htmlToText = require('html-to-text'); @observer export class WebBox extends ViewBoxAnnotatableComponent() { public static LayoutString(fieldKey: string) { diff --git a/src/client/views/nodes/audio/AudioWaveform.tsx b/src/client/views/nodes/audio/AudioWaveform.tsx index 01392c4a5..c034d95ea 100644 --- a/src/client/views/nodes/audio/AudioWaveform.tsx +++ b/src/client/views/nodes/audio/AudioWaveform.tsx @@ -16,7 +16,6 @@ import { ObservableReactComponent } from '../../ObservableReactComponent'; * AudioWaveform * * Used in CollectionStackedTimeline to render a canvas with a visual of an audio waveform for AudioBox and VideoBox documents. - * Uses react-audio-waveform package. * Bins the audio data into audioBuckets which are passed to package to render the lines. * Calculates new buckets each time a new zoom factor or new set of trim bounds is created and stores it in a field on the layout doc with a title indicating the bounds and zoom for that list (see audioBucketField) */ diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts index 186f0bcd3..72c01def7 100644 --- a/src/server/ApiManagers/SearchManager.ts +++ b/src/server/ApiManagers/SearchManager.ts @@ -8,7 +8,7 @@ import RouteSubscriber from '../RouteSubscriber'; import { Search } from '../Search'; import ApiManager, { Registration } from './ApiManager'; import { Directory, pathToDirectory } from './UploadManager'; -const findInFiles = require('find-in-files'); +import { find } from 'find-in-files'; export class SearchManager extends ApiManager { protected initialize(register: Registration): void { @@ -47,7 +47,7 @@ export class SearchManager extends ApiManager { const dir = pathToDirectory(Directory.text); try { const regex = new RegExp(q.toString()); - results = await findInFiles.find({ term: q, flags: 'ig' }, dir, '.txt$'); + results = await find({ term: q, flags: 'ig' }, dir, '.txt$'); for (const result in results) { resObj.ids.push(path.basename(result, '.txt').replace(/upload_/, '')); resObj.lines.push(results[result].line); diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts index 06f4f1a9d..8a2fe1389 100644 --- a/src/server/ApiManagers/UploadManager.ts +++ b/src/server/ApiManagers/UploadManager.ts @@ -14,8 +14,8 @@ import { SolrManager } from './SearchManager'; import * as uuid from 'uuid'; import { DashVersion } from '../../fields/DocSymbols'; import * as AdmZip from 'adm-zip'; -const imageDataUri = require('image-data-uri'); -const fs = require('fs'); +import * as imageDataUri from 'image-data-uri'; +import * as fs from 'fs'; export enum Directory { parsed_files = 'parsed_files', @@ -265,7 +265,7 @@ export default class UploadManager extends ApiManager { try { zip.extractEntryTo(entry.entryName, publicDirectory, true, false); createReadStream(pathname).pipe(createWriteStream(targetname)); - Jimp.read(pathname).then((img:any) => { + Jimp.read(pathname).then(img => { DashUploadUtils.imageResampleSizes(extension).forEach(({ width, suffix }) => { const outputPath = InjectSize(targetname, suffix); if (!width) createReadStream(pathname).pipe(createWriteStream(outputPath)); @@ -278,26 +278,28 @@ export default class UploadManager extends ApiManager { } }); const json = zip.getEntry('docs.json'); - try { - const data = JSON.parse(json.getData().toString('utf8'), retrocycle()); - const { docs, links } = data; - id = getId(data.id); - const rdocs = Object.keys(docs).map(key => docs[key]); - const ldocs = Object.keys(links).map(key => links[key]); - [...rdocs, ...ldocs].forEach(mapFn); - docids = rdocs.map(doc => doc.id); - linkids = ldocs.map(link => link.id); - await Promise.all( - [...rdocs, ...ldocs].map( - doc => - new Promise(res => { - // overwrite mongo doc with json doc contents - Database.Instance.replace(doc.id, doc, (err, r) => res(err && console.log(err)), true); - }) - ) - ); - } catch (e) { - console.log(e); + if (json) { + try { + const data = JSON.parse(json.getData().toString('utf8'), retrocycle()); + const { docs, links } = data; + id = getId(data.id); + const rdocs = Object.keys(docs).map(key => docs[key]); + const ldocs = Object.keys(links).map(key => links[key]); + [...rdocs, ...ldocs].forEach(mapFn); + docids = rdocs.map(doc => doc.id); + linkids = ldocs.map(link => link.id); + await Promise.all( + [...rdocs, ...ldocs].map( + doc => + new Promise(res => { + // overwrite mongo doc with json doc contents + Database.Instance.replace(doc.id, doc, (err, r) => res(err && console.log(err)), true); + }) + ) + ); + } catch (e) { + console.log(e); + } } unlink(path_2.filepath, () => {}); } @@ -346,7 +348,7 @@ export default class UploadManager extends ApiManager { return imageDataUri.outputFile(uri, serverPathToFile(Directory.images, InjectSize(filename, origSuffix))).then((savedName: string) => { const ext = path.extname(savedName).toLowerCase(); if (AcceptableMedia.imageFormats.includes(ext)) { - Jimp.read(savedName).then((img:any) => + Jimp.read(savedName).then(img => (!origSuffix ? [{ width: 400, suffix: SizeSuffix.Medium }] : Object.values(DashUploadUtils.Sizes)) // .forEach(({ width, suffix }) => { const outputPath = serverPathToFile(Directory.images, InjectSize(filename, suffix) + ext); diff --git a/src/server/DashStats.ts b/src/server/DashStats.ts index 8d341db63..b6164832f 100644 --- a/src/server/DashStats.ts +++ b/src/server/DashStats.ts @@ -3,23 +3,23 @@ import { Response } from 'express'; import SocketIO from 'socket.io'; import { timeMap } from './ApiManagers/UserManager'; import { WebSocket } from './websocket'; -const fs = require('fs'); +import * as fs from 'fs'; /** * DashStats focuses on tracking user data for each session. - * + * * This includes time connected, number of operations, and * the rate of their operations */ export namespace DashStats { - export const SAMPLING_INTERVAL = 1000; // in milliseconds (ms) - Time interval to update the frontend. + export const SAMPLING_INTERVAL = 1000; // in milliseconds (ms) - Time interval to update the frontend. export const RATE_INTERVAL = 10; // in seconds (s) - Used to calculate rate const statsCSVFilename = './src/server/stats/userLoginStats.csv'; const columns = ['USERNAME', 'ACTION', 'TIME']; /** - * UserStats holds the stats associated with a particular user. + * UserStats holds the stats associated with a particular user. */ interface UserStats { socketId: string; @@ -30,18 +30,18 @@ export namespace DashStats { } /** - * UserLastOperations is the queue object for each user - * storing their past operations. + * UserLastOperations is the queue object for each user + * storing their past operations. */ interface UserLastOperations { sampleOperations: number; // stores how many operations total are in this rate section (10 sec, for example) lastSampleOperations: number; // stores how many total operations were recorded at the last sample - previousOperationsQueue: number[]; // stores the operations to calculate rate. + previousOperationsQueue: number[]; // stores the operations to calculate rate. } /** * StatsDataBundle represents an object that will be sent to the frontend view - * on each websocket update. + * on each websocket update. */ interface StatsDataBundle { connectedUsers: UserStats[]; @@ -57,48 +57,44 @@ export namespace DashStats { } /** - * ServerTraffic describes the current traffic going to the backend. + * ServerTraffic describes the current traffic going to the backend. */ enum ServerTraffic { NOT_BUSY, BUSY, - VERY_BUSY + VERY_BUSY, } // These values can be changed after further testing how many - // users correspond to each traffic level in Dash. + // users correspond to each traffic level in Dash. const BUSY_SERVER_BOUND = 2; const VERY_BUSY_SERVER_BOUND = 3; - const serverTrafficMessages = [ - "Not Busy", - "Busy", - "Very Busy" - ] + const serverTrafficMessages = ['Not Busy', 'Busy', 'Very Busy']; // lastUserOperations maps each username to a UserLastOperations - // structure + // structure export const lastUserOperations = new Map(); /** * handleStats is called when the /stats route is called, providing a JSON * object with relevant stats. In this case, we return the number of - * current connections and + * current connections and * @param res Response object from Express */ export function handleStats(res: Response) { let current = getCurrentStats(); const results: CSVStore[] = []; res.json({ - currentConnections: current.length, - socketMap: current, - }); + currentConnections: current.length, + socketMap: current, + }); } /** - * getUpdatedStatesBundle() sends an updated copy of the current stats to the - * frontend /statsview route via websockets. - * + * getUpdatedStatesBundle() sends an updated copy of the current stats to the + * frontend /statsview route via websockets. + * * @returns a StatsDataBundle that is sent to the frontend view on each websocket update */ export function getUpdatedStatsBundle(): StatsDataBundle { @@ -106,43 +102,43 @@ export namespace DashStats { return { connectedUsers: current, - } + }; } /** - * handleStatsView() is called when the /statsview route is called. This + * handleStatsView() is called when the /statsview route is called. This * will use pug to render a frontend view of the current stats - * - * @param res + * + * @param res */ export function handleStatsView(res: Response) { let current = getCurrentStats(); - let connectedUsers = current.map((socketPair) => { - return socketPair.time + " - " + socketPair.username + " Operations: " + socketPair.operations; - }) + let connectedUsers = current.map(socketPair => { + return socketPair.time + ' - ' + socketPair.username + ' Operations: ' + socketPair.operations; + }); let serverTraffic = ServerTraffic.NOT_BUSY; - if(current.length < BUSY_SERVER_BOUND) { + if (current.length < BUSY_SERVER_BOUND) { serverTraffic = ServerTraffic.NOT_BUSY; - } else if(current.length >= BUSY_SERVER_BOUND && current.length < VERY_BUSY_SERVER_BOUND) { + } else if (current.length >= BUSY_SERVER_BOUND && current.length < VERY_BUSY_SERVER_BOUND) { serverTraffic = ServerTraffic.BUSY; } else { serverTraffic = ServerTraffic.VERY_BUSY; } - - res.render("stats.pug", { - title: "Dash Stats", + + res.render('stats.pug', { + title: 'Dash Stats', numConnections: connectedUsers.length, serverTraffic: serverTraffic, - serverTrafficMessage : serverTrafficMessages[serverTraffic], - connectedUsers: connectedUsers + serverTrafficMessage: serverTrafficMessages[serverTraffic], + connectedUsers: connectedUsers, }); } /** - * logUserLogin() writes a login event to the CSV file. - * + * logUserLogin() writes a login event to the CSV file. + * * @param username the username in the format of "username@domain.com logged in" * @param socket the websocket associated with the current connection */ @@ -152,12 +148,12 @@ export namespace DashStats { console.log(magenta(`User ${username.split(' ')[0]} logged in at: ${currentDate.toISOString()}`)); let toWrite: CSVStore = { - USERNAME : username, - ACTION : "loggedIn", - TIME : currentDate.toISOString() - } + USERNAME: username, + ACTION: 'loggedIn', + TIME: currentDate.toISOString(), + }; - let statsFile = fs.createWriteStream(statsCSVFilename, { flags: "a"}); + let statsFile = fs.createWriteStream(statsCSVFilename, { flags: 'a' }); statsFile.write(convertToCSV(toWrite)); statsFile.end(); console.log(cyan(convertToCSV(toWrite))); @@ -165,21 +161,21 @@ export namespace DashStats { } /** - * logUserLogout() writes a logout event to the CSV file. - * + * logUserLogout() writes a logout event to the CSV file. + * * @param username the username in the format of "username@domain.com logged in" - * @param socket the websocket associated with the current connection. + * @param socket the websocket associated with the current connection. */ export function logUserLogout(username: string | undefined, socket: SocketIO.Socket) { if (!(username === undefined)) { let currentDate = new Date(); - let statsFile = fs.createWriteStream(statsCSVFilename, { flags: "a"}); + let statsFile = fs.createWriteStream(statsCSVFilename, { flags: 'a' }); let toWrite: CSVStore = { - USERNAME : username, - ACTION : "loggedOut", - TIME : currentDate.toISOString() - } + USERNAME: username, + ACTION: 'loggedOut', + TIME: currentDate.toISOString(), + }; statsFile.write(convertToCSV(toWrite)); statsFile.end(); } @@ -188,22 +184,22 @@ export namespace DashStats { /** * getLastOperationsOrDefault() is a helper method that will attempt * to query the lastUserOperations map for a specified username. If the - * username is not in the map, an empty UserLastOperations object is returned. - * @param username + * username is not in the map, an empty UserLastOperations object is returned. + * @param username * @returns the user's UserLastOperations structure or an empty * UserLastOperations object (All values set to 0) if the username is not found. */ function getLastOperationsOrDefault(username: string): UserLastOperations { - if(lastUserOperations.get(username) === undefined) { + if (lastUserOperations.get(username) === undefined) { let initializeOperationsQueue = []; - for(let i = 0; i < RATE_INTERVAL; i++) { + for (let i = 0; i < RATE_INTERVAL; i++) { initializeOperationsQueue.push(0); } return { sampleOperations: 0, lastSampleOperations: 0, - previousOperationsQueue: initializeOperationsQueue - } + previousOperationsQueue: initializeOperationsQueue, + }; } return lastUserOperations.get(username)!; } @@ -211,19 +207,19 @@ export namespace DashStats { /** * updateLastOperations updates a specific user's UserLastOperations information * for the current sampling cycle. The method removes old/outdated counts for - * operations from the queue and adds new data for the current sampling - * cycle to the queue, updating the total count as it goes. + * operations from the queue and adds new data for the current sampling + * cycle to the queue, updating the total count as it goes. * @param lastOperationData the old UserLastOperations data that must be updated * @param currentOperations the total number of operations measured for this sampling cycle. - * @returns the udpated UserLastOperations structure. + * @returns the udpated UserLastOperations structure. */ function updateLastOperations(lastOperationData: UserLastOperations, currentOperations: number): UserLastOperations { // create a copy of the UserLastOperations to modify let newLastOperationData: UserLastOperations = { sampleOperations: lastOperationData.sampleOperations, lastSampleOperations: lastOperationData.lastSampleOperations, - previousOperationsQueue: lastOperationData.previousOperationsQueue.slice() - } + previousOperationsQueue: lastOperationData.previousOperationsQueue.slice(), + }; let newSampleOperations = newLastOperationData.sampleOperations; newSampleOperations -= newLastOperationData.previousOperationsQueue.shift()!; // removes and returns the first element of the queue @@ -241,20 +237,20 @@ export namespace DashStats { /** * getUserOperationsOrDefault() is a helper method to get the user's total - * operations for the CURRENT sampling interval. The method will return 0 + * operations for the CURRENT sampling interval. The method will return 0 * if the username is not in the userOperations map. * @param username the username to search the map for - * @returns the total number of operations recorded up to this sampling cycle. + * @returns the total number of operations recorded up to this sampling cycle. */ function getUserOperationsOrDefault(username: string): number { - return WebSocket.userOperations.get(username) === undefined ? 0 : WebSocket.userOperations.get(username)! + return WebSocket.userOperations.get(username) === undefined ? 0 : WebSocket.userOperations.get(username)!; } /** * getCurrentStats() calculates the total stats for this cycle. In this case, - * getCurrentStats() returns an Array of UserStats[] objects describing + * getCurrentStats() returns an Array of UserStats[] objects describing * the stats for each user - * @returns an array of UserStats storing data for each user at the current moment. + * @returns an array of UserStats storing data for each user at the current moment. */ function getCurrentStats(): UserStats[] { let socketPairs: UserStats[] = []; @@ -262,20 +258,20 @@ export namespace DashStats { let username = value.split(' ')[0]; let connectionTime = new Date(timeMap[username]); - let connectionTimeString = connectionTime.toLocaleDateString() + " " + connectionTime.toLocaleTimeString(); + let connectionTimeString = connectionTime.toLocaleDateString() + ' ' + connectionTime.toLocaleTimeString(); if (!key.disconnected) { let lastRecordedOperations = getLastOperationsOrDefault(username); let currentUserOperationCount = getUserOperationsOrDefault(username); - socketPairs.push({ + socketPairs.push({ socketId: key.id, username: username, - time: connectionTimeString.includes("Invalid Date") ? "" : connectionTimeString, - operations : WebSocket.userOperations.get(username) ? WebSocket.userOperations.get(username)! : 0, - rate: lastRecordedOperations.sampleOperations + time: connectionTimeString.includes('Invalid Date') ? '' : connectionTimeString, + operations: WebSocket.userOperations.get(username) ? WebSocket.userOperations.get(username)! : 0, + rate: lastRecordedOperations.sampleOperations, }); - lastUserOperations.set(username, updateLastOperations(lastRecordedOperations,currentUserOperationCount)); + lastUserOperations.set(username, updateLastOperations(lastRecordedOperations, currentUserOperationCount)); } } return socketPairs; @@ -283,9 +279,9 @@ export namespace DashStats { /** * convertToCSV() is a helper method that stringifies a CSVStore object - * that can be written to the CSV file later. + * that can be written to the CSV file later. * @param dataObject the object to stringify - * @returns the object as a string. + * @returns the object as a string. */ function convertToCSV(dataObject: CSVStore): string { return `${dataObject.USERNAME},${dataObject.ACTION},${dataObject.TIME}\n`; diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts index 0161a8d38..a8e09818e 100644 --- a/src/server/DashUploadUtils.ts +++ b/src/server/DashUploadUtils.ts @@ -20,12 +20,12 @@ import { AzureManager } from './ApiManagers/AzureManager'; import axios from 'axios'; const spawn = require('child_process').spawn; const { exec } = require('child_process'); -const parse = require('pdf-parse'); -const ffmpeg = require('fluent-ffmpeg'); -const fs = require('fs'); const requestImageSize = require('../client/util/request-image-size'); -const md5File = require('md5-file'); -const autorotate = require('jpeg-autorotate'); +import * as parse from 'pdf-parse'; +import { ffprobe, FfmpegCommand } from 'fluent-ffmpeg'; +import * as fs from 'fs'; +import * as md5File from 'md5-file'; +import * as autorotate from 'jpeg-autorotate'; export enum SizeSuffix { Small = '_s', @@ -95,7 +95,7 @@ export namespace DashUploadUtils { // concatenate the videos await new Promise((resolve, reject) => { - var merge = ffmpeg(); + var merge = new FfmpegCommand(); merge .input(textFilePath) .inputOptions(['-f concat', '-safe 0']) @@ -152,7 +152,7 @@ export namespace DashUploadUtils { exec(`yt-dlp -o ${finalPath} "https://www.youtube.com/watch?v=${videoId}" --get-duration`, (error: any, stdout: any, stderr: any) => { const time = Array.from(stdout.trim().split(':')).reverse(); const duration = (time.length > 2 ? Number(time[2]) * 1000 * 60 : 0) + (time.length > 1 ? Number(time[1]) * 60 : 0) + (time.length > 0 ? Number(time[0]) : 0); - res(resolveExistingFile(name, finalPath, Directory.videos, 'video/mp4', duration, undefined)); + res(resolveExistingFile(name, filepath, Directory.videos, 'video/mp4', duration, undefined)); }); } else { uploadProgress.set(overwriteId, 'starting download'); @@ -185,9 +185,12 @@ export namespace DashUploadUtils { exec(`yt-dlp-o ${filepath} "https://www.youtube.com/watch?v=${videoId}" --get-duration`, (error: any, stdout: any, stderr: any) => { const time = Array.from(stdout.trim().split(':')).reverse(); const duration = (time.length > 2 ? Number(time[2]) * 1000 * 60 : 0) + (time.length > 1 ? Number(time[1]) * 60 : 0) + (time.length > 0 ? Number(time[0]) : 0); - const data = { size: 0, filepath, name, mimetype: '', originalFilename: name, newFilename: name, hashAlgorithm: 'md5' as 'md5', type: 'video/mp4' }; - const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date(), mime: '', hashAlgorithm: 'md5' as 'md5', toJson: () => undefined as any }) }; - res(MoveParsedFile(file, Directory.videos)); + const data = { size: 0, filepath, name, mimetype: 'video', originalFilename: name, newFilename: name, hashAlgorithm: 'md5' as 'md5', type: 'video/mp4' }; + const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date(), toJson: () => undefined as any }) }; + MoveParsedFile(file, Directory.videos).then(output => { + console.log('OUTPUT = ' + output); + res(output); + }); }); } }); @@ -217,7 +220,7 @@ export namespace DashUploadUtils { if (format.includes('x-matroska')) { console.log('case video'); await new Promise(res => - ffmpeg(file.filepath) + new FfmpegCommand(file.filepath) .videoCodec('copy') // this will copy the data instead of reencode it .save(file.filepath.replace('.mkv', '.mp4')) .on('end', res) @@ -229,7 +232,7 @@ export namespace DashUploadUtils { if (format.includes('quicktime')) { let abort = false; await new Promise(res => - ffmpeg.ffprobe(file.filepath, (err: any, metadata: any) => { + ffprobe(file.filepath, (err: any, metadata: any) => { if (metadata.streams.some((stream: any) => stream.codec_name === 'hevc')) { abort = true; } @@ -615,13 +618,13 @@ export namespace DashUploadUtils { buffer = buffer2; } catch (e) {} return Jimp.read(buffer ?? fileIn) - .then(async (img:any) => { + .then(async (img: any) => { await Promise.all( sizes.filter(({ width }) => width) .map(({ width, suffix }) => img = img.resize(width, Jimp.AUTO).write(outputPath(suffix)) )); // prettier-ignore return writtenFiles; }) - .catch((e:any) => { + .catch((e: any) => { console.log('ERROR' + e); return writtenFiles; }); diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts index 12fb42077..8f21966ae 100644 --- a/src/typings/index.d.ts +++ b/src/typings/index.d.ts @@ -2,17 +2,17 @@ declare module 'googlephotos'; declare module 'cors'; +declare module 'image-data-uri'; +declare module 'md5-file'; +declare module 'jpeg-autorotate'; declare module 'webrtc-adapter'; declare module 'bezier-curve'; declare module 'fit-curve'; -declare module 'react-audio-waveform'; declare module 'iink-js'; declare module 'pdfjs-dist/web/pdf_viewer'; +declare module 'react-jsx-parser'; -declare module 'reveal'; -declare module 'react-reveal'; -declare module 'react-reveal/makeCarousel'; declare module 'express-flash'; declare module 'connect-flash' { interface flash {} -- cgit v1.2.3-70-g09d2 From 9b9f54a43793ca6ffb26c56f962d11ba8325abd2 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 29 Dec 2023 17:01:40 -0500 Subject: cleaned up imports, mobx observable initialization and some compile errors. --- src/Utils.ts | 27 ++--- src/client/util/CalendarManager.tsx | 34 +++--- src/client/util/CaptureManager.tsx | 2 +- src/client/util/CurrentUserUtils.ts | 14 +-- src/client/util/GroupManager.tsx | 2 +- src/client/util/HypothesisUtils.ts | 13 ++- src/client/views/DocumentButtonBar.tsx | 5 - src/client/views/DocumentDecorations.tsx | 11 +- src/client/views/FilterPanel.tsx | 11 +- src/client/views/GestureOverlay.tsx | 25 +++-- src/client/views/InkTranscription.tsx | 8 +- src/client/views/InkingStroke.tsx | 76 +++++--------- src/client/views/MainView.tsx | 2 +- src/client/views/MetadataEntryMenu.tsx | 12 +-- src/client/views/PreviewCursor.tsx | 2 +- src/client/views/PropertiesButtons.tsx | 17 +-- .../views/PropertiesDocBacklinksSelector.tsx | 4 +- src/client/views/PropertiesSection.tsx | 6 +- src/client/views/TemplateMenu.tsx | 2 +- src/client/views/UndoStack.tsx | 22 ++-- src/client/views/animationtimeline/Region.tsx | 2 +- src/client/views/animationtimeline/Timeline.tsx | 4 +- .../views/animationtimeline/TimelineOverview.tsx | 2 +- src/client/views/animationtimeline/Track.tsx | 8 +- .../views/collections/CollectionCalendarView.tsx | 19 ++-- .../views/collections/CollectionDockingView.tsx | 4 +- src/client/views/collections/CollectionMenu.tsx | 3 - .../CollectionNoteTakingViewDivider.tsx | 2 +- .../views/collections/CollectionPileView.tsx | 2 +- .../collections/CollectionStackedTimeline.tsx | 4 +- .../CollectionStackingViewFieldColumn.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 8 +- .../views/collections/CollectionTimeView.tsx | 14 +-- src/client/views/collections/CollectionView.tsx | 2 +- src/client/views/collections/KeyRestrictionRow.tsx | 37 +++---- src/client/views/collections/TreeView.tsx | 2 +- .../CollectionFreeFormBackgroundGrid.tsx | 2 +- .../CollectionFreeFormInfoState.tsx | 2 +- .../CollectionFreeFormInfoUI.tsx | 8 +- .../CollectionFreeFormLinksView.tsx | 4 +- .../CollectionFreeFormPannableContents.tsx | 5 +- .../CollectionFreeFormRemoteCursors.tsx | 4 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 5 +- .../collectionGrid/CollectionGridView.tsx | 4 +- .../views/collections/collectionGrid/Grid.tsx | 2 +- .../CollectionMulticolumnView.tsx | 4 +- .../CollectionMultirowView.tsx | 3 +- .../collectionMulticolumn/MulticolumnResizer.tsx | 8 +- .../MulticolumnWidthLabel.tsx | 27 +++-- .../collectionMulticolumn/MultirowHeightLabel.tsx | 22 ++-- .../collectionMulticolumn/MultirowResizer.tsx | 6 +- .../collectionSchema/SchemaColumnHeader.tsx | 4 +- src/client/views/linking/LinkMenuItem.tsx | 6 +- src/client/views/linking/LinkPopup.tsx | 8 +- .../views/linking/LinkRelationshipSearch.tsx | 2 +- .../views/newlightbox/ButtonMenu/ButtonMenu.tsx | 4 +- src/client/views/newlightbox/NewLightboxView.tsx | 26 ++--- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 4 +- .../views/nodes/DataVizBox/SchemaCSVPopUp.tsx | 30 +++--- .../nodes/DataVizBox/components/Histogram.tsx | 6 +- .../nodes/DataVizBox/components/LineChart.tsx | 28 ++--- .../views/nodes/DataVizBox/components/PieChart.tsx | 6 +- .../views/nodes/DataVizBox/components/TableBox.tsx | 12 +-- src/client/views/nodes/DocumentContentsView.tsx | 6 +- src/client/views/nodes/DocumentView.tsx | 7 +- src/client/views/nodes/FaceRectangle.tsx | 4 +- src/client/views/nodes/FaceRectangles.tsx | 4 +- src/client/views/nodes/FieldView.tsx | 2 +- src/client/views/nodes/KeyValuePair.tsx | 6 +- src/client/views/nodes/LinkDescriptionPopup.tsx | 2 +- src/client/views/nodes/LinkDocPreview.tsx | 8 +- src/client/views/nodes/LoadingBox.tsx | 2 +- src/client/views/nodes/MapBox/AnimationUtility.ts | 13 +-- .../views/nodes/MapBox/DirectionsAnchorMenu.tsx | 14 +-- src/client/views/nodes/MapBox/MapAnchorMenu.tsx | 106 +++++++------------ src/client/views/nodes/MapBox/MapBox.tsx | 60 +++++------ src/client/views/nodes/MapBox/MapBox2.tsx | 2 +- .../views/nodes/MapboxMapBox/MapboxContainer.tsx | 20 ++-- src/client/views/nodes/PDFBox.tsx | 2 +- .../nodes/PhysicsBox/PhysicsSimulationBox.tsx | 4 +- .../nodes/PhysicsBox/PhysicsSimulationWeight.tsx | 2 +- src/client/views/nodes/RadialMenu.tsx | 2 +- src/client/views/nodes/RadialMenuItem.tsx | 2 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 4 +- src/client/views/nodes/ScreenshotBox.tsx | 2 +- src/client/views/nodes/ScriptingBox.tsx | 8 +- src/client/views/nodes/TaskCompletedBox.tsx | 8 +- src/client/views/nodes/VideoBox.tsx | 6 +- src/client/views/nodes/audio/AudioWaveform.tsx | 2 +- src/client/views/nodes/calendarBox/CalendarBox.tsx | 114 +++++++++------------ .../views/nodes/formattedText/DashDocView.tsx | 6 +- .../views/nodes/formattedText/EquationView.tsx | 7 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 4 +- .../views/nodes/formattedText/RichTextMenu.tsx | 2 +- .../views/nodes/importBox/ImportElementBox.tsx | 8 +- src/client/views/nodes/trails/PresBox.tsx | 6 +- src/client/views/pdf/Annotation.tsx | 5 +- src/client/views/pdf/GPTPopup/GPTPopup.tsx | 16 +-- src/client/views/pdf/PDFViewer.tsx | 2 +- src/client/views/search/SearchBox.tsx | 15 ++- src/client/views/selectedDoc/SelectedDocView.tsx | 6 +- src/client/views/topbar/TopBar.tsx | 4 +- src/client/views/webcam/DashWebRTCVideo.tsx | 5 +- src/debug/Repl.tsx | 10 +- src/debug/Viewer.tsx | 18 ++-- src/fields/CursorField.ts | 7 +- src/fields/Doc.ts | 4 +- src/fields/List.ts | 8 +- src/fields/Proxy.ts | 12 +-- src/fields/util.ts | 4 +- src/mobile/ImageUpload.tsx | 6 +- src/mobile/MobileInkOverlay.tsx | 2 +- src/mobile/MobileInterface.tsx | 110 ++++++++++---------- src/typings/index.d.ts | 4 +- test/test.ts | 106 ++++++++++--------- 116 files changed, 650 insertions(+), 793 deletions(-) (limited to 'src/client/views/nodes/audio') diff --git a/src/Utils.ts b/src/Utils.ts index a060e4a2c..b5c218e01 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -1,13 +1,12 @@ -import * as uuid from 'uuid'; import { ColorResult } from 'react-color'; +import * as uuid from 'uuid'; //import { Socket } from '../node_modules/socket.io-client'; -import { Socket } from '../node_modules/socket.io/dist/index'; +import * as Color from 'color'; import * as rp from 'request-promise'; +import { Socket } from '../node_modules/socket.io/dist/index'; import { DocumentType } from './client/documents/DocumentTypes'; import { Colors } from './client/views/global/globalEnums'; import { Message } from './server/Message'; -import * as Color from 'color'; -import { action } from 'mobx'; export namespace Utils { export let CLICK_TIME = 300; @@ -896,23 +895,19 @@ export function setupMoveUpEvents( document.addEventListener('click', _clickEvent, true); } -export function dateRangeStrToDates (dateStr: string) { +export function dateRangeStrToDates(dateStr: string) { // dateStr in yyyy-mm-dd format - const dateRangeParts = dateStr.split("|"); // splits into from and to date - const fromParts = dateRangeParts[0].split("-"); - const toParts = dateRangeParts[1].split("-"); + const dateRangeParts = dateStr.split('|'); // splits into from and to date + const fromParts = dateRangeParts[0].split('-'); + const toParts = dateRangeParts[1].split('-'); const fromYear = parseInt(fromParts[0]); - const fromMonth = parseInt(fromParts[1])-1; + const fromMonth = parseInt(fromParts[1]) - 1; const fromDay = parseInt(fromParts[2]); const toYear = parseInt(toParts[0]); - const toMonth = parseInt(toParts[1])-1; + const toMonth = parseInt(toParts[1]) - 1; const toDay = parseInt(toParts[2]); - - return [ - new Date(fromYear, fromMonth, fromDay), - new Date(toYear, toMonth, toDay) - ]; -} \ No newline at end of file + return [new Date(fromYear, fromMonth, fromDay), new Date(toYear, toMonth, toDay)]; +} diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx index 6ef2d3429..6e9094b3a 100644 --- a/src/client/util/CalendarManager.tsx +++ b/src/client/util/CalendarManager.tsx @@ -1,26 +1,24 @@ -import * as React from 'react'; -import './CalendarManager.scss'; +import { TextField } from '@mui/material'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; -import { action, computed, observable, runInAction, makeObservable } from 'mobx'; +import * as React from 'react'; +import Select from 'react-select'; import { Doc, DocListCast } from '../../fields/Doc'; -import { DocumentView } from '../views/nodes/DocumentView'; +import { DocData } from '../../fields/DocSymbols'; +import { StrCast } from '../../fields/Types'; import { DictationOverlay } from '../views/DictationOverlay'; -import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox'; import { MainViewModal } from '../views/MainViewModal'; -import { TextField } from '@mui/material'; -import Select from 'react-select'; -import { SettingsManager } from './SettingsManager'; -import { DateCast, DocCast, StrCast } from '../../fields/Types'; -import { SelectionManager } from './SelectionManager'; +import { DocumentView } from '../views/nodes/DocumentView'; +import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox'; +import './CalendarManager.scss'; import { DocumentManager } from './DocumentManager'; -import { DocData } from '../../fields/DocSymbols'; +import { SelectionManager } from './SelectionManager'; +import { SettingsManager } from './SettingsManager'; // import { DateRange, Range, RangeKeyDict } from 'react-date-range'; -import { Button } from 'browndash-components'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Provider, defaultTheme } from '@adobe/react-spectrum'; -import { DateValue } from '@internationalized/date'; -import { DateRangePicker, SpectrumDateRangePickerProps } from '@adobe/react-spectrum'; +import { DateRangePicker, Provider, defaultTheme } from '@adobe/react-spectrum'; import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Button } from 'browndash-components'; import { Docs } from '../documents/Documents'; import { ObservableReactComponent } from '../views/ObservableReactComponent'; // import 'react-date-range/dist/styles.css'; @@ -51,8 +49,8 @@ const formatCalendarDateToString = (calendarDate: any) => { export class CalendarManager extends ObservableReactComponent<{}> { public static Instance: CalendarManager; @observable private isOpen = false; - @observable private targetDoc: Doc | undefined; // the target document - @observable private targetDocView: DocumentView | undefined; // the DocumentView of the target doc + @observable private targetDoc: Doc | undefined = undefined; // the target document + @observable private targetDocView: DocumentView | undefined = undefined; // the DocumentView of the target doc @observable private dialogueBoxOpacity = 1; // for the modal @observable private overlayOpacity = 0.4; // for the modal diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx index 071fc1ee9..c1e0a5b2e 100644 --- a/src/client/util/CaptureManager.tsx +++ b/src/client/util/CaptureManager.tsx @@ -15,7 +15,7 @@ import { SelectionManager } from './SelectionManager'; export class CaptureManager extends React.Component<{}> { public static Instance: CaptureManager; static _settingsStyle = addStyleSheet(); - @observable _document: any; + @observable _document: any = undefined; @observable isOpen: boolean = false; // whether the CaptureManager is to be displayed or not. constructor(props: {}) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index c1d74c398..3f28f44fc 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1,5 +1,6 @@ import { observable, reaction, runInAction } from "mobx"; import * as rp from 'request-promise'; +import { OmitKeys, Utils } from "../../Utils"; import { Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc"; import { InkTool } from "../../fields/InkField"; import { List } from "../../fields/List"; @@ -8,29 +9,28 @@ import { RichTextField } from "../../fields/RichTextField"; import { listSpec } from "../../fields/Schema"; import { ScriptField } from "../../fields/ScriptField"; import { Cast, DateCast, DocCast, StrCast } from "../../fields/Types"; -import { nullAudio, WebField } from "../../fields/URLField"; +import { WebField, nullAudio } from "../../fields/URLField"; import { SetCachedGroups, SharingPermissions } from "../../fields/util"; import { GestureUtils } from "../../pen-gestures/GestureUtils"; -import { OmitKeys, Utils } from "../../Utils"; import { DocServer } from "../DocServer"; -import { Docs, DocumentOptions, DocUtils, FInfo } from "../documents/Documents"; import { CollectionViewType, DocumentType } from "../documents/DocumentTypes"; -import { TreeViewType } from "../views/collections/CollectionTreeView"; +import { DocUtils, Docs, DocumentOptions, FInfo } from "../documents/Documents"; import { DashboardView } from "../views/DashboardView"; +import { OverlayView } from "../views/OverlayView"; +import { TreeViewType } from "../views/collections/CollectionTreeView"; import { Colors } from "../views/global/globalEnums"; import { media_state } from "../views/nodes/AudioBox"; -import { DocumentView, OpenWhere } from "../views/nodes/DocumentView"; +import { OpenWhere } from "../views/nodes/DocumentView"; import { ButtonType } from "../views/nodes/FontIconBox/FontIconBox"; import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox"; -import { OverlayView } from "../views/OverlayView"; import { DragManager, dropActionType } from "./DragManager"; import { MakeTemplate } from "./DropConverter"; import { FollowLinkScript } from "./LinkFollower"; import { LinkManager } from "./LinkManager"; import { ScriptingGlobals } from "./ScriptingGlobals"; import { ColorScheme } from "./SettingsManager"; -import { UndoManager } from "./UndoManager"; import { SnappingManager } from "./SnappingManager"; +import { UndoManager } from "./UndoManager"; interface Button { // DocumentOptions fields a button can set diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx index 90f65b648..f4f879208 100644 --- a/src/client/util/GroupManager.tsx +++ b/src/client/util/GroupManager.tsx @@ -33,7 +33,7 @@ export class GroupManager extends ObservableReactComponent<{}> { @observable isOpen: boolean = false; // whether the GroupManager is to be displayed or not. @observable private users: string[] = []; // list of users populated from the database. @observable private selectedUsers: UserOptions[] | null = null; // list of users selected in the "Select users" dropdown. - @observable currentGroup: Opt; // the currently selected group. + @observable currentGroup: Opt = undefined; // the currently selected group. @observable private createGroupModalOpen: boolean = false; private inputRef: React.RefObject = React.createRef(); // the ref for the input box. private createGroupButtonRef: React.RefObject = React.createRef(); // the ref for the group creation button diff --git a/src/client/util/HypothesisUtils.ts b/src/client/util/HypothesisUtils.ts index 990798ed3..0ae23d793 100644 --- a/src/client/util/HypothesisUtils.ts +++ b/src/client/util/HypothesisUtils.ts @@ -1,16 +1,15 @@ -import { StrCast, Cast } from '../../fields/Types'; -import { SearchUtil } from './SearchUtil'; import { action, runInAction } from 'mobx'; +import { simulateMouseClick } from '../../Utils'; import { Doc, Opt } from '../../fields/Doc'; +import { Cast, StrCast } from '../../fields/Types'; +import { WebField } from '../../fields/URLField'; import { DocumentType } from '../documents/DocumentTypes'; import { Docs } from '../documents/Documents'; -import { SelectionManager } from './SelectionManager'; -import { WebField } from '../../fields/URLField'; -import { DocumentManager } from './DocumentManager'; import { DocumentLinksButton } from '../views/nodes/DocumentLinksButton'; -import { simulateMouseClick, Utils } from '../../Utils'; import { DocumentView } from '../views/nodes/DocumentView'; -import { Id } from '../../fields/FieldSymbols'; +import { DocumentManager } from './DocumentManager'; +import { SearchUtil } from './SearchUtil'; +import { SelectionManager } from './SelectionManager'; export namespace Hypothesis { /** diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index f0887676f..3938b81cd 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -40,14 +40,9 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( private _pullAnimating = false; private _pushAnimating = false; private _pullColorAnimating = false; - @observable private pushIcon: IconProp = 'arrow-alt-circle-up'; - @observable private pullIcon: IconProp = 'arrow-alt-circle-down'; - @observable private pullColor: string = 'white'; @observable public isAnimatingFetch = false; @observable public isAnimatingPulse = false; - @observable private openHover: UtilityButtonState = UtilityButtonState.Default; - @observable public static Instance: DocumentButtonBar; public static hasPushedHack = false; public static hasPulledHack = false; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index d2f23c2f3..dab6e6193 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -12,7 +12,7 @@ import { RichTextField } from '../../fields/RichTextField'; import { ScriptField } from '../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types'; import { GetEffectiveAcl } from '../../fields/util'; -import { emptyFunction, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils'; +import { emptyFunction, lightOrDark, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils'; import { Docs } from '../documents/Documents'; import { DocumentType } from '../documents/DocumentTypes'; import { DocumentManager } from '../util/DocumentManager'; @@ -85,7 +85,7 @@ export class DocumentDecorations extends ObservableReactComponent; - @observable public SavedColor?: string; - @observable public SavedWidth?: number; + @observable public InkShape: Opt = undefined; + @observable public SavedColor?: string = undefined; + @observable public SavedWidth?: number = undefined; @observable public Tool: ToolglassTools = ToolglassTools.None; @observable public KeepPrimitiveMode = false; // for whether primitive selection enters a one-shot or persistent mode - @observable private _thumbX?: number; - @observable private _thumbY?: number; + @observable private _thumbX?: number = undefined; + @observable private _thumbY?: number = undefined; @observable private _selectedIndex: number = -1; @observable private _menuX: number = -300; @observable private _menuY: number = -300; - @observable private _pointerY?: number; + @observable private _pointerY?: number = undefined; @observable private _points: { X: number; Y: number }[] = []; @observable private _strokes: InkData[] = []; - @observable private _palette?: JSX.Element; - @observable private _clipboardDoc?: JSX.Element; + @observable private _palette?: JSX.Element = undefined; + @observable private _clipboardDoc?: JSX.Element = undefined; @observable private _possibilities: JSX.Element[] = []; public static DownDocView: DocumentView | undefined; diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx index b2ac208ca..7e2b334af 100644 --- a/src/client/views/InkTranscription.tsx +++ b/src/client/views/InkTranscription.tsx @@ -17,10 +17,10 @@ // export class InkTranscription extends React.Component { // static Instance: InkTranscription; -// @observable _mathRegister: any; -// @observable _mathRef: any; -// @observable _textRegister: any; -// @observable _textRef: any; +// @observable _mathRegister: any= undefined; +// @observable _mathRef: any= undefined; +// @observable _textRegister: any= undefined; +// @observable _textRef: any= undefined; // private lastJiix: any; // private currGroup?: Doc; diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 9c96b4563..95c677845 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -20,9 +20,9 @@ Most of the operations that can be performed on an InkStroke (eg delete a point, rotate, stretch) are implemented in the InkStrokeProperties helper class */ -import * as React from 'react'; import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc } from '../../fields/Doc'; import { InkData, InkField } from '../../fields/InkField'; import { BoolCast, Cast, NumCast, RTFCast, StrCast } from '../../fields/Types'; @@ -32,7 +32,6 @@ import { CognitiveServices } from '../cognitive_services/CognitiveServices'; import { Docs } from '../documents/Documents'; import { InteractionUtils } from '../util/InteractionUtils'; import { SnappingManager } from '../util/SnappingManager'; -import { Transform } from '../util/Transform'; import { UndoManager } from '../util/UndoManager'; import { ContextMenu } from './ContextMenu'; import { ViewBoxBaseComponent } from './DocComponent'; @@ -59,14 +58,14 @@ export class InkingStroke extends ViewBoxBaseComponent() { private _handledClick = false; // flag denoting whether ink stroke has handled a psuedo-click onPointerUp so that the real onClick event can be stopPropagated private _disposers: { [key: string]: IReactionDisposer } = {}; - @observable _nearestSeg?: number; // nearest Bezier segment along the ink stroke to the cursor (used for displaying the Add Point highlight) - @observable _nearestT?: number; // nearest t value within the nearest Bezier segment " + @observable _nearestSeg?: number = undefined; // nearest Bezier segment along the ink stroke to the cursor (used for displaying the Add Point highlight) + @observable _nearestT?: number = undefined; // nearest t value within the nearest Bezier segment " @observable _nearestScrPt?: { X: number; Y: number }; // nearst screen point on the ink stroke "" componentDidMount() { - this.props.setContentView?.(this); + this._props.setContentView?.(this); this._disposers.selfDisper = reaction( - () => this.props.isSelected(), // react to stroke being deselected by turning off ink handles + () => this._props.isSelected(), // react to stroke being deselected by turning off ink handles selected => !selected && (InkStrokeProperties.Instance._controlButton = false) ); } @@ -76,7 +75,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { // transform is the inherited screentolocal xf plus any scaling that was done to make the stroke // fit within its panel (e.g., for content fitting views like Lightbox or multicolumn, etc) - screenToLocal = () => this.props.ScreenToLocalTransform().scale(this.props.NativeDimScaling?.() || 1); + screenToLocal = () => this._props.ScreenToLocalTransform().scale(this._props.NativeDimScaling?.() || 1); getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { const subAnchor = this._subContentView?.getAnchor?.(addAsAnnotation); @@ -100,27 +99,6 @@ export class InkingStroke extends ViewBoxBaseComponent() { return this.Document; }; - /** - * @returns the center of the ink stroke in the ink document's coordinate space (not screen space, and not the ink data coordinate space); - * DocumentDecorations calls getBounds() on DocumentViews which call getCenter() if defined - in the case of ink it needs to be defined since - * the center of the ink stroke changes as the stroke is rotated. - */ - getCenter = (xf: Transform) => { - const { inkData, inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData(); - const angle = -NumCast(this.layoutDoc.rotation); - const newPoints = inkData.map(pt => { - const newX = Math.cos(angle) * pt.X - (Math.sin(angle) * pt.Y * inkScaleY) / inkScaleX; - const newY = (Math.sin(angle) * pt.X * inkScaleX) / inkScaleY + Math.cos(angle) * pt.Y; - return { X: newX, Y: newY }; - }); - const crx = (Math.max(...newPoints.map(np => np.X)) + Math.min(...newPoints.map(np => np.X))) / 2; - const cry = (Math.max(...newPoints.map(np => np.Y)) + Math.min(...newPoints.map(np => np.Y))) / 2; - const cx = Math.cos(-angle) * crx - (Math.sin(-angle) * cry * inkScaleY) / inkScaleX; - const cy = (Math.sin(-angle) * crx * inkScaleX) / inkScaleY + Math.cos(-angle) * cry; - const tc = xf.transformPoint((cx - inkLeft - inkStrokeWidth / 2) * inkScaleX + inkStrokeWidth / 2, (cy - inkTop - inkStrokeWidth / 2) * inkScaleY + inkStrokeWidth / 2); - return { X: tc[0], Y: tc[1] }; - }; - /** * analyzes the ink stroke and saves the analysis of the stroke to the 'inkAnalysis' field, * and the recognized words to the 'handwriting' @@ -147,7 +125,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { @action onPointerDown = (e: React.PointerEvent) => { this._handledClick = false; - const inkView = this.props.docViewPath().lastElement(); + const inkView = this._props.docViewPath().lastElement(); const { inkData, inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData(); const screenPts = inkData .map(point => @@ -159,7 +137,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { const { nearestSeg } = InkStrokeProperties.nearestPtToStroke(screenPts, { X: e.clientX, Y: e.clientY }); const controlIndex = nearestSeg; const wasSelected = InkStrokeProperties.Instance._currentPoint === controlIndex; - const isEditing = InkStrokeProperties.Instance._controlButton && this.props.isSelected(); + const isEditing = InkStrokeProperties.Instance._controlButton && this._props.isSelected(); this.controlUndo = undefined; setupMoveUpEvents( this, @@ -187,7 +165,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { InkStrokeProperties.Instance._currentPoint = -1; this._handledClick = true; // mark the double-click pseudo pointerevent so we can block the real mouse event from propagating to DocumentView if (isEditing) { - this._nearestT && this._nearestSeg !== undefined && InkStrokeProperties.Instance.addPoints(this.props.docViewPath().lastElement(), this._nearestT, this._nearestSeg, this.inkScaledData().inkData.slice()); + this._nearestT && this._nearestSeg !== undefined && InkStrokeProperties.Instance.addPoints(this._props.docViewPath().lastElement(), this._nearestT, this._nearestSeg, this.inkScaledData().inkData.slice()); } } }), @@ -258,8 +236,8 @@ export class InkingStroke extends ViewBoxBaseComponent() { inkLeft, inkWidth, inkHeight, - inkScaleX: (this.props.PanelWidth() - inkStrokeWidth) / (inkWidth - inkStrokeWidth || 1) || 1, - inkScaleY: (this.props.PanelHeight() - inkStrokeWidth) / (inkHeight - inkStrokeWidth || 1) || 1, + inkScaleX: (this._props.PanelWidth() - inkStrokeWidth) / (inkWidth - inkStrokeWidth || 1) || 1, + inkScaleY: (this._props.PanelHeight() - inkStrokeWidth) / (inkHeight - inkStrokeWidth || 1) || 1, }; }; @@ -311,7 +289,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { * @returns the JSX controls for displaying an editing UI for the stroke (control point & tangent handles) */ componentUI = (boundsLeft: number, boundsTop: number) => { - const inkDoc = this.props.Document; + const inkDoc = this.Document; const { inkData, inkStrokeWidth } = this.inkScaledData(); const screenSpaceCenterlineStrokeWidth = Math.min(3, inkStrokeWidth * this.screenToLocal().inverse().Scale); // the width of the blue line widget that shows the centerline of the ink stroke @@ -321,7 +299,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { const endMarker = StrCast(this.layoutDoc.stroke_endMarker); const markerScale = NumCast(this.layoutDoc.stroke_markerScale); return SnappingManager.IsDragging ? null : !InkStrokeProperties.Instance._controlButton ? ( - !this.props.isSelected() || InkingStroke.IsClosed(inkData) ? null : ( + !this._props.isSelected() || InkingStroke.IsClosed(inkData) ? null : (
@@ -360,12 +338,12 @@ export class InkingStroke extends ViewBoxBaseComponent() { setSubContentView = (doc: DocComponentView) => (this._subContentView = doc); @computed get fillColor() { const isInkMask = BoolCast(this.layoutDoc.stroke_isInkMask); - return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FillColor) ?? 'transparent'; + return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FillColor) ?? 'transparent'; } @computed get strokeColor() { const { inkData } = this.inkScaledData(); const fillColor = this.fillColor; - return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color) ?? StrCast(this.layoutDoc.color); + return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) ?? StrCast(this.layoutDoc.color); } render() { TraceMobx(); @@ -385,9 +363,9 @@ export class InkingStroke extends ViewBoxBaseComponent() { this.layoutDoc._height = Math.round(NumCast(this.layoutDoc._height)); }); } - const highlight = !this.controlUndo && this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Highlighting); + const highlight = !this.controlUndo && this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting); const highlightIndex = highlight?.highlightIndex; - const highlightColor = !this.props.isSelected() && !isInkMask && highlight?.highlightIndex ? highlight?.highlightColor : undefined; + const highlightColor = !this._props.isSelected() && !isInkMask && highlight?.highlightIndex ? highlight?.highlightColor : undefined; const color = StrCast(this.layoutDoc.stroke_outlineColor, !closed && fillColor && fillColor !== 'transparent' ? StrCast(this.layoutDoc.color, 'transparent') : 'transparent'); // Visually renders the polygonal line made by the user. @@ -437,7 +415,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { inkScaleX, inkScaleY, '', - this.props.pointerEvents?.() ?? 'visiblepainted', + this._props.pointerEvents?.() ?? 'visiblepainted', 0.0, false, downHdlr, @@ -450,7 +428,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { const lineHeightGuess = +getComputedStyle(document.body).lineHeight.replace('px', '') / +getComputedStyle(document.body).fontSize.replace('px', ''); const interactions = { onPointerLeave: action(() => (this._nearestScrPt = undefined)), - onPointerMove: this.props.isSelected() ? this.onPointerMove : undefined, + onPointerMove: this._props.isSelected() ? this.onPointerMove : undefined, onClick: (e: React.MouseEvent) => this._handledClick && e.stopPropagation(), onContextMenu: () => { const cm = ContextMenu.Instance; @@ -464,27 +442,27 @@ export class InkingStroke extends ViewBoxBaseComponent() { {clickableLine(this.onPointerDown, isInkMask)} {isInkMask ? null : inkLine} - {!closed || (!RTFCast(this.dataDoc.text)?.Text && (!this.props.isSelected() || Doc.UserDoc().activeInkHideTextLabels)) ? null : ( + {!closed || (!RTFCast(this.dataDoc.text)?.Text && (!this._props.isSelected() || Doc.UserDoc().activeInkHideTextLabels)) ? null : (
() { dontRegisterView={true} noSidebar={true} dontScale={true} - isContentActive={this.props.isContentActive} + isContentActive={this._props.isContentActive} />
)} diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 094bd2adb..35ffab337 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -118,7 +118,7 @@ export class MainView extends ObservableReactComponent<{}> { @computed private get userDoc() { return Doc.UserDoc(); } - @observable mainDoc: Opt; + @observable mainDoc: Opt = undefined; @computed private get mainContainer() { if (window.location.pathname.startsWith('/doc/') && Doc.CurrentUserEmail === 'guest') { DocServer.GetRefField(window.location.pathname.substring('/doc/'.length)).then(main => runInAction(() => (this.mainDoc = main as Doc))); diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx index 5c6912121..89c3c41f8 100644 --- a/src/client/views/MetadataEntryMenu.tsx +++ b/src/client/views/MetadataEntryMenu.tsx @@ -1,12 +1,12 @@ -import * as React from 'react'; -import './MetadataEntryMenu.scss'; +import { IReactionDisposer, action, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; -import { observable, action, runInAction, trace, computed, IReactionDisposer, reaction } from 'mobx'; -import { KeyValueBox } from './nodes/KeyValueBox'; -import { Doc, Field, DocListCastAsync, DocListCast } from '../../fields/Doc'; +import * as React from 'react'; import * as Autosuggest from 'react-autosuggest'; -import { undoBatch, UndoManager } from '../util/UndoManager'; import { emptyFunction, emptyPath } from '../../Utils'; +import { Doc, DocListCast, Field } from '../../fields/Doc'; +import { undoBatch } from '../util/UndoManager'; +import './MetadataEntryMenu.scss'; +import { KeyValueBox } from './nodes/KeyValueBox'; export type DocLike = Doc | Doc[] | Promise | Promise; export interface MetadataEntryProps { diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 166afc0c2..a69a5f5e8 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -24,7 +24,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> { _addLiveTextDoc?: (doc: Doc) => void; _nudge?: undefined | ((x: number, y: number) => boolean); _slowLoadDocuments?: (files: File[] | string, options: DocumentOptions, generatedDocuments: Doc[], text: string, completed: ((doc: Doc[]) => void) | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => Promise; - @observable _clickPoint: number[]; + @observable _clickPoint: number[] = []; @observable public Visible = false; public Doc: Opt; constructor(props: any) { diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 8540e81e1..f1dadcd5e 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -2,6 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Dropdown, DropdownType, IListItemProps, Toggle, ToggleType, Type } from 'browndash-components'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { AiOutlineColumnWidth } from 'react-icons/ai'; import { BiHide, BiShow } from 'react-icons/bi'; import { BsGrid3X3GapFill } from 'react-icons/bs'; @@ -12,28 +13,20 @@ import { RxWidth } from 'react-icons/rx'; import { TbEditCircle, TbEditCircleOff, TbHandOff, TbHandStop, TbHighlight, TbHighlightOff } from 'react-icons/tb'; import { TfiBarChart } from 'react-icons/tfi'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; -import { InkField } from '../../fields/InkField'; import { RichTextField } from '../../fields/RichTextField'; import { BoolCast, ScriptCast } from '../../fields/Types'; import { ImageField } from '../../fields/URLField'; -import { DocUtils } from '../documents/Documents'; 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'; import { SettingsManager } from '../util/SettingsManager'; -import { undoable, undoBatch } from '../util/UndoManager'; -import { Colors } from './global/globalEnums'; +import { undoBatch, undoable } from '../util/UndoManager'; import { InkingStroke } from './InkingStroke'; -import { DocumentView, OpenWhere } from './nodes/DocumentView'; import './PropertiesButtons.scss'; -import * as React from 'react'; - -enum UtilityButtonState { - Default, - OpenRight, - OpenExternally, -} +import { Colors } from './global/globalEnums'; +import { DocumentView, OpenWhere } from './nodes/DocumentView'; @observer export class PropertiesButtons extends React.Component<{}, {}> { diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx index 58d3b72e8..244cd4aa0 100644 --- a/src/client/views/PropertiesDocBacklinksSelector.tsx +++ b/src/client/views/PropertiesDocBacklinksSelector.tsx @@ -7,10 +7,10 @@ import { DocumentType } from '../documents/DocumentTypes'; import { LinkManager } from '../util/LinkManager'; import { SelectionManager } from '../util/SelectionManager'; import { SettingsManager } from '../util/SettingsManager'; +import './PropertiesDocBacklinksSelector.scss'; import { CollectionDockingView } from './collections/CollectionDockingView'; import { LinkMenu } from './linking/LinkMenu'; -import { OpenWhere, OpenWhereMod } from './nodes/DocumentView'; -import './PropertiesDocBacklinksSelector.scss'; +import { OpenWhere } from './nodes/DocumentView'; type PropertiesDocBacklinksSelectorProps = { Document: Doc; diff --git a/src/client/views/PropertiesSection.tsx b/src/client/views/PropertiesSection.tsx index 2b9bfb505..3c9fa1123 100644 --- a/src/client/views/PropertiesSection.tsx +++ b/src/client/views/PropertiesSection.tsx @@ -1,11 +1,9 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; -import './PropertiesSection.scss'; -import { Doc } from '../../fields/Doc'; -import { StrCast } from '../../fields/Types'; +import * as React from 'react'; import { SettingsManager } from '../util/SettingsManager'; +import './PropertiesSection.scss'; export interface PropertiesSectionProps { title: string; diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 48653f30a..791928b4a 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -1,5 +1,6 @@ import { action, computed, observable, ObservableSet, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast } from '../../fields/Doc'; import { ScriptField } from '../../fields/ScriptField'; import { Cast, StrCast } from '../../fields/Types'; @@ -13,7 +14,6 @@ import { CollectionTreeView } from './collections/CollectionTreeView'; import { DocumentView } from './nodes/DocumentView'; import { DefaultStyleProvider } from './StyleProvider'; import './TemplateMenu.scss'; -import * as React from 'react'; @observer class TemplateToggle extends React.Component<{ template: string; checked: boolean; toggle: (event: React.ChangeEvent, template: string) => void }> { diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx index f07e38af1..ea038250e 100644 --- a/src/client/views/UndoStack.tsx +++ b/src/client/views/UndoStack.tsx @@ -15,8 +15,8 @@ interface UndoStackProps { } @observer export class UndoStack extends React.Component { - @observable static HideInline: boolean; - @observable static Expand: boolean; + @observable static HideInline: boolean = false; + @observable static Expand: boolean = false; render() { const background = UndoManager.batchCounter.get() ? 'yellow' : SettingsManager.userVariantColor; const color = UndoManager.batchCounter.get() ? 'black' : SettingsManager.userColor; @@ -39,19 +39,25 @@ export class UndoStack extends React.Component { color, }}> {Array.from(UndoManager.undoStackNames).map((name, i) => ( -
{ +
{ const size = UndoManager.undoStackNames.length; - for (let n = 0; n < size-i; n++ ) UndoManager.Undo(); } } - > + for (let n = 0; n < size - i; n++) UndoManager.Undo(); + }}>
{StrCast(name).replace(/[^\.]*\./, '')}
))} {Array.from(UndoManager.redoStackNames) .reverse() .map((name, i) => ( -
- { for (let n = 0; n <= i; n++ ) UndoManager.Redo() }}> +
{ + for (let n = 0; n <= i; n++) UndoManager.Redo(); + }}>
{StrCast(name).replace(/[^\.]*\./, '')}
diff --git a/src/client/views/animationtimeline/Region.tsx b/src/client/views/animationtimeline/Region.tsx index 15cbbc16f..99163f6c6 100644 --- a/src/client/views/animationtimeline/Region.tsx +++ b/src/client/views/animationtimeline/Region.tsx @@ -6,11 +6,11 @@ import { List } from '../../../fields/List'; import { createSchema, defaultSpec, listSpec, makeInterface } from '../../../fields/Schema'; import { Cast, NumCast } from '../../../fields/Types'; import { Transform } from '../../util/Transform'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import '../global/globalCssVariables.module.scss'; import './Region.scss'; import './Timeline.scss'; import { TimelineMenu } from './TimelineMenu'; -import { ObservableReactComponent } from '../ObservableReactComponent'; /** * Useful static functions that you can use. Mostly for logic, but you can also add UI logic here also diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index f27a2d2fd..cc4da1694 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -4,17 +4,17 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { Utils, emptyFunction, setupMoveUpEvents } from '../../../Utils'; import { Doc, DocListCast } from '../../../fields/Doc'; import { BoolCast, NumCast, StrCast } from '../../../fields/Types'; -import { emptyFunction, setupMoveUpEvents, Utils } from '../../../Utils'; import { DocumentType } from '../../documents/DocumentTypes'; import clamp from '../../util/clamp'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import { FieldViewProps } from '../nodes/FieldView'; import { RegionHelpers } from './Region'; import './Timeline.scss'; import { TimelineOverview } from './TimelineOverview'; import { Track } from './Track'; -import { ObservableReactComponent } from '../ObservableReactComponent'; /** * Timeline class controls most of timeline functions besides individual region and track mechanism. Main functions are diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index 82ac69a3b..928739b53 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -28,7 +28,7 @@ export class TimelineOverview extends React.Component { @observable private overviewBarWidth: number = 0; @observable private playbarWidth: number = 0; @observable private activeOverviewWidth: number = 0; - @observable private _authoringReaction?: IReactionDisposer; + @observable private _authoringReaction?: IReactionDisposer = undefined; @observable private visibleTime: number = 0; @observable private currentX: number = 0; @observable private visibleStart: number = 0; diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index 00aa51cac..490a14be5 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -8,10 +8,10 @@ import { ObjectField } from '../../../fields/ObjectField'; import { listSpec } from '../../../fields/Schema'; import { Cast, NumCast } from '../../../fields/Types'; import { Transform } from '../../util/Transform'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import { Region, RegionData, RegionHelpers } from './Region'; import { Timeline } from './Timeline'; import './Track.scss'; -import { ObservableReactComponent } from '../ObservableReactComponent'; interface IProps { timeline: Timeline; @@ -29,9 +29,9 @@ interface IProps { @observer export class Track extends ObservableReactComponent { @observable private _inner = React.createRef(); - @observable private _currentBarXReaction: any; - @observable private _timelineVisibleReaction: any; - @observable private _autoKfReaction: any; + @observable private _currentBarXReaction: any = undefined; + @observable private _timelineVisibleReaction: any = undefined; + @observable private _autoKfReaction: any = undefined; @observable private _newKeyframe: boolean = false; private readonly MAX_TITLE_HEIGHT = 75; @observable private _trackHeight = 0; diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx index 2cec29669..4c0a917f5 100644 --- a/src/client/views/collections/CollectionCalendarView.tsx +++ b/src/client/views/collections/CollectionCalendarView.tsx @@ -1,18 +1,11 @@ -import * as React from 'react'; -import { CollectionSubView } from './CollectionSubView'; +import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; -import { computed, makeObservable, observable } from 'mobx'; -import { Doc, DocListCast, Opt } from '../../../fields/Doc'; +import * as React from 'react'; +import { dateRangeStrToDates, emptyFunction, returnTrue } from '../../../Utils'; +import { Doc, DocListCast } from '../../../fields/Doc'; +import { StrCast } from '../../../fields/Types'; import { CollectionStackingView } from './CollectionStackingView'; -import { CollectionViewType } from '../../documents/DocumentTypes'; -import { dateRangeStrToDates, emptyFunction, returnAll, returnEmptyDoclist, returnNone, returnOne, returnTrue } from '../../../Utils'; -import { DocumentView, DocumentViewProps } from '../nodes/DocumentView'; -import { TbRuler } from 'react-icons/tb'; -import { Transform } from '../../util/Transform'; -import { DocData } from '../../../fields/DocSymbols'; -import { Cast, NumCast, StrCast } from '../../../fields/Types'; -import { StyleProp } from '../StyleProvider'; -import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView'; +import { CollectionSubView } from './CollectionSubView'; @observer export class CollectionCalendarView extends CollectionSubView() { diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 75c178136..868df7a3b 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -1,4 +1,4 @@ -import { action, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; +import { action, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; @@ -30,7 +30,7 @@ import { ScriptingRepl } from '../ScriptingRepl'; import { UndoStack } from '../UndoStack'; import './CollectionDockingView.scss'; import { CollectionFreeFormView } from './collectionFreeForm'; -import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; +import { CollectionSubView } from './CollectionSubView'; import { TabDocView } from './TabDocView'; const _global = (window /* browser */ || global) /* node */ as any; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 443aa3f17..2a6cb081f 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -32,16 +32,13 @@ interface CollectionMenuProps { @observer export class CollectionMenu extends AntimodeMenu { @observable static Instance: CollectionMenu; - @observable SelectedCollection: DocumentView | undefined = undefined; - @observable FieldKey: string; private _docBtnRef = React.createRef(); constructor(props: any) { super(props); makeObservable(this); - this.FieldKey = ''; CollectionMenu.Instance = this; this._canFade = false; // don't let the inking menu fade away this.Pinned = Cast(Doc.UserDoc()['menuCollections-pinned'], 'boolean', true); diff --git a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx index af822d917..2aad48d4a 100644 --- a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx @@ -1,4 +1,4 @@ -import { action, observable, trace } from 'mobx'; +import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { emptyFunction, setupMoveUpEvents } from '../../../Utils'; diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 170b1f1ec..e5068645f 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -1,5 +1,6 @@ import { action, computed, IReactionDisposer, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; import { ScriptField } from '../../../fields/ScriptField'; import { NumCast, StrCast } from '../../../fields/Types'; @@ -12,7 +13,6 @@ import { computePassLayout, computeStarburstLayout } from './collectionFreeForm' import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import './CollectionPileView.scss'; import { CollectionSubView } from './CollectionSubView'; -import * as React from 'react'; @observer export class CollectionPileView extends CollectionSubView() { diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index fb8bc4da2..fa3844aa4 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -20,7 +20,7 @@ import { ScriptingGlobals } from '../../util/ScriptingGlobals'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { undoBatch, UndoManager } from '../../util/UndoManager'; -import { CollectionSubView, SubCollectionViewProps } from '../collections/CollectionSubView'; +import { CollectionSubView } from '../collections/CollectionSubView'; import { LightboxView } from '../LightboxView'; import { AudioWaveform } from '../nodes/audio/AudioWaveform'; import { DocFocusFunc, DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from '../nodes/DocumentView'; @@ -56,7 +56,7 @@ export enum TrimScope { @observer export class CollectionStackedTimeline extends CollectionSubView() { @observable static SelectingRegion: CollectionStackedTimeline | undefined = undefined; - @observable public static CurrentlyPlaying: DocumentView[]; + @observable public static CurrentlyPlaying: DocumentView[] = []; constructor(props: any) { super(props); makeObservable(this); diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index f9d575da2..69f1c332d 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -20,8 +20,8 @@ import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { EditableView } from '../EditableView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; -import './CollectionStackingView.scss'; import { ObservableReactComponent } from '../ObservableReactComponent'; +import './CollectionStackingView.scss'; // So this is how we are storing a column interface CSVFieldColumnProps { diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 2ff435ce2..570330174 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -4,11 +4,11 @@ import * as rp from 'request-promise'; import { Utils, returnFalse } from '../../../Utils'; import CursorField from '../../../fields/CursorField'; import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc'; -import { AclPrivate, DocData } from '../../../fields/DocSymbols'; +import { AclPrivate } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; -import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; +import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types'; import { WebField } from '../../../fields/URLField'; import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; @@ -41,8 +41,8 @@ export function CollectionSubView(moreProps?: X) { makeObservable(this); } - @observable _focusFilters: Opt; // childFilters that are overridden when previewing a link to an anchor which has childFilters set on it - @observable _focusRangeFilters: Opt; // childFiltersByRanges that are overridden when previewing a link to an anchor which has childFiltersByRanges set on it + @observable _focusFilters: Opt = undefined; // childFilters that are overridden when previewing a link to an anchor which has childFilters set on it + @observable _focusRangeFilters: Opt = undefined; // childFiltersByRanges that are overridden when previewing a link to an anchor which has childFiltersByRanges set on it protected createDashEventsTarget = (ele: HTMLDivElement | null) => { this.dropDisposer?.(); this.gestureDisposer?.(); diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 6033b897d..7bbdb7073 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -1,6 +1,8 @@ import { toUpper } from 'lodash'; import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { emptyFunction, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../../Utils'; import { Doc, Opt, StrListCast } from '../../../fields/Doc'; import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; @@ -8,7 +10,6 @@ import { RichTextField } from '../../../fields/RichTextField'; import { listSpec } from '../../../fields/Schema'; import { ComputedField, ScriptField } from '../../../fields/ScriptField'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; -import { emptyFunction, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../../Utils'; import { Docs } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { ScriptingGlobals } from '../../util/ScriptingGlobals'; @@ -17,20 +18,19 @@ import { ContextMenuProps } from '../ContextMenuItem'; import { EditableView } from '../EditableView'; import { DocFocusOptions, DocumentView } from '../nodes/DocumentView'; import { PresBox } from '../nodes/trails'; -import { computePivotLayout, computeTimelineLayout, ViewDefBounds } from './collectionFreeForm/CollectionFreeFormLayoutEngines'; -import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import { CollectionSubView } from './CollectionSubView'; import './CollectionTimeView.scss'; -import * as React from 'react'; +import { ViewDefBounds, computePivotLayout, computeTimelineLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines'; +import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; @observer export class CollectionTimeView extends CollectionSubView() { _changing = false; @observable _layoutEngine = computePivotLayout.name; @observable _collapsed: boolean = false; - @observable _childClickedScript: Opt; - @observable _viewDefDivClick: Opt; - @observable _focusPivotField: Opt; + @observable _childClickedScript: Opt = undefined; + @observable _viewDefDivClick: Opt = undefined; + @observable _focusPivotField: Opt = undefined; constructor(props: any) { super(props); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 0656843cb..c2f5ab2c0 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -16,6 +16,7 @@ import { ContextMenuProps } from '../ContextMenuItem'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent'; import { OpenWhere } from '../nodes/DocumentView'; import { FieldView, FieldViewProps } from '../nodes/FieldView'; +import { CollectionCalendarView } from './CollectionCalendarView'; import { CollectionCarousel3DView } from './CollectionCarousel3DView'; import { CollectionCarouselView } from './CollectionCarouselView'; import { CollectionDockingView } from './CollectionDockingView'; @@ -28,7 +29,6 @@ import { CollectionTreeView } from './CollectionTreeView'; import './CollectionView.scss'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import { CollectionGridView } from './collectionGrid/CollectionGridView'; -import { CollectionCalendarView } from './CollectionCalendarView'; import { CollectionLinearView } from './collectionLinear'; import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView'; import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx index f3071b316..4523a4f1e 100644 --- a/src/client/views/collections/KeyRestrictionRow.tsx +++ b/src/client/views/collections/KeyRestrictionRow.tsx @@ -1,6 +1,6 @@ -import * as React from "react"; -import { observable, runInAction } from "mobx"; -import { observer } from "mobx-react"; +import { observable, runInAction } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; interface IKeyRestrictionProps { contains: boolean; @@ -19,37 +19,28 @@ export default class KeyRestrictionRow extends React.Component - runInAction(() => this._key = e.target.value)} - placeholder="KEY" /> - - runInAction(() => this._value = e.target.value)} - placeholder="VALUE" /> + runInAction(() => (this._value = e.target.value))} placeholder="VALUE" />
); } -} \ No newline at end of file +} diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index a7705ea7e..72882ac17 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -93,7 +93,7 @@ export class TreeView extends ObservableReactComponent { static _openLevelScript: Opt; private _header: React.RefObject = React.createRef(); private _tref = React.createRef(); - @observable _docRef: Opt; + @observable _docRef: Opt = undefined; private _disposers: { [name: string]: IReactionDisposer } = {}; private _editTitleScript: (() => ScriptField) | undefined; private _openScript: (() => ScriptField) | undefined; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx index 99ee5ef4e..08dfb32ad 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx @@ -1,8 +1,8 @@ import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc } from '../../../../fields/Doc'; import { NumCast } from '../../../../fields/Types'; import './CollectionFreeFormView.scss'; -import * as React from 'react'; export interface CollectionFreeFormViewBackgroundGridProps { panX: () => number; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx index 2606304d0..58f6b1593 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx @@ -1,5 +1,5 @@ import { IconButton, Size, Type } from 'browndash-components'; -import { action, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; +import { IReactionDisposer, action, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { SettingsManager } from '../../../util/SettingsManager'; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx index 15e4d8360..8628ca3c3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx @@ -1,16 +1,16 @@ -import { IReactionDisposer, makeObservable, observable, runInAction } from 'mobx'; +import { makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, Field, FieldResult } from '../../../../fields/Doc'; import { InkTool } from '../../../../fields/InkField'; +import { StrCast } from '../../../../fields/Types'; import { DocumentManager } from '../../../util/DocumentManager'; import { LinkManager } from '../../../util/LinkManager'; -import { DocButtonState, DocumentLinksButton } from '../../nodes/DocumentLinksButton'; import { ObservableReactComponent } from '../../ObservableReactComponent'; -import { CollectionFreeFormInfoState, InfoState, infoState, StateEntryFunc } from './CollectionFreeFormInfoState'; +import { DocButtonState, DocumentLinksButton } from '../../nodes/DocumentLinksButton'; +import { CollectionFreeFormInfoState, InfoState, StateEntryFunc, infoState } from './CollectionFreeFormInfoState'; import { CollectionFreeFormView } from './CollectionFreeFormView'; import './CollectionFreeFormView.scss'; -import { StrCast } from '../../../../fields/Types'; export interface CollectionFreeFormInfoUIProps { Document: Doc; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index 779a0bf96..95d521f65 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -1,11 +1,11 @@ import { computed } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Id } from '../../../../fields/FieldSymbols'; import { DocumentManager } from '../../../util/DocumentManager'; import { LightboxView } from '../../LightboxView'; -import './CollectionFreeFormLinksView.scss'; import { CollectionFreeFormLinkView } from './CollectionFreeFormLinkView'; -import * as React from 'react'; +import './CollectionFreeFormLinksView.scss'; @observer export class CollectionFreeFormLinksView extends React.Component { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx index f54726a00..ec8416303 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx @@ -1,12 +1,11 @@ import { computed } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc } from '../../../../fields/Doc'; import { ScriptField } from '../../../../fields/ScriptField'; import { PresBox } from '../../nodes/trails/PresBox'; -import './CollectionFreeFormView.scss'; -import * as React from 'react'; import { CollectionFreeFormView } from './CollectionFreeFormView'; - +import './CollectionFreeFormView.scss'; export interface CollectionFreeFormPannableContentsProps { Document: Doc; viewDefDivClick?: ScriptField; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx index 45e24bbb2..fa8218bdd 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx @@ -1,6 +1,8 @@ import { computed } from 'mobx'; import { observer } from 'mobx-react'; import * as mobxUtils from 'mobx-utils'; +import * as React from 'react'; +import * as uuid from 'uuid'; import CursorField from '../../../../fields/CursorField'; import { Doc, FieldResult } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; @@ -9,8 +11,6 @@ import { listSpec } from '../../../../fields/Schema'; import { Cast } from '../../../../fields/Types'; import { CollectionViewProps } from '../CollectionView'; import './CollectionFreeFormView.scss'; -import * as React from 'react'; -import * as uuid from 'uuid'; @observer export class CollectionFreeFormRemoteCursors extends React.Component { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 645e9cff7..cc0833698 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -37,6 +37,7 @@ import { CtrlKey } from '../../GlobalKeyHandler'; import { ActiveInkWidth, InkingStroke, SetActiveInkColor, SetActiveInkWidth } from '../../InkingStroke'; import { LightboxView } from '../../LightboxView'; import { CollectionFreeFormDocumentView, CollectionFreeFormDocumentViewWrapper } from '../../nodes/CollectionFreeFormDocumentView'; +import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp'; import { DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from '../../nodes/DocumentView'; import { FieldViewProps } from '../../nodes/FieldView'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; @@ -52,7 +53,6 @@ import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannable import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors'; import './CollectionFreeFormView.scss'; import { MarqueeView } from './MarqueeView'; -import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp'; export type collectionFreeformViewProps = { NativeWidth?: () => number; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index b22fdfa19..39d828302 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -16,19 +16,18 @@ import { DocumentType } from '../../../documents/DocumentTypes'; import { DocUtils, Docs, DocumentOptions } from '../../../documents/Documents'; import { SelectionManager } from '../../../util/SelectionManager'; import { freeformScrollMode } from '../../../util/SettingsManager'; +import { SnappingManager } from '../../../util/SnappingManager'; import { Transform } from '../../../util/Transform'; import { UndoManager, undoBatch } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { PreviewCursor } from '../../PreviewCursor'; -import { DocumentView, OpenWhere } from '../../nodes/DocumentView'; +import { OpenWhere } from '../../nodes/DocumentView'; import { pasteImageBitmap } from '../../nodes/WebBoxRenderer'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { SubCollectionViewProps } from '../CollectionSubView'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './MarqueeView.scss'; -import { SnappingManager } from '../../../util/SnappingManager'; - interface MarqueeViewProps { getContainerTransform: () => Transform; getTransform: () => Transform; diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 1e19964d7..3e75257e5 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -7,7 +7,6 @@ import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents } from '../../../../Utils'; import { Docs } from '../../../documents/Documents'; import { DragManager } from '../../../util/DragManager'; -import { SnappingManager } from '../../../util/SnappingManager'; import { Transform } from '../../../util/Transform'; import { undoBatch } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; @@ -17,13 +16,12 @@ import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { CollectionSubView } from '../CollectionSubView'; import './CollectionGridView.scss'; import Grid, { Layout } from './Grid'; - @observer export class CollectionGridView extends CollectionSubView() { private _containerRef: React.RefObject = React.createRef(); private _changeListenerDisposer: Opt; // listens for changes in this.childLayoutPairs private _resetListenerDisposer: Opt; // listens for when the reset button is clicked - @observable private _rowHeight: Opt; // temporary store of row height to make change undoable + @observable private _rowHeight: Opt = undefined; // temporary store of row height to make change undoable @observable private _scroll: number = 0; // required to make sure the decorations box container updates on scroll private dropLocation: object = {}; // sets the drop location for external drops diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx index 3d1d87aa0..9145d7ef1 100644 --- a/src/client/views/collections/collectionGrid/Grid.tsx +++ b/src/client/views/collections/collectionGrid/Grid.tsx @@ -1,5 +1,5 @@ -import * as React from 'react'; import { observer } from 'mobx-react'; +import * as React from 'react'; import '../../../../../node_modules/react-grid-layout/css/styles.css'; import '../../../../../node_modules/react-resizable/css/styles.css'; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index e12bcd8b0..5bea59e7b 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -4,13 +4,13 @@ import { Button } from 'browndash-components'; import { action, computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { returnFalse } from '../../../../Utils'; import { Doc, DocListCast } from '../../../../fields/Doc'; import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; -import { returnFalse } from '../../../../Utils'; import { DragManager, dropActionType } from '../../../util/DragManager'; import { SettingsManager } from '../../../util/SettingsManager'; import { Transform } from '../../../util/Transform'; -import { undoable, undoBatch } from '../../../util/UndoManager'; +import { undoBatch, undoable } from '../../../util/UndoManager'; import { DocumentView } from '../../nodes/DocumentView'; import { CollectionSubView } from '../CollectionSubView'; import './CollectionMulticolumnView.scss'; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 7dbc18e60..3043eb0f8 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -1,9 +1,9 @@ import { action, computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { returnFalse } from '../../../../Utils'; import { Doc, DocListCast } from '../../../../fields/Doc'; import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; -import { returnFalse } from '../../../../Utils'; import { DragManager, dropActionType } from '../../../util/DragManager'; import { Transform } from '../../../util/Transform'; import { undoBatch } from '../../../util/UndoManager'; @@ -12,7 +12,6 @@ import { CollectionSubView } from '../CollectionSubView'; import './CollectionMultirowView.scss'; import HeightLabel from './MultirowHeightLabel'; import ResizeBar from './MultirowResizer'; - interface HeightSpecifier { magnitude: number; unit: string; diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx index 868b1140d..ea99bff2e 100644 --- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx @@ -1,12 +1,12 @@ -import * as React from 'react'; +import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; -import { observable, action } from 'mobx'; +import * as React from 'react'; import { Doc } from '../../../../fields/Doc'; import { NumCast, StrCast } from '../../../../fields/Types'; -import { DimUnit } from './CollectionMulticolumnView'; import { UndoManager } from '../../../util/UndoManager'; -import { StyleProviderFunc } from '../../nodes/DocumentView'; import { StyleProp } from '../../StyleProvider'; +import { StyleProviderFunc } from '../../nodes/DocumentView'; +import { DimUnit } from './CollectionMulticolumnView'; interface ResizerProps { width: number; diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx index 9985a9fba..a9579d931 100644 --- a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx +++ b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx @@ -1,27 +1,25 @@ -import * as React from "react"; -import { observer } from "mobx-react"; -import { computed } from "mobx"; -import { Doc } from "../../../../fields/Doc"; -import { NumCast, StrCast, BoolCast } from "../../../../fields/Types"; -import { EditableView } from "../../EditableView"; -import { DimUnit } from "./CollectionMulticolumnView"; +import { computed } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { Doc } from '../../../../fields/Doc'; +import { BoolCast, NumCast, StrCast } from '../../../../fields/Types'; +import { EditableView } from '../../EditableView'; +import { DimUnit } from './CollectionMulticolumnView'; interface WidthLabelProps { layout: Doc; collectionDoc: Doc; - decimals?: number; } @observer export default class WidthLabel extends React.Component { - @computed private get contents() { - const { layout, decimals } = this.props; + const { layout } = this.props; const getUnit = () => StrCast(layout.dimUnit); - const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(decimals ?? 3)); + const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(3)); return ( -
+
{ @@ -50,7 +48,6 @@ export default class WidthLabel extends React.Component { } render() { - return BoolCast(this.props.collectionDoc.showWidthLabels) ? this.contents : (null); + return BoolCast(this.props.collectionDoc.showWidthLabels) ? this.contents : null; } - -} \ No newline at end of file +} diff --git a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx index aa5439fa4..878c7ff3c 100644 --- a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx +++ b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx @@ -1,10 +1,10 @@ -import * as React from "react"; -import { observer } from "mobx-react"; -import { computed } from "mobx"; -import { Doc } from "../../../../fields/Doc"; -import { NumCast, StrCast, BoolCast } from "../../../../fields/Types"; -import { EditableView } from "../../EditableView"; -import { DimUnit } from "./CollectionMultirowView"; +import { computed } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { Doc } from '../../../../fields/Doc'; +import { BoolCast, NumCast, StrCast } from '../../../../fields/Types'; +import { EditableView } from '../../EditableView'; +import { DimUnit } from './CollectionMultirowView'; interface HeightLabelProps { layout: Doc; @@ -14,14 +14,13 @@ interface HeightLabelProps { @observer export default class HeightLabel extends React.Component { - @computed private get contents() { const { layout, decimals } = this.props; const getUnit = () => StrCast(layout.dimUnit); const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(decimals ?? 3)); return ( -
+
{ @@ -50,7 +49,6 @@ export default class HeightLabel extends React.Component { } render() { - return BoolCast(this.props.collectionDoc.showHeightLabels) ? this.contents : (null); + return BoolCast(this.props.collectionDoc.showHeightLabels) ? this.contents : null; } - -} \ No newline at end of file +} diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx index 5a9d6a82c..7dee65e58 100644 --- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx @@ -1,12 +1,12 @@ -import * as React from 'react'; +import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; -import { observable, action } from 'mobx'; +import * as React from 'react'; import { Doc } from '../../../../fields/Doc'; import { NumCast, StrCast } from '../../../../fields/Types'; -import { DimUnit } from './CollectionMultirowView'; import { UndoManager } from '../../../util/UndoManager'; import { StyleProp } from '../../StyleProvider'; import { StyleProviderFunc } from '../../nodes/DocumentView'; +import { DimUnit } from './CollectionMultirowView'; interface ResizerProps { height: number; diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index 04443b4a7..5f8b412be 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -1,7 +1,7 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable } from 'mobx'; +import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { emptyFunction, setupMoveUpEvents } from '../../../../Utils'; import { Colors } from '../../global/globalEnums'; import './CollectionSchemaView.scss'; diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 06073b52c..85e97f95f 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -1,3 +1,4 @@ +import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { action, computed, makeObservable, observable } from 'mobx'; @@ -7,18 +8,17 @@ import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils'; import { Doc } from '../../../fields/Doc'; import { Cast, DocCast, StrCast } from '../../../fields/Types'; import { WebField } from '../../../fields/URLField'; +import { DocumentType } from '../../documents/DocumentTypes'; import { DragManager } from '../../util/DragManager'; import { LinkFollower } from '../../util/LinkFollower'; import { LinkManager } from '../../util/LinkManager'; 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 { LinkInfo } from '../nodes/LinkDocPreview'; import './LinkMenuItem.scss'; -import { undoBatch } from '../../util/UndoManager'; -import { IconProp } from '@fortawesome/fontawesome-svg-core'; -import { DocumentType } from '../../documents/DocumentTypes'; interface LinkMenuItemProps { groupType: string; diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx index 5460a6daf..7e344dd7a 100644 --- a/src/client/views/linking/LinkPopup.tsx +++ b/src/client/views/linking/LinkPopup.tsx @@ -1,16 +1,16 @@ import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import { EditorView } from 'prosemirror-view'; -import { Doc } from '../../../fields/Doc'; +import * as React from 'react'; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils'; +import { Doc } from '../../../fields/Doc'; import { Transform } from '../../util/Transform'; import { undoBatch } from '../../util/UndoManager'; +import { DefaultStyleProvider } from '../StyleProvider'; import { OpenWhere } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { SearchBox } from '../search/SearchBox'; -import { DefaultStyleProvider } from '../StyleProvider'; import './LinkPopup.scss'; -import * as React from 'react'; interface LinkPopupProps { linkFrom?: () => Doc | undefined; @@ -29,7 +29,7 @@ interface LinkPopupProps { @observer export class LinkPopup extends React.Component { @observable private linkURL: string = ''; - @observable public view?: EditorView; + @observable public view?: EditorView = undefined; // TODO: should check for valid URL @undoBatch diff --git a/src/client/views/linking/LinkRelationshipSearch.tsx b/src/client/views/linking/LinkRelationshipSearch.tsx index 3e7f5be74..0902d53b2 100644 --- a/src/client/views/linking/LinkRelationshipSearch.tsx +++ b/src/client/views/linking/LinkRelationshipSearch.tsx @@ -1,6 +1,6 @@ import { observer } from 'mobx-react'; -import './LinkEditor.scss'; import * as React from 'react'; +import './LinkEditor.scss'; interface link_relationshipSearchProps { results: string[] | undefined; diff --git a/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx b/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx index 72b63cf8f..bce2b296f 100644 --- a/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx +++ b/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx @@ -3,12 +3,12 @@ import * as React from 'react'; import { Doc } from '../../../../fields/Doc'; import { InkTool } from '../../../../fields/InkField'; import { SelectionManager } from '../../../util/SelectionManager'; +import { SnappingManager } from '../../../util/SnappingManager'; import { CollectionDockingView } from '../../collections/CollectionDockingView'; -import { DocumentView, OpenWhereMod } from '../../nodes/DocumentView'; +import { OpenWhereMod } from '../../nodes/DocumentView'; import { NewLightboxView } from '../NewLightboxView'; import './ButtonMenu.scss'; import { IButtonMenu } from './utils'; -import { SnappingManager } from '../../../util/SnappingManager'; export const ButtonMenu = (props: IButtonMenu) => { return ( diff --git a/src/client/views/newlightbox/NewLightboxView.tsx b/src/client/views/newlightbox/NewLightboxView.tsx index 6980e31c1..3d159c3e3 100644 --- a/src/client/views/newlightbox/NewLightboxView.tsx +++ b/src/client/views/newlightbox/NewLightboxView.tsx @@ -2,28 +2,28 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../../Utils'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { InkTool } from '../../../fields/InkField'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; -import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils'; import { DocUtils } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { LinkManager } from '../../util/LinkManager'; import { SelectionManager } from '../../util/SelectionManager'; +import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; -import { CollectionStackedTimeline } from '../collections/CollectionStackedTimeline'; -import { TabDocView } from '../collections/TabDocView'; import { GestureOverlay } from '../GestureOverlay'; import { LightboxView } from '../LightboxView'; -import { DocumentView, OpenWhere } from '../nodes/DocumentView'; import { DefaultStyleProvider } from '../StyleProvider'; -import { IRecommendation } from './components'; +import { CollectionStackedTimeline } from '../collections/CollectionStackedTimeline'; +import { TabDocView } from '../collections/TabDocView'; +import { DocumentView, OpenWhere } from '../nodes/DocumentView'; import { ExploreView } from './ExploreView'; -import { emptyBounds, IBounds } from './ExploreView/utils'; +import { IBounds, emptyBounds } from './ExploreView/utils'; import { NewLightboxHeader } from './Header'; import './NewLightboxView.scss'; import { RecommendationList } from './RecommendationList'; -import { SnappingManager } from '../../util/SnappingManager'; +import { IRecommendation } from './components'; enum LightboxStatus { RECOMMENDATIONS = 'recommendations', @@ -50,15 +50,15 @@ export class NewLightboxView extends React.Component { return this._doc; } private static LightboxDocTemplate = () => NewLightboxView._layoutTemplate; - @observable private static _layoutTemplate: Opt; - @observable private static _layoutTemplateString: Opt; - @observable private static _doc: Opt; - @observable private static _docTarget: Opt; + @observable private static _layoutTemplate: Opt = undefined; + @observable private static _layoutTemplateString: Opt = undefined; + @observable private static _doc: Opt = undefined; + @observable private static _docTarget: Opt = undefined; @observable private static _docFilters: string[] = []; // filters - private static _savedState: Opt; + private static _savedState: Opt = undefined; private static _history: Opt<{ doc: Doc; target?: Doc }[]> = []; @observable private static _future: Opt = []; - @observable private static _docView: Opt; + @observable private static _docView: Opt = undefined; // keywords @observable private static _keywords: string[] = []; diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index 4c36d2fcb..12e8e1a69 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -44,8 +44,8 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { private _annotationLayer: React.RefObject = React.createRef(); anchorMenuClick?: () => undefined | ((anchor: Doc) => void); crop: ((region: Doc | undefined, addCrop?: boolean) => Doc | undefined) | undefined; - @observable schemaDataVizChildren: any; - @observable _marqueeing: number[] | undefined; + @observable schemaDataVizChildren: any = undefined; + @observable _marqueeing: number[] | undefined = undefined; @observable _savedAnnotations = new ObservableMap(); @computed get annotationLayer() { TraceMobx(); diff --git a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx index 3cb5125da..24023077f 100644 --- a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx +++ b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx @@ -1,15 +1,14 @@ -import * as React from 'react'; -import './SchemaCSVPopUp.scss'; +import { IconButton } from 'browndash-components'; import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { CgClose } from 'react-icons/cg'; +import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../Utils'; import { Doc } from '../../../../fields/Doc'; -import { Button, IconButton, Type } from 'browndash-components'; import { StrCast } from '../../../../fields/Types'; -import { MarqueeView } from '../../collections/collectionFreeForm/MarqueeView'; -import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../Utils'; import { DragManager } from '../../../util/DragManager'; import { DocumentView } from '../DocumentView'; -import { CgClose } from 'react-icons/cg'; +import './SchemaCSVPopUp.scss'; interface SchemaCSVPopUpProps {} @@ -56,13 +55,11 @@ export class SchemaCSVPopUp extends React.Component {
{this.heading('Schema Table as Data Visualization Doc')}
-
-
this.drag(e)}> - -
+
+
this.drag(e)}> +
+
); @@ -88,9 +85,10 @@ export class SchemaCSVPopUp extends React.Component { return embedding; }; if (this.view && sourceAnchorCreator && !Utils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) { - DragManager.StartAnchorAnnoDrag(e.target instanceof HTMLElement ? [e.target] : [], - new DragManager.AnchorAnnoDragData(this.view, sourceAnchorCreator, targetCreator), downX, downY, { - dragComplete: e => {this.setVisible(false);}, + DragManager.StartAnchorAnnoDrag(e.target instanceof HTMLElement ? [e.target] : [], new DragManager.AnchorAnnoDragData(this.view, sourceAnchorCreator, targetCreator), downX, downY, { + dragComplete: e => { + this.setVisible(false); + }, }); return true; } @@ -108,4 +106,4 @@ export class SchemaCSVPopUp extends React.Component {
); } -} \ No newline at end of file +} diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx index 227c993c7..9e9a43b34 100644 --- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx +++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { ColorPicker, EditableText, IconButton, Size, Type } from 'browndash-components'; import * as d3 from 'd3'; -import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; +import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { FaFillDrip } from 'react-icons/fa'; @@ -11,10 +11,10 @@ import { listSpec } from '../../../../../fields/Schema'; import { Cast, DocCast, StrCast } from '../../../../../fields/Types'; import { Docs } from '../../../../documents/Documents'; import { undoable } from '../../../../util/UndoManager'; +import { ObservableReactComponent } from '../../../ObservableReactComponent'; import { PinProps, PresBox } from '../../trails'; import { scaleCreatorNumerical, yAxisCreator } from '../utils/D3Utils'; import './Chart.scss'; -import { ObservableReactComponent } from '../../../ObservableReactComponent'; export interface HistogramProps { Document: Doc; @@ -461,7 +461,7 @@ export class Histogram extends ObservableReactComponent { if (this._histogramData.length > 0 || !this.parentViz) { return this._props.axes.length >= 1 ? ( -
+
{ private _lineChartSvg: d3.Selection | undefined; @observable _currSelected: SelectedDataPoint | undefined = undefined; // TODO: nda - some sort of mapping that keeps track of the annotated points so we can easily remove when annotations list updates - constructor(props:any) { + constructor(props: any) { super(props); makeObservable(this); } - @computed get _tableDataIds() { return !this.parentViz ? this._props.records.map((rec, i) => i) : NumListCast(this.parentViz.dataViz_selectedRows); } @@ -359,7 +358,7 @@ export class LineChart extends ObservableReactComponent { const selectedPt = this._currSelected ? `{ ${this._props.axes[0]}: ${this._currSelected.x} ${this._props.axes[1]}: ${this._currSelected.y} }` : 'none'; if (this._lineChartData.length > 0 || !this.parentViz || this.parentViz.length == 0) { return this._props.axes.length >= 2 && /\d/.test(this._props.records[0][this._props.axes[0]]) && /\d/.test(this._props.records[0][this._props.axes[1]]) ? ( -
+
{ />
- {selectedPt != 'none' ? -
+ {selectedPt != 'none' ? ( +
{`Selected: ${selectedPt}`} - -
- : null} + +
+ ) : null}
) : ( {'first use table view to select two numerical axes to plot'} diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx index e644870da..e67556cd0 100644 --- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx @@ -1,7 +1,7 @@ import { Checkbox } from '@mui/material'; import { ColorPicker, EditableText, Size, Type } from 'browndash-components'; import * as d3 from 'd3'; -import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; +import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { FaFillDrip } from 'react-icons/fa'; @@ -11,9 +11,9 @@ import { listSpec } from '../../../../../fields/Schema'; import { Cast, DocCast, StrCast } from '../../../../../fields/Types'; import { Docs } from '../../../../documents/Documents'; import { undoable } from '../../../../util/UndoManager'; +import { ObservableReactComponent } from '../../../ObservableReactComponent'; import { PinProps, PresBox } from '../../trails'; import './Chart.scss'; -import { ObservableReactComponent } from '../../../ObservableReactComponent'; export interface PieChartProps { Document: Doc; @@ -356,7 +356,7 @@ export class PieChart extends ObservableReactComponent { if (this._pieChartData.length > 0 || !this.parentViz) { return this._props.axes.length >= 1 ? ( -
+
{ return (this.viewScale * this._tableHeight) / this._tableDataIds.length; } @computed get startID() { - return this.rowHeight ? Math.max(Math.floor(this._scrollTop / this.rowHeight)-1, 0) : 0; + return this.rowHeight ? Math.max(Math.floor(this._scrollTop / this.rowHeight) - 1, 0) : 0; } @computed get endID() { console.log('start = ' + this.startID + ' container = ' + this._tableContainerHeight + ' scale = ' + this.viewScale + ' row = ' + this.rowHeight); @@ -169,7 +169,7 @@ export class TableBox extends ObservableReactComponent { return (
{ if (this._props.layoutDoc && e.key === 'a' && (e.ctrlKey || e.metaKey)) { @@ -226,7 +226,7 @@ export class TableBox extends ObservableReactComponent { {this._tableDataIds - .filter((rowId, i) => this.startID-2 <= i && i <= this.endID+2) + .filter((rowId, i) => this.startID - 2 <= i && i <= this.endID + 2) ?.map(rowId => ( ; export interface JsxBindings { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index cc7fca8d2..f8f4b94a2 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,10 +1,11 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { Dropdown, DropdownType, Type } from 'browndash-components'; +import { Howl } from 'howler'; import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; -import { Bounce, Fade, Flip, JackInTheBox, Roll, Rotate, Zoom } from 'react-awesome-reveal'; import * as React from 'react'; +import { Bounce, Fade, Flip, JackInTheBox, Roll, Rotate, Zoom } from 'react-awesome-reveal'; import { Utils, emptyFunction, isTargetChildOf as isParentOf, lightOrDark, returnEmptyString, returnFalse, returnTrue, returnVal, simulateMouseClick } from '../../../Utils'; import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc'; import { AclPrivate, Animation, AudioPlay, DocViews } from '../../../fields/DocSymbols'; @@ -53,7 +54,6 @@ import { LinkAnchorBox } from './LinkAnchorBox'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; import { PresEffect, PresEffectDirection } from './trails'; import { PinProps, PresBox } from './trails/PresBox'; -import { Howl } from 'howler'; interface Window { MediaRecorder: MediaRecorder; @@ -138,7 +138,6 @@ export interface DocComponentView { dragStarting?: (snapToDraggedDoc: boolean, showGroupDragTarget: boolean, visited: Set) => void; incrementalRendering?: () => void; infoUI?: () => JSX.Element | null; - getCenter?: (xf: Transform) => { X: number; Y: number }; screenBounds?: () => Opt<{ left: number; top: number; right: number; bottom: number; center?: { X: number; Y: number } }>; ptToScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number }; ptFromScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number }; @@ -1516,7 +1515,7 @@ export class DocumentView extends ObservableReactComponent { const docuBox = this.docView.ContentDiv.getElementsByClassName('linkAnchorBox-cont'); if (docuBox.length) return { ...docuBox[0].getBoundingClientRect(), center: undefined }; } - return { left, top, right, bottom, center: this.ComponentView?.getCenter?.(xf) }; + return { left, top, right, bottom }; }; public iconify(finished?: () => void, animateTime?: number) { diff --git a/src/client/views/nodes/FaceRectangle.tsx b/src/client/views/nodes/FaceRectangle.tsx index 8d03bf57a..46bc6eb03 100644 --- a/src/client/views/nodes/FaceRectangle.tsx +++ b/src/client/views/nodes/FaceRectangle.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; -import { observer } from 'mobx-react'; import { observable, runInAction } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; import { RectangleTemplate } from './FaceRectangles'; @observer diff --git a/src/client/views/nodes/FaceRectangles.tsx b/src/client/views/nodes/FaceRectangles.tsx index 26e720c0d..ade4225d9 100644 --- a/src/client/views/nodes/FaceRectangles.tsx +++ b/src/client/views/nodes/FaceRectangles.tsx @@ -1,8 +1,8 @@ +import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; -import { Cast, NumCast } from '../../../fields/Types'; -import { observer } from 'mobx-react'; import { Id } from '../../../fields/FieldSymbols'; +import { Cast, NumCast } from '../../../fields/Types'; import FaceRectangle from './FaceRectangle'; interface FaceRectanglesProps { diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index f4c5167a5..008f10f26 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; import { computed } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { DateField } from '../../../fields/DateField'; import { Doc, Field, FieldResult, Opt } from '../../../fields/Doc'; import { List } from '../../../fields/List'; diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index fd8d8ef56..7bc9d3f85 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -1,7 +1,6 @@ import { Tooltip } from '@mui/material'; import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; -import { ObservableGroupMap } from 'mobx-utils'; import * as React from 'react'; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../Utils'; import { Doc, Field } from '../../../fields/Doc'; @@ -11,13 +10,13 @@ import { Transform } from '../../util/Transform'; import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { EditableView } from '../EditableView'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import { DefaultStyleProvider } from '../StyleProvider'; import { OpenWhere } from './DocumentView'; import { FieldViewProps } from './FieldView'; import { KeyValueBox } from './KeyValueBox'; import './KeyValueBox.scss'; import './KeyValuePair.scss'; -import { ObservableReactComponent } from '../ObservableReactComponent'; // Represents one row in a key value plane @@ -35,12 +34,11 @@ export class KeyValuePair extends ObservableReactComponent { @observable private isPointerOver = false; @observable public isChecked = false; private checkbox = React.createRef(); - constructor(props:any) { + constructor(props: any) { super(props); makeObservable(this); } - @action handleCheck = (e: React.ChangeEvent) => { this.isChecked = e.currentTarget.checked; diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx index 32300d60a..8ad0b7dde 100644 --- a/src/client/views/nodes/LinkDescriptionPopup.tsx +++ b/src/client/views/nodes/LinkDescriptionPopup.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc } from '../../../fields/Doc'; import { LinkManager } from '../../util/LinkManager'; import './LinkDescriptionPopup.scss'; diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index d0a9f10b4..ea23ecbea 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -2,13 +2,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import wiki from 'wikijs'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils'; import { Doc, Opt } from '../../../fields/Doc'; import { Cast, DocCast, NumCast, PromiseValue, StrCast } from '../../../fields/Types'; -import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils'; import { DocServer } from '../../DocServer'; -import { Docs } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; +import { Docs } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager } from '../../util/DragManager'; import { LinkFollower } from '../../util/LinkFollower'; @@ -16,10 +17,9 @@ import { LinkManager } from '../../util/LinkManager'; import { SearchUtil } from '../../util/SearchUtil'; import { SettingsManager } from '../../util/SettingsManager'; import { Transform } from '../../util/Transform'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView'; import './LinkDocPreview.scss'; -import * as React from 'react'; -import { ObservableReactComponent } from '../ObservableReactComponent'; export class LinkInfo { private static _instance: Opt; diff --git a/src/client/views/nodes/LoadingBox.tsx b/src/client/views/nodes/LoadingBox.tsx index 27d73a585..adccc9db6 100644 --- a/src/client/views/nodes/LoadingBox.tsx +++ b/src/client/views/nodes/LoadingBox.tsx @@ -1,4 +1,4 @@ -import { action, observable, runInAction } from 'mobx'; +import { observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import ReactLoading from 'react-loading'; diff --git a/src/client/views/nodes/MapBox/AnimationUtility.ts b/src/client/views/nodes/MapBox/AnimationUtility.ts index 42dfa59b7..35153f439 100644 --- a/src/client/views/nodes/MapBox/AnimationUtility.ts +++ b/src/client/views/nodes/MapBox/AnimationUtility.ts @@ -1,13 +1,10 @@ -import mapboxgl from 'mapbox-gl'; -import { MercatorCoordinate } from 'mapbox-gl'; -import { MapRef } from 'react-map-gl'; -import * as React from 'react'; -import * as d3 from 'd3'; import * as turf from '@turf/turf'; import { Position } from '@turf/turf'; -import { Feature, FeatureCollection, GeoJsonProperties, Geometry } from 'geojson'; -import { observer } from 'mobx-react'; -import { action, computed, observable, runInAction, makeObservable } from 'mobx'; +import * as d3 from 'd3'; +import { Feature, GeoJsonProperties, Geometry } from 'geojson'; +import mapboxgl, { MercatorCoordinate } from 'mapbox-gl'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; +import { MapRef } from 'react-map-gl'; export enum AnimationStatus { START = 'start', diff --git a/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx b/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx index f9607becf..7e99795b5 100644 --- a/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx +++ b/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx @@ -1,15 +1,15 @@ -import * as React from 'react'; -import { observer } from 'mobx-react'; -import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; +import { IconLookup, faAdd, faCalendarDays, faRoute } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { IconButton } from 'browndash-components'; import { IReactionDisposer, ObservableMap, reaction } from 'mobx'; -import { Doc, Opt } from '../../../../fields/Doc'; +import { observer } from 'mobx-react'; +import * as React from 'react'; import { returnFalse, unimplementedFunction } from '../../../../Utils'; +import { Doc, Opt } from '../../../../fields/Doc'; import { NumCast, StrCast } from '../../../../fields/Types'; import { SelectionManager } from '../../../util/SelectionManager'; -import { IconButton } from 'browndash-components'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { SettingsManager } from '../../../util/SettingsManager'; -import { IconLookup, faAdd, faCalendarDays, faRoute } from '@fortawesome/free-solid-svg-icons'; +import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; @observer export class DirectionsAnchorMenu extends AntimodeMenu { diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx index 1b1b74e7c..08bea5d9d 100644 --- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx +++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx @@ -1,26 +1,23 @@ +import { IconLookup, faAdd, faArrowDown, faArrowLeft, faArrowsRotate, faBicycle, faCalendarDays, faCar, faDiamondTurnRight, faEdit, faPersonWalking, faRoute } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import * as React from 'react'; +import { Autocomplete, Checkbox, FormControlLabel, TextField } from '@mui/material'; +import { IconButton } from 'browndash-components'; +import { Position } from 'geojson'; import { IReactionDisposer, ObservableMap, action, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; -import { Doc, NumListCast, Opt } from '../../../../fields/Doc'; +import * as React from 'react'; +import { CirclePicker, ColorResult } from 'react-color'; import { returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../../Utils'; +import { Doc, Opt } from '../../../../fields/Doc'; +import { NumCast, StrCast } from '../../../../fields/Types'; +import { CalendarManager } from '../../../util/CalendarManager'; import { SelectionManager } from '../../../util/SelectionManager'; -import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; -// import { GPTPopup, GPTPopupMode } from './../../GPTPopup/GPTPopup'; -import { Button, IconButton } from 'browndash-components'; import { SettingsManager } from '../../../util/SettingsManager'; +import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; import './MapAnchorMenu.scss'; -import { NumCast, StrCast } from '../../../../fields/Types'; -import { IconLookup, faDiamondTurnRight, faCalendarDays, faEdit, faAdd, faRoute, faArrowLeft, faLocationDot, faArrowDown, faCar, faBicycle, faPersonWalking, faUpload, faArrowsRotate } from '@fortawesome/free-solid-svg-icons'; -import { DirectionsAnchorMenu } from './DirectionsAnchorMenu'; -import { Autocomplete, Checkbox, FormControlLabel, TextField } from '@mui/material'; import { MapboxApiUtility, TransportationType } from './MapboxApiUtility'; -import { MapBox } from './MapBox'; -import { List } from '../../../../fields/List'; import { MarkerIcons } from './MarkerIcons'; -import { CirclePicker, ColorResult } from 'react-color'; -import { Position } from 'geojson'; -import { CalendarManager } from '../../../util/CalendarManager'; +// import { GPTPopup, GPTPopupMode } from './../../GPTPopup/GPTPopup'; type MapAnchorMenuType = 'standard' | 'routeCreation' | 'calendar' | 'customize' | 'route'; @@ -52,7 +49,6 @@ export class MapAnchorMenu extends AntimodeMenu { public UpdateMarkerColor: (color: string) => void = unimplementedFunction; public UpdateMarkerIcon: (iconKey: string) => void = unimplementedFunction; - public Hide: () => void = unimplementedFunction; public OpenAnimationPanel: (routeDoc: Doc | undefined) => void = unimplementedFunction; @@ -74,22 +70,21 @@ export class MapAnchorMenu extends AntimodeMenu { private title: string | undefined = undefined; public setPinDoc(pinDoc: Doc | undefined) { - if (pinDoc){ + if (pinDoc) { this.pinDoc = pinDoc; this.title = StrCast(pinDoc.title ? pinDoc.title : `${NumCast(pinDoc.longitude)}, ${NumCast(pinDoc.latitude)}`); } - } public setRouteDoc(routeDoc: Doc | undefined) { - if (routeDoc){ + if (routeDoc) { this.routeDoc = routeDoc; this.title = StrCast(routeDoc.title ?? 'Map route'); } } @action - public Reset(){ + public Reset() { this.destinationSelected = false; this.currentRouteInfoMap = undefined; this.destinationFeatures = []; @@ -296,34 +291,23 @@ export class MapAnchorMenu extends AntimodeMenu { return undefined; }; - getDirectionsButton: JSX.Element = ( - } - color={SettingsManager.userColor} /> - ) + getDirectionsButton: JSX.Element = (} color={SettingsManager.userColor} />); getAddToCalendarButton = (docType: string): JSX.Element => { return ( - { - CalendarManager.Instance.open(undefined, docType === 'pin' ? this.pinDoc : this.routeDoc) - }} - icon={} - color={SettingsManager.userColor} + { + CalendarManager.Instance.open(undefined, docType === 'pin' ? this.pinDoc : this.routeDoc); + }} + icon={} + color={SettingsManager.userColor} /> - ) - - } + ); + }; addToCalendarButton: JSX.Element = ( - CalendarManager.Instance.open(undefined, this.pinDoc)} - icon={} - color={SettingsManager.userColor} /> - ) + CalendarManager.Instance.open(undefined, this.pinDoc)} icon={} color={SettingsManager.userColor} /> + ); getLinkNoteToDocButton = (docType: string): JSX.Element => { return ( @@ -335,8 +319,8 @@ export class MapAnchorMenu extends AntimodeMenu { color={SettingsManager.userColor} />
- ) - } + ); + }; linkNoteToPinOrRoutenButton: JSX.Element = (
@@ -347,16 +331,9 @@ export class MapAnchorMenu extends AntimodeMenu { color={SettingsManager.userColor} />
- ) - - customizePinButton: JSX.Element = ( - } - color={SettingsManager.userColor} - /> - ) + ); + + customizePinButton: JSX.Element = (} color={SettingsManager.userColor} />); centerOnPinButton: JSX.Element = ( { icon={} color={SettingsManager.userColor} /> - ) + ); backButton: JSX.Element = ( { icon={} color={SettingsManager.userColor} /> - ) + ); addRouteButton: JSX.Element = ( { icon={} color={SettingsManager.userColor} /> - ) + ); getDeleteButton = (type: string) => { return ( @@ -393,17 +370,10 @@ export class MapAnchorMenu extends AntimodeMenu { icon={} color={SettingsManager.userColor} /> - ) - } + ); + }; - animateRouteButton: JSX.Element = ( - this.OpenAnimationPanel(this.routeDoc)} - icon={} - color={SettingsManager.userColor} - /> - ) + animateRouteButton: JSX.Element = ( this.OpenAnimationPanel(this.routeDoc)} icon={} color={SettingsManager.userColor} />); revertToOriginalMarkerButton = ( { icon={} color={SettingsManager.userColor} /> - ) + ); render() { const buttons = ( diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 7db139d74..ffd52fb0e 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1,8 +1,17 @@ +import { IconLookup, faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Checkbox, FormControlLabel, TextField } from '@mui/material'; +import * as turf from '@turf/turf'; import { IconButton, Size, Type } from 'browndash-components'; +import * as d3 from 'd3'; +import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString, Position } from 'geojson'; +import mapboxgl, { LngLat, LngLatBoundsLike, MapLayerMouseEvent } from 'mapbox-gl'; import { IReactionDisposer, ObservableMap, action, autorun, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { CirclePicker, ColorResult } from 'react-color'; +import { Layer, MapProvider, MapRef, Map as MapboxMap, Marker, Source, ViewState, ViewStateChangeEvent } from 'react-map-gl'; +import { MarkerEvent } from 'react-map-gl/dist/esm/types'; import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../Utils'; import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc'; import { DocCss, Highlight } from '../../../../fields/DocSymbols'; @@ -22,22 +31,13 @@ import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; import { FormattedTextBox } from '../formattedText/FormattedTextBox'; import { PinProps, PresBox } from '../trails'; -import { MapAnchorMenu } from './MapAnchorMenu'; -import { ControlPosition, Layer, MapProvider, MapRef, Map as MapboxMap, Marker, MarkerProps, Source, ViewState, ViewStateChangeEvent } from 'react-map-gl'; -import './MapBox.scss'; -// import { GeocoderControl } from './GeocoderControl'; -import { IconLookup, faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons'; -import { Checkbox, FormControlLabel, TextField } from '@mui/material'; -import * as turf from '@turf/turf'; -import * as d3 from 'd3'; -import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString, Position } from 'geojson'; -import mapboxgl, { LngLat, LngLatBoundsLike, MapLayerMouseEvent } from 'mapbox-gl'; -import { CirclePicker, ColorResult } from 'react-color'; -import { MarkerEvent } from 'react-map-gl/dist/esm/types'; import { fastSpeedIcon, mediumSpeedIcon, slowSpeedIcon } from './AnimationSpeedIcons'; import { AnimationSpeed, AnimationStatus, AnimationUtility } from './AnimationUtility'; +import { MapAnchorMenu } from './MapAnchorMenu'; +import './MapBox.scss'; import { MapboxApiUtility, TransportationType } from './MapboxApiUtility'; import { MarkerIcons } from './MarkerIcons'; +// import { GeocoderControl } from './GeocoderControl'; // amongus /** @@ -480,7 +480,7 @@ export class MapBox extends ViewBoxAnnotatableComponent { @@ -650,7 +650,7 @@ export class MapBox extends ViewBoxAnnotatableComponent { - console.log('deleting') + console.log('deleting'); if (this.selectedPinOrRoute) { // Removes filter Doc.setDocFilter(this.Document, 'latitude', this.selectedPinOrRoute.latitude, 'remove'); @@ -677,15 +677,12 @@ export class MapBox extends ViewBoxAnnotatableComponent { if (this.selectedPinOrRoute) { @@ -882,8 +879,8 @@ export class MapBox extends ViewBoxAnnotatableComponent { return ( <> @@ -1423,20 +1417,14 @@ export class MapBox extends ViewBoxAnnotatableComponent
|
- } - /> + } />
|
|
-
+
Select Line Color:
- this.setAnimationLineColor(color)} /> + this.setAnimationLineColor(color)} />
-
@@ -1478,7 +1466,7 @@ export class MapBox extends ViewBoxAnnotatableComponent) => { const bearing = parseInt(e.target.value); if (!isNaN(bearing) && this._mapRef.current) { - console.log('bearing change') + console.log('bearing change'); const fixedBearing = Math.max(0, Math.min(360, bearing)); this._mapRef.current.setBearing(fixedBearing); this.dataDoc.map_bearing = fixedBearing; @@ -1489,7 +1477,7 @@ export class MapBox extends ViewBoxAnnotatableComponent) => { const pitch = parseInt(e.target.value); if (!isNaN(pitch) && this._mapRef.current) { - console.log('pitch change') + console.log('pitch change'); const fixedPitch = Math.max(0, Math.min(85, pitch)); this._mapRef.current.setPitch(fixedPitch); this.dataDoc.map_pitch = fixedPitch; @@ -1648,7 +1636,7 @@ export class MapBox extends ViewBoxAnnotatableComponent = React.createRef(); -// @observable private _overlayAnnoInfo: Opt; +// @observable private _overlayAnnoInfo: Opt = undefined; // showInfo = action((anno: Opt) => (this._overlayAnnoInfo = anno)); // public static LayoutString(fieldKey: string) { // return FieldView.LayoutString(MapBox2, fieldKey); diff --git a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx index 6a14427c0..70037f29c 100644 --- a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx +++ b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx @@ -1,33 +1,31 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import BingMapsReact from 'bingmaps-react'; import { Button, EditableText, IconButton, Type } from 'browndash-components'; -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; +import { IReactionDisposer, ObservableMap, action, computed, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { MapProvider, Map as MapboxMap } from 'react-map-gl'; +import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, setupMoveUpEvents } from '../../../../Utils'; import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc'; import { DocCss, Highlight } from '../../../../fields/DocSymbols'; -import { Id } from '../../../../fields/FieldSymbols'; import { DocCast, NumCast, StrCast } from '../../../../fields/Types'; -import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils'; -import { Docs, DocUtils } from '../../../documents/Documents'; import { DocumentType } from '../../../documents/DocumentTypes'; +import { DocUtils, Docs } from '../../../documents/Documents'; import { DocumentManager } from '../../../util/DocumentManager'; import { DragManager } from '../../../util/DragManager'; import { LinkManager } from '../../../util/LinkManager'; import { SnappingManager } from '../../../util/SnappingManager'; import { Transform } from '../../../util/Transform'; -import { undoable, UndoManager } from '../../../util/UndoManager'; -import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; +import { UndoManager, undoable } from '../../../util/UndoManager'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent'; -import { Colors } from '../../global/globalEnums'; import { SidebarAnnos } from '../../SidebarAnnos'; +import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; +import { Colors } from '../../global/globalEnums'; import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; +import { MapAnchorMenu } from '../MapBox/MapAnchorMenu'; import { FormattedTextBox } from '../formattedText/FormattedTextBox'; import { PinProps, PresBox } from '../trails'; import './MapBox.scss'; -import { MapAnchorMenu } from '../MapBox/MapAnchorMenu'; -import { MapProvider, Map as MapboxMap } from 'react-map-gl'; // amongus /** @@ -351,7 +349,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 733febd2d..7f1d6b049 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -48,7 +48,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent(); @observable private _searching: boolean = false; - @observable private _pdf: Opt; + @observable private _pdf: Opt = undefined; @observable private _pageControls = false; @computed get pdfUrl() { diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx index e75b1ab6f..135db64e0 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx @@ -6,8 +6,9 @@ import QuestionMarkIcon from '@mui/icons-material/QuestionMark'; import ReplayIcon from '@mui/icons-material/Replay'; import { Box, Button, Checkbox, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, FormControl, FormControlLabel, FormGroup, IconButton, LinearProgress, Stack } from '@mui/material'; import Typography from '@mui/material/Typography'; -import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; +import { IReactionDisposer, action, computed, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { NumListCast } from '../../../../fields/Doc'; import { List } from '../../../../fields/List'; import { BoolCast, NumCast, StrCast } from '../../../../fields/Types'; @@ -19,7 +20,6 @@ import questions from './PhysicsSimulationQuestions.json'; import tutorials from './PhysicsSimulationTutorial.json'; import Wall from './PhysicsSimulationWall'; import Weight from './PhysicsSimulationWeight'; -import * as React from 'react'; interface IWallProps { length: number; diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx index f5077a07e..3b232ddd0 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx @@ -1,7 +1,7 @@ import { computed, IReactionDisposer, makeObservable, reaction } from 'mobx'; import { observer } from 'mobx-react'; -import './PhysicsSimulationBox.scss'; import * as React from 'react'; +import './PhysicsSimulationBox.scss'; interface IWallProps { length: number; diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx index 061a46f03..3b2fc033d 100644 --- a/src/client/views/nodes/RadialMenu.tsx +++ b/src/client/views/nodes/RadialMenu.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import './RadialMenu.scss'; import { RadialMenuItem, RadialMenuProps } from './RadialMenuItem'; diff --git a/src/client/views/nodes/RadialMenuItem.tsx b/src/client/views/nodes/RadialMenuItem.tsx index c931202f1..10a90befd 100644 --- a/src/client/views/nodes/RadialMenuItem.tsx +++ b/src/client/views/nodes/RadialMenuItem.tsx @@ -1,7 +1,7 @@ -import * as React from 'react'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { UndoManager } from '../../util/UndoManager'; export interface RadialMenuProps { diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index f01642236..658cfb1ca 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -8,15 +8,15 @@ import { List } from '../../../../fields/List'; import { BoolCast, DocCast } from '../../../../fields/Types'; import { VideoField } from '../../../../fields/URLField'; import { Upload } from '../../../../server/SharedMediaTypes'; -import { Docs } from '../../../documents/Documents'; import { DocumentType } from '../../../documents/DocumentTypes'; +import { Docs } from '../../../documents/Documents'; import { DocumentManager } from '../../../util/DocumentManager'; import { DragManager } from '../../../util/DragManager'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { Presentation } from '../../../util/TrackMovements'; import { undoBatch } from '../../../util/UndoManager'; -import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; import { ViewBoxBaseComponent } from '../../DocComponent'; +import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; import { media_state } from '../AudioBox'; import { FieldView, FieldViewProps } from '../FieldView'; import { VideoBox } from '../VideoBox'; diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index d5d31b407..79ed69cdd 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,5 +1,5 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import * as React from 'react'; // import { Canvas } from '@react-three/fiber'; import { computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index 7e7eaee45..8e506ec64 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -2,25 +2,23 @@ let ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { returnAlways, returnEmptyString } from '../../../Utils'; import { Doc } from '../../../fields/Doc'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { returnAlways, returnEmptyString, returnTrue } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; -import { InteractionUtils } from '../../util/InteractionUtils'; +import { ScriptManager } from '../../util/ScriptManager'; import { CompileScript, ScriptParam } from '../../util/Scripting'; import { ScriptingGlobals } from '../../util/ScriptingGlobals'; -import { ScriptManager } from '../../util/ScriptManager'; import { ContextMenu } from '../ContextMenu'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent'; import { EditableView } from '../EditableView'; -import { FieldView, FieldViewProps } from '../nodes/FieldView'; import { OverlayView } from '../OverlayView'; +import { FieldView, FieldViewProps } from '../nodes/FieldView'; import { DocumentIconContainer } from './DocumentIcon'; -import { DocFocusOptions, DocumentView } from './DocumentView'; import './ScriptingBox.scss'; const _global = (window /* browser */ || global) /* node */ as any; diff --git a/src/client/views/nodes/TaskCompletedBox.tsx b/src/client/views/nodes/TaskCompletedBox.tsx index 9aab8c5a9..c9e15d314 100644 --- a/src/client/views/nodes/TaskCompletedBox.tsx +++ b/src/client/views/nodes/TaskCompletedBox.tsx @@ -1,15 +1,15 @@ -import * as React from 'react'; +import { Fade } from '@mui/material'; +import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import './TaskCompletedBox.scss'; -import { observable, action } from 'mobx'; -import { Fade } from '@mui/material'; @observer export class TaskCompletionBox extends React.Component<{}> { @observable public static taskCompleted: boolean = false; @observable public static popupX: number = 500; @observable public static popupY: number = 150; - @observable public static textDisplayed: string; + @observable public static textDisplayed: string = ''; @action public static toggleTaskCompleted = () => { diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index f205dbd56..8e9cfe3d7 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -74,8 +74,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent(); @observable _screenCapture = false; @observable _clicking = false; // used for transition between showing/hiding timeline @@ -86,7 +86,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent(){ +export class CalendarBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string = 'calendar') { return FieldView.LayoutString(CalendarBox, fieldKey); } - componentDidMount(): void { - - } + componentDidMount(): void {} - componentWillUnmount(): void { - - } + componentWillUnmount(): void {} - _calendarRef = React.createRef() + _calendarRef = React.createRef(); - get dateRangeStr (){ + get dateRangeStr() { return StrCast(this.Document.date_range); } - // Choose a calendar view based on the date range - get calendarViewType (): CalendarView { + // Choose a calendar view based on the date range + get calendarViewType(): CalendarView { const [fromDate, toDate] = dateRangeStrToDates(this.dateRangeStr); if (fromDate.getFullYear() !== toDate.getFullYear() || fromDate.getMonth() !== toDate.getMonth()) return 'multi-month'; @@ -43,92 +38,83 @@ export class CalendarBox extends ViewBoxBaseComponent(){ return 'week'; } - get calendarStartDate () { - return this.dateRangeStr.split("|")[0]; + get calendarStartDate() { + return this.dateRangeStr.split('|')[0]; } - get calendarToDate () { - return this.dateRangeStr.split("|")[1]; + get calendarToDate() { + return this.dateRangeStr.split('|')[1]; } - get childDocs (): Doc[] { + get childDocs(): Doc[] { return this.childDocs; // get all sub docs for a calendar } - docBackgroundColor (type: string): string { + docBackgroundColor(type: string): string { // TODO: Return a different color based on the event type return 'blue'; } - get calendarEvents (): EventSourceInput | undefined { + get calendarEvents(): EventSourceInput | undefined { if (this.childDocs.length === 0) return undefined; return this.childDocs.map((doc, idx) => { const docTitle = StrCast(doc.title); const docDateRange = StrCast(doc.date_range); const [startDate, endDate] = dateRangeStrToDates(docDateRange); const docType = doc.type; - const docDescription = doc.description ? StrCast(doc.description): ""; + const docDescription = doc.description ? StrCast(doc.description) : ''; return { title: docTitle, start: startDate, end: endDate, allDay: false, - classNames:[StrCast(docType)], // will determine the style + classNames: [StrCast(docType)], // will determine the style editable: false, // subject to change in the future backgroundColor: this.docBackgroundColor(StrCast(doc.type)), color: 'white', extendedProps: { - description: docDescription + description: docDescription, }, - - } - - }) + }; + }); } handleEventClick = (arg: EventClickArg) => { // TODO: open popover with event description, option to open CalendarManager and change event date, delete event, etc. - } + }; calendarEl: HTMLElement = document.getElementById('calendar-box-v1')!; // https://fullcalendar.io get calendar() { - return new Calendar(this.calendarEl, - { - plugins: [this.calendarViewType === 'multi-month' ? multiMonthPlugin : dayGridPlugin], - headerToolbar: { - left: 'prev,next today', - center: 'title', - right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' - }, - initialDate: this.calendarStartDate, - navLinks: true, - editable: false, - displayEventTime: false, - displayEventEnd: false, - events: this.calendarEvents, - eventClick: this.handleEventClick - } - ) - + return new Calendar(this.calendarEl, { + plugins: [this.calendarViewType === 'multi-month' ? multiMonthPlugin : dayGridPlugin], + headerToolbar: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek', + }, + initialDate: this.calendarStartDate, + navLinks: true, + editable: false, + displayEventTime: false, + displayEventEnd: false, + events: this.calendarEvents, + eventClick: this.handleEventClick, + }); } - - constructor(props: any){ + constructor(props: any) { super(props); makeObservable(this); } - render(){ + render() { return ( -
-
- -
-
+
+
+
); - } -} \ No newline at end of file +} diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index 6332b200d..1002ee403 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -1,17 +1,17 @@ import { action, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { NodeSelection } from 'prosemirror-state'; +import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; import { Doc } from '../../../../fields/Doc'; import { Height, Width } from '../../../../fields/DocSymbols'; import { NumCast, StrCast } from '../../../../fields/Types'; -import { emptyFunction, returnFalse, returnTrue, Utils } from '../../../../Utils'; +import { emptyFunction, returnFalse, Utils } from '../../../../Utils'; import { DocServer } from '../../../DocServer'; import { Docs, DocUtils } from '../../../documents/Documents'; import { Transform } from '../../../util/Transform'; import { DocFocusOptions, DocumentView } from '../DocumentView'; import { FormattedTextBox } from './FormattedTextBox'; -import * as React from 'react'; export class DashDocView { dom: HTMLSpanElement; // container for label and value @@ -83,7 +83,7 @@ export class DashDocViewInternal extends React.Component { _disposers: { [name: string]: IReactionDisposer } = {}; _textBox: FormattedTextBox; @observable _dashDoc: Doc | undefined = undefined; - @observable _finalLayout: any; + @observable _finalLayout: any = undefined; @observable _width: number = 0; @observable _height: number = 0; diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx index 331ed1980..7e655531e 100644 --- a/src/client/views/nodes/formattedText/EquationView.tsx +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -1,14 +1,13 @@ -import EquationEditor from './EquationEditor'; -import { IReactionDisposer, trace } from 'mobx'; +import { IReactionDisposer } from 'mobx'; import { observer } from 'mobx-react'; import { TextSelection } from 'prosemirror-state'; +import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; import { Doc } from '../../../../fields/Doc'; import { StrCast } from '../../../../fields/Types'; import './DashFieldView.scss'; +import EquationEditor from './EquationEditor'; import { FormattedTextBox } from './FormattedTextBox'; -import * as React from 'react'; -import { AnyArray } from 'mongoose'; export class EquationView { dom: HTMLDivElement; // container for label and value diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index ad2fab8b0..8bf8abafa 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -11,6 +11,7 @@ import { keymap } from 'prosemirror-keymap'; import { Fragment, Mark, Node, Slice } from 'prosemirror-model'; import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from 'prosemirror-state'; import { EditorView } from 'prosemirror-view'; +import * as React from 'react'; import { BsMarkdownFill } from 'react-icons/bs'; import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast, Field, Opt } from '../../../../fields/Doc'; @@ -70,9 +71,8 @@ import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu'; import { RichTextRules } from './RichTextRules'; import { schema } from './schema_rts'; import { SummaryView } from './SummaryView'; -// import * as applyDevTools from 'prosemirror-dev-tools'; -import * as React from 'react'; export const GoogleRef = 'googleDocId'; +// import * as applyDevTools from 'prosemirror-dev-tools'; type PullHandler = (exportState: Opt, dataDoc: Doc) => void; export interface FormattedTextBoxProps {} diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 4881070fd..3b31f2d17 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -32,7 +32,7 @@ export class RichTextMenu extends AntimodeMenu { private _linkToRef = React.createRef(); layoutDoc: Doc | undefined; - @observable public view?: EditorView; + @observable public view?: EditorView = undefined; public editorProps: FieldViewProps | undefined; public _brushMap: Map> = new Map(); diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx index 9dc0c5180..b573f7c48 100644 --- a/src/client/views/nodes/importBox/ImportElementBox.tsx +++ b/src/client/views/nodes/importBox/ImportElementBox.tsx @@ -1,13 +1,11 @@ import { computed } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { returnFalse } from '../../../../Utils'; import { Doc } from '../../../../fields/Doc'; -import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue } from '../../../../Utils'; -import { Transform } from '../../../util/Transform'; import { ViewBoxBaseComponent } from '../../DocComponent'; -import { DefaultStyleProvider } from '../../StyleProvider'; -import { DocumentView, DocumentViewInternal } from '../DocumentView'; +import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; -import * as React from 'react'; @observer export class ImportElementBox extends ViewBoxBaseComponent() { diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index e213b2fc5..0305689e7 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -1,8 +1,8 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast, FieldResult, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { Animation } from '../../../../fields/DocSymbols'; import { Copy, Id } from '../../../../fields/FieldSymbols'; @@ -24,7 +24,7 @@ import { SerializationHelper } from '../../../util/SerializationHelper'; import { SettingsManager } from '../../../util/SettingsManager'; import { undoBatch, UndoManager } from '../../../util/UndoManager'; import { CollectionDockingView } from '../../collections/CollectionDockingView'; -import { CollectionFreeFormView, computeTimelineLayout, MarqueeViewBounds } from '../../collections/collectionFreeForm'; +import { CollectionFreeFormView, MarqueeViewBounds } from '../../collections/collectionFreeForm'; import { CollectionStackedTimeline } from '../../collections/CollectionStackedTimeline'; import { CollectionView } from '../../collections/CollectionView'; import { TreeView } from '../../collections/TreeView'; @@ -83,12 +83,12 @@ export class PresBox extends ViewBoxBaseComponent() { _batch: UndoManager.Batch | undefined = undefined; // undo batch for dragging sliders which generate multiple scene edit events as the cursor moves _keyTimer: NodeJS.Timeout | undefined; // timer for turning off transition flag when key frame change has completed. Need to clear this if you do a second navigation before first finishes, or else first timer can go off during second naviation. _unmounting = false; // flag that view is unmounting used to block RemFromMap from deleting things + _presTimer: NodeJS.Timeout | undefined; @observable public static Instance: PresBox; @observable _isChildActive = false; @observable _moveOnFromAudio: boolean = true; - @observable _presTimer!: NodeJS.Timeout; @observable _eleArray: HTMLElement[] = []; @observable _dragArray: HTMLElement[] = []; diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index cf19ff6bc..5ea9e9979 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -1,18 +1,17 @@ -import * as React from 'react'; import { action, computed } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types'; import { LinkFollower } from '../../util/LinkFollower'; +import { LinkManager } from '../../util/LinkManager'; import { undoBatch } from '../../util/UndoManager'; import { OpenWhere } from '../nodes/DocumentView'; import { FieldViewProps } from '../nodes/FieldView'; import { AnchorMenu } from './AnchorMenu'; import './Annotation.scss'; -import { LinkManager } from '../../util/LinkManager'; -import { Rect } from 'react-measure'; interface IAnnotationProps extends FieldViewProps { anno: Doc; diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index db21d9a3d..da8a88803 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -1,20 +1,20 @@ -import * as React from 'react'; -import './GPTPopup.scss'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Button, IconButton, Type } from 'browndash-components'; import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { CgClose } from 'react-icons/cg'; import ReactLoading from 'react-loading'; import { TypeAnimation } from 'react-type-animation'; +import { Utils } from '../../../../Utils'; import { Doc } from '../../../../fields/Doc'; -import { DocUtils, Docs } from '../../../documents/Documents'; -import { Button, IconButton, Type } from 'browndash-components'; import { NumCast, StrCast } from '../../../../fields/Types'; -import { CgClose } from 'react-icons/cg'; -import { AnchorMenu } from '../AnchorMenu'; -import { gptImageCall } from '../../../apis/gpt/GPT'; import { Networking } from '../../../Network'; -import { Utils } from '../../../../Utils'; +import { gptImageCall } from '../../../apis/gpt/GPT'; +import { DocUtils, Docs } from '../../../documents/Documents'; import { ObservableReactComponent } from '../../ObservableReactComponent'; +import { AnchorMenu } from '../AnchorMenu'; +import './GPTPopup.scss'; export enum GPTPopupMode { SUMMARY, diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index e342c25b3..b6d027d30 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -302,7 +302,7 @@ export class PDFViewer extends ObservableReactComponent { } }; - @observable private _scrollTimer: any; + @observable private _scrollTimer: any = undefined; onScroll = (e: React.UIEvent) => { if (this._mainCont.current && !this._forcedScroll) { diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index ccfccb771..14187833f 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -2,24 +2,23 @@ import { Tooltip } from '@mui/material'; import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, DocListCast, DocListCastAsync, Field, Opt } from '../../../fields/Doc'; +import { Doc, DocListCastAsync, Field } from '../../../fields/Doc'; import { DirectLinks } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { DocCast, StrCast } from '../../../fields/Types'; -import { DocUtils } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; +import { DocUtils } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { LinkManager } from '../../util/LinkManager'; +import { SearchUtil } from '../../util/SearchUtil'; +import { SettingsManager } from '../../util/SettingsManager'; import { undoBatch } from '../../util/UndoManager'; -import { CollectionDockingView } from '../collections/CollectionDockingView'; import { ViewBoxBaseComponent } from '../DocComponent'; +import { CollectionDockingView } from '../collections/CollectionDockingView'; +import { IRecommendation, Recommendation } from '../newlightbox/components'; +import { fetchRecommendations } from '../newlightbox/utils'; import { FieldView, FieldViewProps } from '../nodes/FieldView'; import './SearchBox.scss'; -import { fetchRecommendations } from '../newlightbox/utils'; -import { IRecommendation, Recommendation } from '../newlightbox/components'; -import { Colors } from '../global/globalEnums'; -import { SettingsManager } from '../../util/SettingsManager'; -import { SearchUtil } from '../../util/SearchUtil'; const DAMPENING_FACTOR = 0.9; const MAX_ITERATIONS = 25; diff --git a/src/client/views/selectedDoc/SelectedDocView.tsx b/src/client/views/selectedDoc/SelectedDocView.tsx index 39e778b76..daacb368b 100644 --- a/src/client/views/selectedDoc/SelectedDocView.tsx +++ b/src/client/views/selectedDoc/SelectedDocView.tsx @@ -1,14 +1,14 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { ListBox } from 'browndash-components'; import { computed } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { emptyFunction } from '../../../Utils'; import { Doc } from '../../../fields/Doc'; import { StrCast } from '../../../fields/Types'; import { DocumentManager } from '../../util/DocumentManager'; -import { DocFocusOptions } from '../nodes/DocumentView'; -import { emptyFunction } from '../../../Utils'; import { SettingsManager } from '../../util/SettingsManager'; +import { DocFocusOptions } from '../nodes/DocumentView'; export interface SelectedDocViewProps { selectedDocs: Doc[]; diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx index 0f3487cd1..575d5849e 100644 --- a/src/client/views/topbar/TopBar.tsx +++ b/src/client/views/topbar/TopBar.tsx @@ -16,15 +16,15 @@ import { ReportManager } from '../../util/reportManager/ReportManager'; import { ServerStats } from '../../util/ServerStats'; import { SettingsManager } from '../../util/SettingsManager'; import { SharingManager } from '../../util/SharingManager'; +import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { CollectionDockingView } from '../collections/CollectionDockingView'; import { CollectionLinearView } from '../collections/collectionLinear'; import { DashboardView } from '../DashboardView'; import { Colors } from '../global/globalEnums'; -import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView'; +import { DocumentViewInternal } from '../nodes/DocumentView'; import { DefaultStyleProvider } from '../StyleProvider'; import './TopBar.scss'; -import { SnappingManager } from '../../util/SnappingManager'; /** * ABOUT: This is the topbar in Dash, which included the current Dashboard as well as access to information on the user diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx index f1739a41a..94458563e 100644 --- a/src/client/views/webcam/DashWebRTCVideo.tsx +++ b/src/client/views/webcam/DashWebRTCVideo.tsx @@ -3,16 +3,15 @@ import { faPhoneSlash, faSync } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc } from '../../../fields/Doc'; import { InkTool } from '../../../fields/InkField'; +import { SnappingManager } from '../../util/SnappingManager'; import '../../views/nodes/WebBox.scss'; import { CollectionFreeFormDocumentViewProps } from '../nodes/CollectionFreeFormDocumentView'; -import { DocumentView } from '../nodes/DocumentView'; import { FieldView, FieldViewProps } from '../nodes/FieldView'; import './DashWebRTCVideo.scss'; import { hangup, initialize, refreshVideos } from './WebCamLogic'; -import * as React from 'react'; -import { SnappingManager } from '../../util/SnappingManager'; /** * This models the component that will be rendered, that can be used as a doc that will reflect the video cams. diff --git a/src/debug/Repl.tsx b/src/debug/Repl.tsx index b8081648f..a9f7c085f 100644 --- a/src/debug/Repl.tsx +++ b/src/debug/Repl.tsx @@ -1,13 +1,13 @@ +import { computed, observable } from 'mobx'; +import { observer } from 'mobx-react'; import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; -import { observer } from 'mobx-react'; -import { observable, computed } from 'mobx'; +import { DocServer } from '../client/DocServer'; +import { resolvedPorts } from '../client/util/CurrentUserUtils'; import { CompileScript } from '../client/util/Scripting'; -import { makeInterface } from '../fields/Schema'; import { ObjectField } from '../fields/ObjectField'; import { RefField } from '../fields/RefField'; -import { DocServer } from '../client/DocServer'; -import { resolvedPorts } from '../client/util/CurrentUserUtils'; +import { makeInterface } from '../fields/Schema'; @observer class Repl extends React.Component { diff --git a/src/debug/Viewer.tsx b/src/debug/Viewer.tsx index 02038c426..f46adef77 100644 --- a/src/debug/Viewer.tsx +++ b/src/debug/Viewer.tsx @@ -1,19 +1,19 @@ -import { action, configure, observable, ObservableMap, Lambda } from 'mobx'; +import { action, configure, observable } from 'mobx'; +import { observer } from 'mobx-react'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; -import { observer } from 'mobx-react'; -import { Doc, Field, FieldResult, Opt } from '../fields/Doc'; import { DocServer } from '../client/DocServer'; +import { resolvedPorts } from '../client/util/CurrentUserUtils'; +import { CompileScript } from '../client/util/Scripting'; +import { EditableView } from '../client/views/EditableView'; +import CursorField from '../fields/CursorField'; +import { DateField } from '../fields/DateField'; +import { Doc, Field, FieldResult } from '../fields/Doc'; import { Id } from '../fields/FieldSymbols'; import { List } from '../fields/List'; -import { URLField } from '../fields/URLField'; -import { EditableView } from '../client/views/EditableView'; -import { CompileScript } from '../client/util/Scripting'; import { RichTextField } from '../fields/RichTextField'; -import { DateField } from '../fields/DateField'; import { ScriptField } from '../fields/ScriptField'; -import CursorField from '../fields/CursorField'; -import { resolvedPorts } from '../client/util/CurrentUserUtils'; +import { URLField } from '../fields/URLField'; DateField; URLField; diff --git a/src/fields/CursorField.ts b/src/fields/CursorField.ts index 46f5a8e1c..84917ae53 100644 --- a/src/fields/CursorField.ts +++ b/src/fields/CursorField.ts @@ -1,8 +1,7 @@ -import { ObjectField } from './ObjectField'; -import { observable } from 'mobx'; +import { createSimpleSchema, object, serializable } from 'serializr'; import { Deserializable } from '../client/util/SerializationHelper'; -import { serializable, createSimpleSchema, object, date } from 'serializr'; -import { FieldChanged, ToScriptString, ToString, Copy } from './FieldSymbols'; +import { Copy, FieldChanged, ToScriptString, ToString } from './FieldSymbols'; +import { ObjectField } from './ObjectField'; export type CursorPosition = { x: number; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 8903a9f97..9dc3c173d 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -265,8 +265,8 @@ export class Doc extends RefField { @observable public [DocAcl]: { [key: string]: symbol } = {}; @observable public [DocCss]: number = 0; // incrementer denoting a change to CSS layout @observable public [DirectLinks] = new ObservableSet(); - @observable public [AudioPlay]: any; // meant to store sound object from Howl - @observable public [Animation]: Opt; + @observable public [AudioPlay]: any = undefined; // meant to store sound object from Howl + @observable public [Animation]: Opt = undefined; @observable public [Highlight]: boolean = false; @observable public [Brushed]: boolean = false; @observable public [DocViews] = new ObservableSet(); diff --git a/src/fields/List.ts b/src/fields/List.ts index 8c8ff1ea3..b8ad552d2 100644 --- a/src/fields/List.ts +++ b/src/fields/List.ts @@ -2,7 +2,7 @@ import { action, computed, makeObservable, observable } from 'mobx'; import { alias, list, serializable } from 'serializr'; import { DocServer } from '../client/DocServer'; import { ScriptingGlobals } from '../client/util/ScriptingGlobals'; -import { afterDocDeserialize, autoObject, Deserializable } from '../client/util/SerializationHelper'; +import { Deserializable, afterDocDeserialize, autoObject } from '../client/util/SerializationHelper'; import { Field } from './Doc'; import { FieldTuples, Self, SelfProxy } from './DocSymbols'; import { Copy, FieldChanged, Parent, ToScriptString, ToString } from './FieldSymbols'; @@ -11,7 +11,7 @@ import { ProxyField } from './Proxy'; import { RefField } from './RefField'; import { listSpec } from './Schema'; import { Cast } from './Types'; -import { deleteProperty, getter, setter, containedFieldChangedHandler } from './util'; +import { containedFieldChangedHandler, deleteProperty, getter, setter } from './util'; function toObjectField(field: Field) { return field instanceof RefField ? new ProxyField(field) : field; @@ -102,8 +102,8 @@ class ListImpl extends ObjectField { items.length === 0 && deleteCount ? { op: '$remFromSet', items: removed, hint: { start, deleteCount }, length: list.__fieldTuples.length } : items.length && !deleteCount && start === list.__fieldTuples.length - ? { op: '$addToSet', items, length: list.__fieldTuples.length } - : undefined + ? { op: '$addToSet', items, length: list.__fieldTuples.length } + : undefined ); return res.map(toRealField); }), diff --git a/src/fields/Proxy.ts b/src/fields/Proxy.ts index c076f5fe1..3a46e3581 100644 --- a/src/fields/Proxy.ts +++ b/src/fields/Proxy.ts @@ -1,12 +1,12 @@ -import { Deserializable } from '../client/util/SerializationHelper'; -import { Field, FieldWaiting, Opt } from './Doc'; +import { action, computed, observable, runInAction } from 'mobx'; import { primitive, serializable } from 'serializr'; -import { observable, action, runInAction, computed } from 'mobx'; import { DocServer } from '../client/DocServer'; -import { RefField } from './RefField'; -import { ObjectField } from './ObjectField'; -import { Id, Copy, ToScriptString, ToString, ToValue } from './FieldSymbols'; import { scriptingGlobal } from '../client/util/ScriptingGlobals'; +import { Deserializable } from '../client/util/SerializationHelper'; +import { Field, FieldWaiting, Opt } from './Doc'; +import { Copy, Id, ToScriptString, ToString, ToValue } from './FieldSymbols'; +import { ObjectField } from './ObjectField'; +import { RefField } from './RefField'; function deserializeProxy(field: any) { if (!field.cache.field) { diff --git a/src/fields/util.ts b/src/fields/util.ts index 545fe4478..b73520999 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -1,11 +1,11 @@ import { $mobx, action, observable, runInAction, trace } from 'mobx'; import { computedFn } from 'mobx-utils'; +import { returnZero } from '../Utils'; import { DocServer } from '../client/DocServer'; import { LinkManager } from '../client/util/LinkManager'; import { SerializationHelper } from '../client/util/SerializationHelper'; import { UndoManager } from '../client/util/UndoManager'; -import { returnZero } from '../Utils'; -import { aclLevel, Doc, DocListCast, Field, FieldResult, HierarchyMapping, ReverseHierarchyMap, StrListCast, updateCachedAcls } from './Doc'; +import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, ReverseHierarchyMap, StrListCast, aclLevel, updateCachedAcls } from './Doc'; import { AclAdmin, AclAugment, AclEdit, AclPrivate, DocAcl, DocData, DocLayout, FieldKeys, ForceServerWrite, Height, Initializing, SelfProxy, UpdatingFromServer, Width } from './DocSymbols'; import { FieldChanged, Id, Parent, ToValue } from './FieldSymbols'; import { List } from './List'; diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx index d2598c2db..e333e6a2e 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -1,19 +1,19 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import * as rp from 'request-promise'; +import { Utils } from '../Utils'; import { DocServer } from '../client/DocServer'; -import { Docs } from '../client/documents/Documents'; import { Networking } from '../client/Network'; +import { Docs } from '../client/documents/Documents'; import { MainViewModal } from '../client/views/MainViewModal'; import { Doc, Opt } from '../fields/Doc'; import { List } from '../fields/List'; import { listSpec } from '../fields/Schema'; import { Cast } from '../fields/Types'; -import { Utils } from '../Utils'; import './ImageUpload.scss'; import { MobileInterface } from './MobileInterface'; -import * as React from 'react'; const { default: { DFLT_IMAGE_NATIVE_DIM } } = require('../client/views/global/globalCssVariables.module.scss'); // prettier-ignore export interface ImageUploadProps { Document: Doc; // Target document for upload (upload location) diff --git a/src/mobile/MobileInkOverlay.tsx b/src/mobile/MobileInkOverlay.tsx index 2e595e4bc..23e19585a 100644 --- a/src/mobile/MobileInkOverlay.tsx +++ b/src/mobile/MobileInkOverlay.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { DocServer } from '../client/DocServer'; import { DragManager } from '../client/util/DragManager'; import { Doc } from '../fields/Doc'; diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index bdd657575..e3d8f9394 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -1,52 +1,33 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { - faTasks, - faReply, - faQuoteLeft, - faHandPointLeft, - faFolderOpen, + faAddressCard, + faAlignLeft, + faAlignRight, faAngleDoubleLeft, - faExternalLinkSquareAlt, - faMobile, - faThLarge, - faWindowClose, - faEdit, - faTrashAlt, - faPalette, faAngleRight, + faArrowDown, + faArrowLeft, + faArrowRight, + faArrowUp, + faArrowsAltH, + faAsterisk, + faBars, faBell, - faTrash, + faBolt, + faBook, + faBrain, + faBullseye, + faCalculator, faCamera, - faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, - faArrowsAltH, - faPlus, - faMinus, - faTerminal, - faToggleOn, - faFile as fileSolid, - faExternalLinkAlt, - faLocationArrow, - faSearch, - faFileDownload, - faStop, - faCalculator, - faWindowMaximize, - faAddressCard, - faQuestionCircle, - faArrowLeft, - faArrowRight, - faArrowDown, - faArrowUp, - faBolt, - faBullseye, faCaretUp, faCat, faCheck, + faChevronLeft, faChevronRight, faClipboard, faClone, @@ -54,76 +35,95 @@ import { faCommentAlt, faCompressArrowsAlt, faCut, + faEdit, faEllipsisV, faEraser, faExclamation, + faExpand, + faExternalLinkAlt, + faExternalLinkSquareAlt, + faEye, faFileAlt, faFileAudio, + faFileDownload, faFilePdf, faFilm, faFilter, + faFolderOpen, faFont, faGlobeAsia, + faHandPointLeft, faHighlighter, + faHome, + faImage, + faLocationArrow, + faLongArrowAltLeft, faLongArrowAltRight, faMicrophone, + faMinus, + faMobile, faMousePointer, faMusic, faObjectGroup, + faPaintBrush, + faPalette, faPause, faPen, faPenNib, faPhone, faPlay, + faPlus, faPortrait, + faQuestionCircle, + faQuoteLeft, faRedoAlt, + faReply, + faSearch, faStamp, faStickyNote, + faStop, + faTasks, + faTerminal, + faTh, + faThLarge, faThumbtack, + faTimes, + faToggleOn, + faTrash, + faTrashAlt, faTree, faTv, - faBook, faUndoAlt, faVideo, - faAsterisk, - faBrain, - faImage, - faPaintBrush, - faTimes, - faEye, - faHome, - faLongArrowAltLeft, - faBars, - faTh, - faChevronLeft, - faAlignRight, - faAlignLeft, + faWindowClose, + faWindowMaximize, + faFile as fileSolid, } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Docs, DocumentOptions, DocUtils } from '../client/documents/Documents'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../Utils'; import { CollectionViewType, DocumentType } from '../client/documents/DocumentTypes'; +import { Docs, DocumentOptions } from '../client/documents/Documents'; import { CurrentUserUtils } from '../client/util/CurrentUserUtils'; import { ScriptingGlobals } from '../client/util/ScriptingGlobals'; -import { SettingsManager, ColorScheme } from '../client/util/SettingsManager'; +import { SettingsManager } from '../client/util/SettingsManager'; import { Transform } from '../client/util/Transform'; import { UndoManager } from '../client/util/UndoManager'; -import { TabDocView } from '../client/views/collections/TabDocView'; import { GestureOverlay } from '../client/views/GestureOverlay'; +import { TabDocView } from '../client/views/collections/TabDocView'; import { AudioBox } from '../client/views/nodes/AudioBox'; import { DocumentView } from '../client/views/nodes/DocumentView'; -import { RichTextMenu } from '../client/views/nodes/formattedText/RichTextMenu'; import { RadialMenu } from '../client/views/nodes/RadialMenu'; +import { RichTextMenu } from '../client/views/nodes/formattedText/RichTextMenu'; import { Doc, DocListCast } from '../fields/Doc'; import { InkTool } from '../fields/InkField'; import { List } from '../fields/List'; import { ScriptField } from '../fields/ScriptField'; import { Cast, FieldValue, StrCast } from '../fields/Types'; -import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero } from '../Utils'; -import { Uploader } from './ImageUpload'; import './AudioUpload.scss'; +import { Uploader } from './ImageUpload'; import './ImageUpload.scss'; import './MobileInterface.scss'; diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts index 8f21966ae..d46977816 100644 --- a/src/typings/index.d.ts +++ b/src/typings/index.d.ts @@ -14,9 +14,7 @@ declare module 'pdfjs-dist/web/pdf_viewer'; declare module 'react-jsx-parser'; declare module 'express-flash'; -declare module 'connect-flash' { - interface flash {} -} +declare module 'connect-flash'; declare module 'connect-mongo'; declare module '@mui/material'; diff --git a/test/test.ts b/test/test.ts index 489aa3025..ee14a9340 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1,37 +1,41 @@ import { expect } from 'chai'; import 'mocha'; const { JSDOM } = require('jsdom'); -const dom = new JSDOM("", { - url: `http://localhost:${resolvedPorts.server}` +const dom = new JSDOM('', { + url: `http://localhost:${resolvedPorts.server}`, }); (global as any).window = dom.window; - -import { autorun, reaction } from "mobx"; +import { reaction } from 'mobx'; +import { resolvedPorts } from '../src/client/util/CurrentUserUtils'; import { Doc } from '../src/fields/Doc'; +import { createSchema, defaultSpec, makeInterface } from '../src/fields/Schema'; import { Cast } from '../src/fields/Types'; -import { createSchema, makeInterface, defaultSpec } from '../src/fields/Schema'; import { ImageField } from '../src/fields/URLField'; -import { resolvedPorts } from '../src/client/util/CurrentUserUtils'; -describe("Document", () => { +describe('Document', () => { it('should hold fields', () => { - const key = "Test"; - const key2 = "Test2"; + const key = 'Test'; + const key2 = 'Test2'; const field = 15; const doc = new Doc(); doc[key] = field; - const getField = Cast(doc[key], "number"); - const getField2 = Cast(doc[key2], "number"); + const getField = Cast(doc[key], 'number'); + const getField2 = Cast(doc[key2], 'number'); expect(getField).to.equal(field); expect(getField2).to.equal(undefined); }); it('should update', () => { const doc = new Doc(); - const key = "Test"; - const key2 = "Test2"; + const key = 'Test'; + const key2 = 'Test2'; let ran = false; - reaction(() => doc[key], (field) => { ran = true; }); + reaction( + () => doc[key], + field => { + ran = true; + } + ); expect(ran).to.equal(false); doc[key2] = 4; @@ -44,55 +48,55 @@ describe("Document", () => { }); const testSchema1 = createSchema({ - a: "number", - b: "string", - c: "boolean", + a: 'number', + b: 'string', + c: 'boolean', d: ImageField, - e: Doc + e: Doc, }); type TestDoc = makeInterface<[typeof testSchema1]>; const TestDoc = makeInterface(testSchema1); const testSchema2 = createSchema({ - a: defaultSpec("boolean", true), - b: defaultSpec("number", 5), - c: defaultSpec("string", "hello world") + a: defaultSpec('boolean', true), + b: defaultSpec('number', 5), + c: defaultSpec('string', 'hello world'), }); type TestDoc2 = makeInterface<[typeof testSchema2]>; const TestDoc2 = makeInterface(testSchema2); const testSchema3 = createSchema({ - a: TestDoc2 + a: TestDoc2, }); type TestDoc3 = makeInterface<[typeof testSchema3]>; const TestDoc3 = makeInterface(testSchema3); -describe("Schema", () => { - it("should do the right thing 1", () => { - const test1 = new Doc; - const test2 = new Doc; - const ifield = new ImageField(new URL("http://google.com")); +describe('Schema', () => { + it('should do the right thing 1', () => { + const test1 = new Doc(); + const test2 = new Doc(); + const ifield = new ImageField(new URL('http://google.com')); test1.a = 5; - test1.b = "hello"; + test1.b = 'hello'; test1.c = true; test1.d = ifield; test1.e = test2; const doc = TestDoc(test1); expect(doc.a).to.equal(5); - expect(doc.b).to.equal("hello"); + expect(doc.b).to.equal('hello'); expect(doc.c).to.equal(true); expect(doc.d).to.equal(ifield); expect(doc.e).to.equal(test2); }); - it("should do the right thing 2", () => { - const test1 = new Doc; - const test2 = new Doc; - const ifield = new ImageField(new URL("http://google.com")); - test1.a = "hello"; + it('should do the right thing 2', () => { + const test1 = new Doc(); + const test2 = new Doc(); + const ifield = new ImageField(new URL('http://google.com')); + test1.a = 'hello'; test1.b = 5; test1.c = test2; test1.d = true; @@ -105,11 +109,11 @@ describe("Schema", () => { expect(doc.e).to.equal(undefined); }); - it("should do the right thing 3", () => { - const test1 = new Doc; - const test2 = new Doc; - const ifield = new ImageField(new URL("http://google.com")); - test1.a = "hello"; + it('should do the right thing 3', () => { + const test1 = new Doc(); + const test2 = new Doc(); + const ifield = new ImageField(new URL('http://google.com')); + test1.a = 'hello'; test1.b = 5; test1.c = test2; test1.d = true; @@ -122,40 +126,40 @@ describe("Schema", () => { expect(doc.e).to.equal(undefined); }); - it("should do the right thing 4", () => { + it('should do the right thing 4', () => { const doc = TestDoc2(); expect(doc.a).to.equal(true); expect(doc.b).to.equal(5); - expect(doc.c).to.equal("hello world"); + expect(doc.c).to.equal('hello world'); - const d2 = new Doc; + const d2 = new Doc(); d2.a = false; d2.b = 4; - d2.c = "goodbye"; + d2.c = 'goodbye'; const doc2 = TestDoc2(d2); expect(doc2.a).to.equal(false); expect(doc2.b).to.equal(4); - expect(doc2.c).to.equal("goodbye"); + expect(doc2.c).to.equal('goodbye'); - const d3 = new Doc; - d3.a = "hello"; + const d3 = new Doc(); + d3.a = 'hello'; d3.b = false; d3.c = 5; const doc3 = TestDoc2(d3); expect(doc3.a).to.equal(true); expect(doc3.b).to.equal(5); - expect(doc3.c).to.equal("hello world"); + expect(doc3.c).to.equal('hello world'); }); - it("should do the right thing 5", async () => { - const test1 = new Doc; - const test2 = new Doc; + it('should do the right thing 5', async () => { + const test1 = new Doc(); + const test2 = new Doc(); const doc = TestDoc3(test1); expect(doc.a).to.equal(undefined); test1.a = test2; const doc2 = (await doc.a)!; expect(doc2.a).to.equal(true); expect(doc2.b).to.equal(5); - expect(doc2.c).to.equal("hello world"); + expect(doc2.c).to.equal('hello world'); }); }); -- cgit v1.2.3-70-g09d2 From fdc0bf7c54af252178f587709630d36726484b91 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 2 Jan 2024 13:26:53 -0500 Subject: fixing more .props => ._props refernces. --- src/client/util/BranchingTrailManager.tsx | 2 +- src/client/util/CaptureManager.tsx | 2 +- src/client/util/DictationManager.ts | 8 +-- src/client/util/DragManager.ts | 2 +- src/client/util/GroupMemberView.tsx | 29 +++++---- src/client/util/SelectionManager.ts | 10 +-- src/client/util/SharingManager.tsx | 2 +- src/client/util/TrackMovements.ts | 4 +- src/client/views/DocComponent.tsx | 3 +- src/client/views/DocumentButtonBar.tsx | 74 +++------------------- src/client/views/DocumentDecorations.tsx | 10 +-- src/client/views/FilterPanel.tsx | 18 ++++-- src/client/views/InkStrokeProperties.ts | 2 +- src/client/views/PropertiesButtons.tsx | 6 +- src/client/views/StyleProvider.tsx | 2 +- src/client/views/TemplateMenu.tsx | 6 +- .../views/collections/CollectionCarousel3DView.tsx | 4 +- .../views/collections/CollectionCarouselView.tsx | 2 +- .../views/collections/CollectionDockingView.tsx | 2 +- src/client/views/collections/CollectionMenu.tsx | 4 +- .../views/collections/CollectionNoteTakingView.tsx | 2 +- .../views/collections/CollectionPileView.tsx | 4 +- .../collections/CollectionStackedTimeline.tsx | 2 +- src/client/views/collections/TreeView.tsx | 6 +- .../CollectionFreeFormLinkView.tsx | 4 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../collectionGrid/CollectionGridView.tsx | 72 ++++++++++----------- .../collectionMulticolumn/MulticolumnResizer.tsx | 11 +--- .../collectionMulticolumn/MultirowResizer.tsx | 11 +--- .../nodes/DataVizBox/components/LineChart.tsx | 6 +- .../views/nodes/DataVizBox/components/TableBox.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 16 ++--- src/client/views/nodes/MapBox/MapBox2.tsx | 34 +++++----- src/client/views/nodes/MapBox/MapPushpinBox.tsx | 4 +- .../views/nodes/MapboxMapBox/MapboxContainer.tsx | 54 ++++++++-------- .../nodes/PhysicsBox/PhysicsSimulationBox.tsx | 34 +++++----- .../views/nodes/RecordingBox/RecordingBox.tsx | 6 +- src/client/views/nodes/ScreenshotBox.tsx | 50 +++++++-------- src/client/views/nodes/ScriptingBox.tsx | 14 ++-- src/client/views/nodes/audio/AudioWaveform.tsx | 2 +- .../views/nodes/formattedText/DashDocView.tsx | 16 ++--- .../views/nodes/formattedText/EquationView.tsx | 4 +- .../views/nodes/formattedText/RichTextMenu.tsx | 16 ++--- .../views/nodes/importBox/ImportElementBox.tsx | 4 +- src/client/views/pdf/Annotation.tsx | 55 ++++++++-------- src/client/views/search/SearchBox.tsx | 10 +-- src/client/views/selectedDoc/SelectedDocView.tsx | 6 +- 47 files changed, 289 insertions(+), 350 deletions(-) (limited to 'src/client/views/nodes/audio') diff --git a/src/client/util/BranchingTrailManager.tsx b/src/client/util/BranchingTrailManager.tsx index 11f16493f..02879e3c4 100644 --- a/src/client/util/BranchingTrailManager.tsx +++ b/src/client/util/BranchingTrailManager.tsx @@ -54,7 +54,7 @@ export class BranchingTrailManager extends React.Component { @observable private docIdToDocMap: Map = new Map(); observeDocumentChange = (targetDoc: Doc, pres: PresBox) => { - const presId = pres.props.Document[Id]; + const presId = pres.Document[Id]; if (this.prevPresId === presId) { return; } diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx index c1e0a5b2e..2e13aff2f 100644 --- a/src/client/util/CaptureManager.tsx +++ b/src/client/util/CaptureManager.tsx @@ -84,7 +84,7 @@ export class CaptureManager extends React.Component<{}> { onClick={() => { const selected = SelectionManager.Views.slice(); SelectionManager.DeselectAll(); - selected.map(dv => dv.props.removeDocument?.(dv.props.Document)); + selected.map(dv => dv.props.removeDocument?.(dv.Document)); this.close(); }}> Cancel diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts index 039bb360e..82c63695c 100644 --- a/src/client/util/DictationManager.ts +++ b/src/client/util/DictationManager.ts @@ -290,7 +290,7 @@ export namespace DictationManager { if (!ctor) { return false; } - return Cast(Doc.GetProto(view.props.Document).data, ctor) !== undefined; + return Cast(Doc.GetProto(view.Document).data, ctor) !== undefined; }; const validate = (target: DocumentView, types: DocumentType[]) => { @@ -318,7 +318,7 @@ export namespace DictationManager { [ 'clear', { - action: (target: DocumentView) => (Doc.GetProto(target.props.Document).data = new List()), + action: (target: DocumentView) => (Doc.GetProto(target.Document).data = new List()), restrictTo: [DocumentType.COL], }, ], @@ -347,7 +347,7 @@ export namespace DictationManager { action: (target: DocumentView, matches: RegExpExecArray) => { const count = interpretNumber(matches[1]); const what = matches[2]; - const dataDoc = Doc.GetProto(target.props.Document); + const dataDoc = Doc.GetProto(target.Document); const fieldKey = 'data'; if (isNaN(count)) { return; @@ -372,7 +372,7 @@ export namespace DictationManager { expression: /view as (freeform|stacking|masonry|schema|tree)/g, action: (target: DocumentView, matches: RegExpExecArray) => { const mode = matches[1]; - mode && (target.props.Document._type_collection = mode); + mode && (target.Document._type_collection = mode); }, restrictTo: [DocumentType.COL], } diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index fe3a52be7..9ede18ed5 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -142,7 +142,7 @@ export namespace DragManager { this.linkSourceGetAnchor = linkSourceGetAnchor; } get dragDocument() { - return this.linkDragView.props.Document; + return this.linkDragView.Document; } linkSourceGetAnchor: () => Doc; linkSourceDoc?: Doc; diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx index 7de0f336f..894583711 100644 --- a/src/client/util/GroupMemberView.tsx +++ b/src/client/util/GroupMemberView.tsx @@ -19,35 +19,38 @@ interface GroupMemberViewProps { @observer export class GroupMemberView extends React.Component { @observable private memberSort: 'ascending' | 'descending' | 'none' = 'none'; + get group() { + return this.props.group; + } private get editingInterface() { - let members: string[] = this.props.group ? JSON.parse(StrCast(this.props.group.members)) : []; + let members: string[] = this.group ? JSON.parse(StrCast(this.group.members)) : []; members = this.memberSort === 'ascending' ? members.sort() : this.memberSort === 'descending' ? members.sort().reverse() : members; - const options: UserOptions[] = this.props.group ? GroupManager.Instance.options.filter(option => !(JSON.parse(StrCast(this.props.group.members)) as string[]).includes(option.value)) : []; + const options: UserOptions[] = this.group ? GroupManager.Instance.options.filter(option => !(JSON.parse(StrCast(this.group.members)) as string[]).includes(option.value)) : []; - const hasEditAccess = GroupManager.Instance.hasEditAccess(this.props.group); + const hasEditAccess = GroupManager.Instance.hasEditAccess(this.group); - return !this.props.group ? null : ( + return !this.group ? null : (
(this.props.group.title = e.currentTarget.value)} + value={StrCast(this.group.title || this.group.groupName)} + onChange={e => (this.group.title = e.currentTarget.value)} disabled={!hasEditAccess}>
- {GroupManager.Instance.hasEditAccess(this.props.group) ? ( + {GroupManager.Instance.hasEditAccess(this.group) ? (
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx index ea99bff2e..c38c6dc4e 100644 --- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx @@ -18,12 +18,8 @@ interface ResizerProps { select: (isCtrlPressed: boolean) => void; } -const resizerOpacity = 1; - @observer export default class ResizeBar extends React.Component { - @observable private isHoverActive = false; - @observable private isResizingActive = false; private _resizeUndo?: UndoManager.Batch; @action @@ -35,7 +31,6 @@ export default class ResizeBar extends React.Component { window.removeEventListener('pointerup', this.onPointerUp); window.addEventListener('pointermove', this.onPointerMove); window.addEventListener('pointerup', this.onPointerUp); - this.isResizingActive = true; this._resizeUndo = UndoManager.StartBatch('multcol resizing'); }; @@ -80,8 +75,6 @@ export default class ResizeBar extends React.Component { @action private onPointerUp = () => { - this.isResizingActive = false; - this.isHoverActive = false; window.removeEventListener('pointermove', this.onPointerMove); window.removeEventListener('pointerup', this.onPointerUp); this._resizeUndo?.end(); @@ -96,9 +89,7 @@ export default class ResizeBar extends React.Component { pointerEvents: this.props.isContentActive?.() ? 'all' : 'none', width: this.props.width, backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor), - }} - onPointerEnter={action(() => (this.isHoverActive = true))} - onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))}> + }}>
this.registerResizing(e)} />
); diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx index 7dee65e58..6f1b3b425 100644 --- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx @@ -17,12 +17,8 @@ interface ResizerProps { toBottom?: Doc; } -const resizerOpacity = 1; - @observer export default class ResizeBar extends React.Component { - @observable private isHoverActive = false; - @observable private isResizingActive = false; private _resizeUndo?: UndoManager.Batch; @action @@ -33,7 +29,6 @@ export default class ResizeBar extends React.Component { window.removeEventListener('pointerup', this.onPointerUp); window.addEventListener('pointermove', this.onPointerMove); window.addEventListener('pointerup', this.onPointerUp); - this.isResizingActive = true; this._resizeUndo = UndoManager.StartBatch('multcol resizing'); }; @@ -78,8 +73,6 @@ export default class ResizeBar extends React.Component { @action private onPointerUp = () => { - this.isResizingActive = false; - this.isHoverActive = false; window.removeEventListener('pointermove', this.onPointerMove); window.removeEventListener('pointerup', this.onPointerUp); this._resizeUndo?.end(); @@ -94,9 +87,7 @@ export default class ResizeBar extends React.Component { pointerEvents: this.props.isContentActive?.() ? 'all' : 'none', height: this.props.height, backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor), - }} - onPointerEnter={action(() => (this.isHoverActive = true))} - onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))}> + }}>
this.registerResizing(e)} />
); diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index a69f083d1..50a8bf83d 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -358,7 +358,7 @@ export class LineChart extends ObservableReactComponent { const selectedPt = this._currSelected ? `{ ${this._props.axes[0]}: ${this._currSelected.x} ${this._props.axes[1]}: ${this._currSelected.y} }` : 'none'; if (this._lineChartData.length > 0 || !this.parentViz || this.parentViz.length == 0) { return this._props.axes.length >= 2 && /\d/.test(this._props.records[0][this._props.axes[0]]) && /\d/.test(this._props.records[0][this._props.axes[1]]) ? ( -
+
{
) : null} diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index f127fecf3..5365fe1b2 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -169,7 +169,7 @@ export class TableBox extends ObservableReactComponent { return (
{ if (this._props.layoutDoc && e.key === 'a' && (e.ctrlKey || e.metaKey)) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index f8f4b94a2..d07824099 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -881,7 +881,7 @@ export class DocumentViewInternal extends DocComponent this._rootSelected; panelHeight = () => this._props.PanelHeight() - this.headerMargin; - screenToLocal = () => this._props.ScreenToLocalTransform().translate(0, -this.headerMargin); + contentScreenToLocal = () => this._props.ScreenToLocalTransform().translate(0, -this.headerMargin); onClickFunc: any = () => (this.disableClickScriptFunc ? undefined : this.onClickHandler); setHeight = (height: number) => !this._props.suppressSetHeight && (this.layoutDoc._height = height); setContentView = action((view: { getAnchor?: (addAsAnnotation: boolean) => Doc; forward?: () => boolean; back?: () => boolean }) => (this._componentView = view)); @@ -925,7 +925,7 @@ export class DocumentViewInternal extends DocComponent { } @observable _selected = false; - public get SELECTED() { + public get IsSelected() { return this._selected; } - public set SELECTED(val) { + public set IsSelected(val) { runInAction(() => (this._selected = val)); } @observable public static LongPress = false; @@ -1431,9 +1431,9 @@ export class DocumentView extends ObservableReactComponent { return this._props.LayoutTemplateString?.includes('link_anchor_2') ? DocCast(this.Document['link_anchor_2']) : this._props.LayoutTemplateString?.includes('link_anchor_1') ? DocCast(this.Document['link_anchor_1']) : undefined; } @computed get hideLinkButton() { - return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HideLinkBtn + (this.SELECTED ? ':selected' : '')); + return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HideLinkBtn + (this.IsSelected ? ':selected' : '')); } - hideLinkCount = () => this._props.renderDepth === -1 || (this.SELECTED && this._props.renderDepth) || !this._isHovering || this.hideLinkButton; + hideLinkCount = () => this._props.renderDepth === -1 || (this.IsSelected && this._props.renderDepth) || !this._isHovering || this.hideLinkButton; @computed get linkCountView() { return ; } @@ -1568,9 +1568,9 @@ export class DocumentView extends ObservableReactComponent { layout_fitWidthFunc = (doc: Doc) => BoolCast(this.layout_fitWidth); scaleToScreenSpace = () => (1 / (this._props.NativeDimScaling?.() || 1)) * this.screenToLocalTransform().Scale; docViewPathFunc = () => this.docViewPath; - isSelected = () => this.SELECTED; + isSelected = () => this.IsSelected; select = (extendSelection: boolean, focusSelection?: boolean) => { - if (this.SELECTED && SelectionManager.Views.length > 1) SelectionManager.DeselectView(this); + if (this.IsSelected && SelectionManager.Views.length > 1) SelectionManager.DeselectView(this); else { SelectionManager.SelectView(this, extendSelection); if (focusSelection) { diff --git a/src/client/views/nodes/MapBox/MapBox2.tsx b/src/client/views/nodes/MapBox/MapBox2.tsx index 1dbbbb633..722a347f1 100644 --- a/src/client/views/nodes/MapBox/MapBox2.tsx +++ b/src/client/views/nodes/MapBox/MapBox2.tsx @@ -127,7 +127,7 @@ // private _ref: React.RefObject = React.createRef(); // componentDidMount() { -// this.props.setContentView?.(this); +// this._props.setContentView?.(this); // } // @action @@ -358,9 +358,9 @@ // e, // (e, down, delta) => // runInAction(() => { -// const localDelta = this.props +// const localDelta = this._props // .ScreenToLocalTransform() -// .scale(this.props.NativeDimScaling?.() || 1) +// .scale(this._props.NativeDimScaling?.() || 1) // .transformDirection(delta[0], delta[1]); // const fullWidth = NumCast(this.layoutDoc._width); // const mapWidth = fullWidth - this.sidebarWidth(); @@ -380,12 +380,12 @@ // ); // }; -// sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth(); +// sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this._props.PanelWidth(); // @computed get layout_sidebarWidthPercent() { // return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); // } // @computed get sidebarColor() { -// return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this.props.fieldKey + '_backgroundColor'], '#e4e4e4')); +// return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this._props.fieldKey + '_backgroundColor'], '#e4e4e4')); // } // /** @@ -444,7 +444,7 @@ // key="sidebar" // title="Toggle Sidebar" // style={{ -// display: !this.props.isContentActive() ? 'none' : undefined, +// display: !this._props.isContentActive() ? 'none' : undefined, // top: StrCast(this.layoutDoc._layout_showTitle) === 'title' ? 20 : 5, // backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK, // }} @@ -481,7 +481,7 @@ // }; // pointerEvents = () => { -// return this.props.isContentActive() === false ? 'none' : this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : SnappingManager.IsDragging ? undefined : 'none'; +// return this._props.isContentActive() === false ? 'none' : this._props.isContentActive() && this._props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : SnappingManager.IsDragging ? undefined : 'none'; // }; // @computed get annotationLayer() { // return ( @@ -489,7 +489,7 @@ // {this.inlineTextAnnotations // .sort((a, b) => NumCast(a.y) - NumCast(b.y)) // .map(anno => ( -// +// // ))} //
// ); @@ -515,13 +515,13 @@ // // } // }; -// panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth(); -// panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); -// scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); -// transparentFilter = () => [...this.props.childFilters(), Utils.TransparentBackgroundFilter]; -// opaqueFilter = () => [...this.props.childFilters(), Utils.OpaqueBackgroundFilter]; -// infoWidth = () => this.props.PanelWidth() / 5; -// infoHeight = () => this.props.PanelHeight() / 5; +// panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1) - this.sidebarWidth(); +// panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); +// scrollXf = () => this._props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); +// transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter]; +// opaqueFilter = () => [...this._props.childFilters(), Utils.OpaqueBackgroundFilter]; +// infoWidth = () => this._props.PanelWidth() / 5; +// infoHeight = () => this._props.PanelHeight() / 5; // anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; // savedAnnotations = () => this._savedAnnotations; @@ -556,7 +556,7 @@ // .map(marker => ( // // () { } get mapBoxView() { - return this.props.DocumentView?.()?._props.docViewPath().lastElement()?.ComponentView as MapBox; + return this._props.DocumentView?.()?._props.docViewPath().lastElement()?.ComponentView as MapBox; } get mapBox() { - return this.props.DocumentView?.()._props.docViewPath().lastElement()?.Document; + return this._props.DocumentView?.()._props.docViewPath().lastElement()?.Document; } render() { diff --git a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx index 70037f29c..2c31bbab7 100644 --- a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx +++ b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx @@ -89,7 +89,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent runInAction(() => { - const localDelta = this.props + const localDelta = this._props .ScreenToLocalTransform() - .scale(this.props.NativeDimScaling?.() || 1) + .scale(this._props.NativeDimScaling?.() || 1) .transformDirection(delta[0], delta[1]); const fullWidth = NumCast(this.layoutDoc._width); const mapWidth = fullWidth - this.sidebarWidth(); @@ -183,7 +183,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent UndoManager.RunInBatch(this.toggleSidebar, 'toggle sidebar map') ); }; - sidebarWidth = () => (Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth(); + sidebarWidth = () => (Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100) * this._props.PanelWidth(); /** * Handles toggle of sidebar on click the little comment button @@ -195,7 +195,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent { if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) { - e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.props.Document; + e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this._props.Document; e.annoDragData.linkSourceDoc.followLinkZoom = false; } }, @@ -276,15 +276,15 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent this.addDocument(doc, annotationKey); - pointerEvents = () => (this.props.isContentActive() && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : 'none'); + pointerEvents = () => (this._props.isContentActive() && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : 'none'); - panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth(); - panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); - scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); - transparentFilter = () => [...this.props.childFilters(), Utils.TransparentBackgroundFilter]; - opaqueFilter = () => [...this.props.childFilters(), Utils.OpaqueBackgroundFilter]; - infoWidth = () => this.props.PanelWidth() / 5; - infoHeight = () => this.props.PanelHeight() / 5; + panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1) - this.sidebarWidth(); + panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); + scrollXf = () => this._props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); + transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter]; + opaqueFilter = () => [...this._props.childFilters(), Utils.OpaqueBackgroundFilter]; + infoWidth = () => this._props.PanelWidth() / 5; + infoHeight = () => this._props.PanelHeight() / 5; anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; savedAnnotations = () => this._savedAnnotations; @@ -399,9 +399,9 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent { - this.props.select(false); + this._props.select(false); this.deselectPin(); }; /* @@ -677,9 +677,9 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent ( {/* [this.props.PanelWidth(), this.props.PanelHeight()], this.setupSimulation, { fireImmediately: true }); + this._widthDisposer = reaction(() => [this._props.PanelWidth(), this._props.PanelHeight()], this.setupSimulation, { fireImmediately: true }); // Create walls this.wallPositions = [ { length: 100, xPos: 0, yPos: 0, angleInDegrees: 0 }, { length: 100, xPos: 0, yPos: 100, angleInDegrees: 0 }, { length: 100, xPos: 0, yPos: 0, angleInDegrees: 90 }, - { length: 100, xPos: (this.xMax / this.props.PanelWidth()) * 100, yPos: 0, angleInDegrees: 90 }, + { length: 100, xPos: (this.xMax / this._props.PanelWidth()) * 100, yPos: 0, angleInDegrees: 90 }, ]; } - componentDidUpdate(prevProps: Readonly>) { + componentDidUpdate(prevProps: Readonly) { super.componentDidUpdate(prevProps); - 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(); + 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(); } } @@ -632,7 +632,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { - const length = (300 * this.props.PanelWidth()) / 1000; + const length = (300 * this._props.PanelWidth()) / 1000; const angle = 30; const x = length * Math.cos(((90 - angle) * Math.PI) / 180); const y = length * Math.sin(((90 - angle) * Math.PI) / 180); @@ -808,8 +808,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
@@ -923,8 +923,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
this.props.isContentActive() && e.stopPropagation()} - style={{ overflow: 'auto', height: `${Math.max(1, 800 / this.props.PanelWidth()) * 100}%`, transform: `scale(${Math.min(1, this.props.PanelWidth() / 850)})` }}> + onWheel={e => this._props.isContentActive() && e.stopPropagation()} + style={{ overflow: 'auto', height: `${Math.max(1, 800 / this._props.PanelWidth()) * 100}%`, transform: `scale(${Math.min(1, this._props.PanelWidth() / 850)})` }}>
{this.dataDoc.simulation_paused && this.simulationMode != 'Tutorial' && ( diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 658cfb1ca..c04a81f7d 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -31,7 +31,7 @@ export class RecordingBox extends ViewBoxBaseComponent() { private _ref: React.RefObject = React.createRef(); componentDidMount() { - this.props.setContentView?.(this); + this._props.setContentView?.(this); Doc.SetNativeWidth(this.dataDoc, 1280); Doc.SetNativeHeight(this.dataDoc, 720); } @@ -49,7 +49,7 @@ export class RecordingBox extends ViewBoxBaseComponent() { this.dataDoc[this.fieldKey + '_duration'] = this.videoDuration; this.dataDoc.layout = VideoBox.LayoutString(this.fieldKey); - this.dataDoc[this.props.fieldKey] = new VideoField(this.result.accessPaths.client); + this.dataDoc[this._props.fieldKey] = new VideoField(this.result.accessPaths.client); this.dataDoc[this.fieldKey + '_recorded'] = true; // stringify the presentation and store it if (presentation?.movements) { @@ -135,7 +135,7 @@ export class RecordingBox extends ViewBoxBaseComponent() { @action public static addRecToWorkspace(value: RecordingBox) { let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); - (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value.Document); + (ffView?.ComponentView as CollectionFreeFormView)._props.addDocument?.(value.Document); Doc.RemoveDocFromList(Doc.UserDoc(), 'workspaceRecordings', value.Document); Doc.RemFromMyOverlay(value.Document); Doc.UserDoc().currentRecording = undefined; diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 79ed69cdd..36527c311 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -47,8 +47,8 @@ declare class MediaRecorder { // _mesh: any = undefined; // render() { -// const topLeft = [this.props.x, this.props.y]; -// const raised = this.props.raised; +// const topLeft = [this._props.x, this._props.y]; +// const raised = this._props.raised; // const find = (raised: { coord: Vector2, off: Vector3 }[], what: Vector2) => raised.find(r => r.coord.x === what.x && r.coord.y === what.y); // const tl1 = find(raised, new Vector2(topLeft[0], topLeft[1] + 1)); // const tl2 = find(raised, new Vector2(topLeft[0] + 1, topLeft[1] + 1)); @@ -69,11 +69,11 @@ declare class MediaRecorder { // const normals = new Float32Array(quad_normals); // const uvs = new Float32Array(quad_uvs); // Each vertex has one uv coordinate for texture mapping // const indices = new Uint32Array(quad_indices); // Use the four vertices to draw the two triangles that make up the square. -// const popOut = () => NumCast(this.props.Document.popOut); -// const popOff = () => NumCast(this.props.Document.popOff); +// const popOut = () => NumCast(this.Document.popOut); +// const popOff = () => NumCast(this.Document.popOff); // return ( // { -// this.props.setRaised([ +// this._props.setRaised([ // { coord: new Vector2(topLeft[0], topLeft[1]), off: new Vector3(-popOff(), -popOff(), popOut()) }, // { coord: new Vector2(topLeft[0] + 1, topLeft[1]), off: new Vector3(popOff(), -popOff(), popOut()) }, // { coord: new Vector2(topLeft[0], topLeft[1] + 1), off: new Vector3(-popOff(), popOff(), popOut()) }, @@ -99,7 +99,7 @@ declare class MediaRecorder { // r?.setAttribute('uv', new BufferAttribute(uvs, 2)); // r?.setIndex(new BufferAttribute(indices, 1)); // }} /> -// {!this._videoRef ? : +// {!this._videoRef ? : // // // } @@ -118,7 +118,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent ({ width: this.props.PanelWidth(), height: this.props.PanelHeight() }), + this._props.setContentView?.(this); // this tells the DocumentView that this ScreenshotBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link. + // this.layoutDoc.videoWall && reaction(() => ({ width: this._props.PanelWidth(), height: this._props.PanelHeight() }), // ({ width, height }) => { // if (this._camera) { // const angle = -Math.abs(1 - width / height); @@ -201,7 +201,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent numberRange(this._numScreens).forEach(y => screens.push( // ))); - // return { + // return { // this._camera = props.camera; // props.camera.position.set(this._numScreens / 2, this._numScreens / 2, this._numScreens - 2); // props.camera.lookAt(this._numScreens / 2, this._numScreens / 2, 0); @@ -224,15 +224,15 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { const [{ result }] = await Networking.UploadFilesToServer(aud_chunks.map((file: any) => ({ file }))); if (!(result instanceof Error)) { - this.dataDoc[this.props.fieldKey + '_audio'] = new AudioField(result.accessPaths.agnostic.client); + this.dataDoc[this._props.fieldKey + '_audio'] = new AudioField(result.accessPaths.agnostic.client); } }; this._videoRef!.srcObject = await (navigator.mediaDevices as any).getDisplayMedia({ video: true }); this._videoRec = new MediaRecorder(this._videoRef!.srcObject); const vid_chunks: any = []; this._videoRec.onstart = () => { - if (this.dataDoc[this.props.fieldKey + '_trackScreen']) TrackMovements.Instance.start(); - this.dataDoc[this.props.fieldKey + '_recordingStart'] = new DateField(new Date()); + if (this.dataDoc[this._props.fieldKey + '_trackScreen']) TrackMovements.Instance.start(); + this.dataDoc[this._props.fieldKey + '_recordingStart'] = new DateField(new Date()); }; this._videoRec.ondataavailable = (e: any) => vid_chunks.push(e.data); this._videoRec.onstop = async (e: any) => { @@ -252,7 +252,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent (NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], NumCast(this.layoutDoc._height)) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth'], NumCast(this.layoutDoc._width))) * this.props.PanelWidth(); - formattedPanelHeight = () => Math.max(0, this.props.PanelHeight() - this.videoPanelHeight()); + videoPanelHeight = () => (NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], NumCast(this.layoutDoc._height)) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth'], NumCast(this.layoutDoc._width))) * this._props.PanelWidth(); + formattedPanelHeight = () => Math.max(0, this._props.PanelHeight() - this.videoPanelHeight()); render() { TraceMobx(); return ( @@ -296,14 +296,14 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent
+ ScreenToLocalTransform={this._props.ScreenToLocalTransform} + renderDepth={this._props.renderDepth + 1}> <> {this.threed} {this.content} @@ -324,7 +324,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent {!(this.dataDoc[this.fieldKey + '_dictation'] instanceof Doc) ? null : ( )}
- {!this.props.isSelected() ? null : ( + {!this._props.isSelected() ? null : (
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index 8e506ec64..73ad3a004 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -60,7 +60,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent !p.startsWith('_')) @@ -116,7 +116,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent { @@ -294,7 +294,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent { const copy = Doc.MakeCopy(this.Document, true); copy.x = NumCast(this.Document.x) + NumCast(this.dataDoc._width); - this.props.addDocument?.(copy); + this._props.addDocument?.(copy); }; // adds option to create a copy to the context menu @@ -310,7 +310,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent (this.functionName = e.target.value)} placeholder="enter name here" value={this.functionName} />; return ( -
this.props.isSelected() && e.stopPropagation()}> +
this._props.isSelected() && e.stopPropagation()}>
@@ -687,7 +687,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent this.props.isSelected() && e.stopPropagation()}> +
this._props.isSelected() && e.stopPropagation()}>
{this.renderScriptingBox} {definedParameters} @@ -745,7 +745,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent this.props.isSelected() && e.stopPropagation()}> +
this._props.isSelected() && e.stopPropagation()}> {!this.compileParams.length || !this.paramsNames ? null : (
{this.paramsNames.map((parameter: string, i: number) => ( @@ -812,7 +812,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent -
this.props.isSelected() && e.stopPropagation()}> +
this._props.isSelected() && e.stopPropagation()}> {this._paramSuggestion ? (
{' '} diff --git a/src/client/views/nodes/audio/AudioWaveform.tsx b/src/client/views/nodes/audio/AudioWaveform.tsx index 3e46ff4e6..7fd799952 100644 --- a/src/client/views/nodes/audio/AudioWaveform.tsx +++ b/src/client/views/nodes/audio/AudioWaveform.tsx @@ -109,7 +109,7 @@ export class AudioWaveform extends ObservableReactComponent progressColor={Colors.MEDIUM_BLUE_ALT} progress={this._props.progress ?? 1} barWidth={200 / this.audioBuckets.length} - //gradientColors={this.props.gradientColors} + //gradientColors={this._props.gradientColors} peaks={this.audioBuckets} width={(this._props.PanelWidth ?? 0) * window.devicePixelRatio} height={this.waveHeight * window.devicePixelRatio} diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index 1002ee403..5a13fa8b4 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -177,7 +177,7 @@ export class DashDocViewInternal extends React.Component { }; componentWillUnmount = () => Object.values(this._disposers).forEach(disposer => disposer?.()); - isContentActive = () => this.props.tbox.props.isSelected() || this.props.tbox.isAnyChildContentActive?.(); + isContentActive = () => this.props.tbox._props.isSelected() || this.props.tbox.isAnyChildContentActive?.(); render() { return !this._dashDoc || !this._finalLayout || this.props.hidden ? null : ( @@ -205,21 +205,21 @@ export class DashDocViewInternal extends React.Component { removeDocument={this.removeDoc} isDocumentActive={returnFalse} isContentActive={this.isContentActive} - styleProvider={this._textBox.props.styleProvider} - docViewPath={this._textBox.props.docViewPath} + styleProvider={this._textBox._props.styleProvider} + docViewPath={this._textBox._props.docViewPath} ScreenToLocalTransform={this.getDocTransform} - addDocTab={this._textBox.props.addDocTab} + addDocTab={this._textBox._props.addDocTab} pinToPres={returnFalse} - renderDepth={this._textBox.props.renderDepth + 1} + renderDepth={this._textBox._props.renderDepth + 1} PanelWidth={this._finalLayout[Width]} PanelHeight={this._finalLayout[Height]} focus={this.outerFocus} whenChildContentsActiveChanged={this.props.tbox.whenChildContentsActiveChanged} bringToFront={emptyFunction} dontRegisterView={false} - childFilters={this.props.tbox?.props.childFilters} - childFiltersByRanges={this.props.tbox?.props.childFiltersByRanges} - searchFilterDocs={this.props.tbox?.props.searchFilterDocs} + childFilters={this.props.tbox?._props.childFilters} + childFiltersByRanges={this.props.tbox?._props.childFiltersByRanges} + searchFilterDocs={this.props.tbox?._props.searchFilterDocs} />
); diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx index 7e655531e..b786c5ffb 100644 --- a/src/client/views/nodes/formattedText/EquationView.tsx +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -65,8 +65,8 @@ export class EquationViewInternal extends React.Component constructor(props: any) { super(props); - this._fieldKey = this.props.fieldKey; - this._textBoxDoc = this.props.tbox.props.Document; + this._fieldKey = props.fieldKey; + this._textBoxDoc = props.tbox.Document; } componentWillUnmount() { diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 3b31f2d17..5858c3b11 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -186,7 +186,7 @@ export class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveAlignment() { - if (this.view && this.TextView?.props.rootSelected?.()) { + if (this.view && this.TextView?._props.rootSelected?.()) { const path = (this.view.state.selection.$from as any).path; for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) { if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) { @@ -199,7 +199,7 @@ export class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveListStyle() { - if (this.view && this.TextView?.props.rootSelected?.()) { + if (this.view && this.TextView?._props.rootSelected?.()) { const path = (this.view.state.selection.$from as any).path; for (let i = 0; i < path.length; i += 3) { if (path[i].type === this.view.state.schema.nodes.ordered_list) { @@ -219,7 +219,7 @@ export class RichTextMenu extends AntimodeMenu { const activeSizes = new Set(); const activeColors = new Set(); const activeHighlights = new Set(); - if (this.view && this.TextView?.props.rootSelected?.()) { + if (this.view && this.TextView?._props.rootSelected?.()) { const state = this.view.state; const pos = this.view.state.selection.$from; const marks: Mark[] = [...(state.storedMarks ?? [])]; @@ -254,7 +254,7 @@ export class RichTextMenu extends AntimodeMenu { //finds all active marks on selection in given group getActiveMarksOnSelection() { let activeMarks: MarkType[] = []; - if (!this.view || !this.TextView?.props.rootSelected?.()) return activeMarks; + if (!this.view || !this.TextView?._props.rootSelected?.()) return activeMarks; const markGroup = [schema.marks.noAutoLinkAnchor, schema.marks.strong, schema.marks.em, schema.marks.underline, schema.marks.strikethrough, schema.marks.superscript, schema.marks.subscript]; if (this.view.state.storedMarks) return this.view.state.storedMarks.map(mark => mark.type); @@ -447,7 +447,7 @@ export class RichTextMenu extends AntimodeMenu { this.layoutDoc && (this.layoutDoc.layout_centered = !this.layoutDoc.layout_centered); }; align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => { - if (this.TextView?.props.rootSelected?.()) { + if (this.TextView?._props.rootSelected?.()) { var tr = view.state.tr; view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos, parent, index) => { if ([schema.nodes.paragraph, schema.nodes.heading].includes(node.type)) { @@ -581,7 +581,7 @@ export class RichTextMenu extends AntimodeMenu { return (this.view as any)?.TextView as FormattedTextBox; } get TextViewFieldKey() { - return this.TextView?.props.fieldKey; + return this.TextView?._props.fieldKey; } @action setActiveHighlight(color: string) { @@ -774,11 +774,11 @@ export class RichTextMenu extends AntimodeMenu { //
// {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => { // this.activeFontSize = val; - // SelectionManager.Views.map(dv => dv.props.Document._text_fontSize = val); + // SelectionManager.Views.map(dv => dv.Document._text_fontSize = val); // })), // this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family", action((val: string) => { // this.activeFontFamily = val; - // SelectionManager.Views.map(dv => dv.props.Document._text_fontFamily = val); + // SelectionManager.Views.map(dv => dv.Document._text_fontFamily = val); // })), //
, // this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", () => ({})), diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx index b573f7c48..1a92acea1 100644 --- a/src/client/views/nodes/importBox/ImportElementBox.tsx +++ b/src/client/views/nodes/importBox/ImportElementBox.tsx @@ -13,12 +13,12 @@ export class ImportElementBox extends ViewBoxBaseComponent() { return FieldView.LayoutString(ImportElementBox, fieldKey); } - screenToLocalXf = () => this.props.ScreenToLocalTransform().scale(1 * (this.props.NativeDimScaling?.() || 1)); + screenToLocalXf = () => this._props.ScreenToLocalTransform().scale(1 * (this._props.NativeDimScaling?.() || 1)); @computed get mainItem() { return (
Opt; } @observer -export class Annotation extends React.Component { +export class Annotation extends ObservableReactComponent { + constructor(props: any) { + super(props); + makeObservable(this); + } render() { return ( -
- {DocListCast(this.props.anno.text_inlineAnnotations).map(a => ( - +
+ {DocListCast(this._props.anno.text_inlineAnnotations).map(a => ( + ))}
); @@ -38,23 +43,23 @@ interface IRegionAnnotationProps extends IAnnotationProps { pointerEvents?: () => Opt; } @observer -class RegionAnnotation extends React.Component { +class RegionAnnotation extends ObservableReactComponent { private _mainCont: React.RefObject = React.createRef(); @computed get annoTextRegion() { - return Cast(this.props.document.annoTextRegion, Doc, null) || this.props.document; + return Cast(this._props.document.annoTextRegion, Doc, null) || this._props.document; } @undoBatch deleteAnnotation = () => { - const docAnnotations = DocListCast(this.props.dataDoc[this.props.fieldKey]); - this.props.dataDoc[this.props.fieldKey] = new List(docAnnotations.filter(a => a !== this.annoTextRegion)); + const docAnnotations = DocListCast(this._props.dataDoc[this._props.fieldKey]); + this._props.dataDoc[this._props.fieldKey] = new List(docAnnotations.filter(a => a !== this.annoTextRegion)); AnchorMenu.Instance.fadeOut(true); - this.props.select(false); + this._props.select(false); }; @undoBatch - pinToPres = () => this.props.pinToPres(this.annoTextRegion, {}); + pinToPres = () => this._props.pinToPres(this.annoTextRegion, {}); @undoBatch makeTargretToggle = () => (this.annoTextRegion.followLinkToggle = !this.annoTextRegion.followLinkToggle); @@ -65,7 +70,7 @@ class RegionAnnotation extends React.Component { const trail = DocCast(anchor.presentationTrail); if (trail) { Doc.ActivePresentation = trail; - this.props.addDocTab(trail, OpenWhere.replaceRight); + this._props.addDocTab(trail, OpenWhere.replaceRight); } }; @@ -94,9 +99,9 @@ class RegionAnnotation extends React.Component { }; @computed get linkHighlighted() { - for (const link of LinkManager.Instance.getAllDirectLinks(this.props.document)) { - const a1 = LinkManager.getOppositeAnchor(link, this.props.document); - if (a1 && Doc.GetBrushStatus(DocCast(a1.annotationOn, this.props.document))) return true; + for (const link of LinkManager.Instance.getAllDirectLinks(this._props.document)) { + const a1 = LinkManager.getOppositeAnchor(link, this._props.document); + if (a1 && Doc.GetBrushStatus(DocCast(a1.annotationOn, this._props.document))) return true; } } @@ -107,24 +112,24 @@ class RegionAnnotation extends React.Component { className="htmlAnnotation" ref={this._mainCont} onPointerEnter={action(() => { - Doc.BrushDoc(this.props.anno); - this.props.showInfo?.(this.props.anno); + Doc.BrushDoc(this._props.anno); + this._props.showInfo?.(this._props.anno); })} onPointerLeave={action(() => { - Doc.UnBrushDoc(this.props.anno); - this.props.showInfo?.(undefined); + Doc.UnBrushDoc(this._props.anno); + this._props.showInfo?.(undefined); })} onPointerDown={this.onPointerDown} onContextMenu={this.onContextMenu} style={{ - left: NumCast(this.props.document.x), - top: NumCast(this.props.document.y), - width: NumCast(this.props.document._width), - height: NumCast(this.props.document._height), + left: NumCast(this._props.document.x), + top: NumCast(this._props.document.y), + width: NumCast(this._props.document._width), + height: NumCast(this._props.document._height), opacity: brushed === Doc.DocBrushStatus.highlighted ? 0.5 : undefined, - pointerEvents: this.props.pointerEvents?.() as any, + pointerEvents: this._props.pointerEvents?.() as any, outline: brushed === Doc.DocBrushStatus.unbrushed && this.linkHighlighted ? 'solid 1px lightBlue' : undefined, - backgroundColor: brushed === Doc.DocBrushStatus.highlighted ? 'orange' : StrCast(this.props.document.backgroundColor), + backgroundColor: brushed === Doc.DocBrushStatus.highlighted ? 'orange' : StrCast(this._props.document.backgroundColor), }} /> ); diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 14187833f..4d29573d4 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -122,10 +122,10 @@ export class SearchBox extends ViewBoxBaseComponent() { @undoBatch makeLink = action((linkTo: Doc) => { - const linkFrom = this.props.linkCreateAnchor?.(); + const linkFrom = this._props.linkCreateAnchor?.(); if (linkFrom) { const link = DocUtils.MakeLink(linkFrom, linkTo, {}); - link && this.props.linkCreated?.(link); + link && this._props.linkCreated?.(link); } }); @@ -292,7 +292,7 @@ export class SearchBox extends ViewBoxBaseComponent() { const query = StrCast(this._searchString); Doc.SetSearchQuery(query); - if (!this.props.linkSearch) Array.from(this._results.keys()).forEach(doc => DocumentManager.Instance.getFirstDocumentView(doc)?.ComponentView?.search?.(this._searchString, undefined, true)); + if (!this._props.linkSearch) Array.from(this._results.keys()).forEach(doc => DocumentManager.Instance.getFirstDocumentView(doc)?.ComponentView?.search?.(this._searchString, undefined, true)); this._results.clear(); if (query) { @@ -375,13 +375,13 @@ export class SearchBox extends ViewBoxBaseComponent() { render() { var validResults = 0; - const isLinkSearch: boolean = this.props.linkSearch; + const isLinkSearch: boolean = this._props.linkSearch; const sortedResults = Array.from(this._results.entries()).sort((a, b) => (this._pageRanks.get(b[0]) ?? 0) - (this._pageRanks.get(a[0]) ?? 0)); // sorted by page rank const resultsJSX = Array(); - const fromDoc = this.props.linkFrom?.(); + const fromDoc = this._props.linkFrom?.(); sortedResults.forEach(result => { var className = 'searchBox-results-scroll-view-result'; diff --git a/src/client/views/selectedDoc/SelectedDocView.tsx b/src/client/views/selectedDoc/SelectedDocView.tsx index daacb368b..39e778b76 100644 --- a/src/client/views/selectedDoc/SelectedDocView.tsx +++ b/src/client/views/selectedDoc/SelectedDocView.tsx @@ -1,14 +1,14 @@ +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { ListBox } from 'browndash-components'; import { computed } from 'mobx'; import { observer } from 'mobx-react'; -import * as React from 'react'; -import { emptyFunction } from '../../../Utils'; import { Doc } from '../../../fields/Doc'; import { StrCast } from '../../../fields/Types'; import { DocumentManager } from '../../util/DocumentManager'; -import { SettingsManager } from '../../util/SettingsManager'; import { DocFocusOptions } from '../nodes/DocumentView'; +import { emptyFunction } from '../../../Utils'; +import { SettingsManager } from '../../util/SettingsManager'; export interface SelectedDocViewProps { selectedDocs: Doc[]; -- cgit v1.2.3-70-g09d2