diff options
author | bobzel <zzzman@gmail.com> | 2023-12-14 00:07:52 -0500 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2023-12-14 00:07:52 -0500 |
commit | cebe9d2a567c20b99c8c394cfa598ee9d4d53ece (patch) | |
tree | c33df9a3dc80cb199002610cc38645976023eff9 /src | |
parent | 1cf241544f8063e3d71406238a584299b6ced794 (diff) |
a bunch more fixes to making things observable. fixed calling super.componentDidUpdate on subsclasses
Diffstat (limited to 'src')
76 files changed, 224 insertions, 1126 deletions
diff --git a/src/Utils.ts b/src/Utils.ts index 3a2bbf9a1..5f9475f23 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -7,7 +7,7 @@ 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, makeObservable } from 'mobx'; +import { action } from 'mobx'; export namespace Utils { export let CLICK_TIME = 300; @@ -56,10 +56,6 @@ export namespace Utils { return uuid.v5(seed, uuid.v5.URL); } - export function GenerateMongoId(id: string): string { - return id.length !== 36 ? Utils.GenerateDeterministicGuid(id) : id; - } - export function GuestID() { return '__guest__'; } @@ -440,17 +436,6 @@ export namespace Utils { socket.on(message, (room: any) => handler(socket, room)); } } -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 - thing._prevProps = thing.props; -} export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc?: (dup: any) => void): { omit: any; extract: any } { const omit: any = { ...obj }; diff --git a/src/client/util/BranchingTrailManager.tsx b/src/client/util/BranchingTrailManager.tsx index a224b84f4..11f16493f 100644 --- a/src/client/util/BranchingTrailManager.tsx +++ b/src/client/util/BranchingTrailManager.tsx @@ -1,4 +1,4 @@ -import { action, computed, observable } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc } from '../../fields/Doc'; @@ -15,13 +15,14 @@ export class BranchingTrailManager extends React.Component { constructor(props: any) { super(props); + makeObservable(this); if (!BranchingTrailManager.Instance) { BranchingTrailManager.Instance = this; } } setupUi = () => { - OverlayView.Instance.addWindow(<BranchingTrailManager></BranchingTrailManager>, { x: 100, y: 150, width: 1000, title: 'Branching Trail'}); + OverlayView.Instance.addWindow(<BranchingTrailManager></BranchingTrailManager>, { x: 100, y: 150, width: 1000, title: 'Branching Trail' }); // OverlayView.Instance.forceUpdate(); console.log(OverlayView.Instance); // let hi = Docs.Create.TextDocument("beee", { @@ -30,11 +31,10 @@ export class BranchingTrailManager extends React.Component { // }) // hi.overlayX = 100; // hi.overlayY = 100; - + // Doc.AddToMyOverlay(hi); console.log(DocumentManager._overlayViews); }; - // stack of the history @observable private slideHistoryStack: String[] = []; @@ -69,7 +69,7 @@ export class BranchingTrailManager extends React.Component { if (this.prevPresId === null || this.prevPresId !== presId) { Doc.UserDoc().isBranchingMode = true; this.setPrevPres(presId); - + // REVERT THE SET const stringified = [presId, targetDocId].toString(); if (this.containsSet.has([presId, targetDocId].toString())) { @@ -98,7 +98,7 @@ export class BranchingTrailManager extends React.Component { const newStack = this.slideHistoryStack.slice(0, removeIndex); const removed = this.slideHistoryStack.slice(removeIndex); - + this.setSlideHistoryStack(newStack); removed.forEach(info => this.containsSet.delete(info.toString())); diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx index 271cf7495..071fc1ee9 100644 --- a/src/client/util/CaptureManager.tsx +++ b/src/client/util/CaptureManager.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc } from '../../fields/Doc'; @@ -20,6 +20,7 @@ export class CaptureManager extends React.Component<{}> { constructor(props: {}) { super(props); + makeObservable(this); CaptureManager.Instance = this; } diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx index c8c93b7d0..90f65b648 100644 --- a/src/client/util/GroupManager.tsx +++ b/src/client/util/GroupManager.tsx @@ -1,6 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button, IconButton, Size, Type } from 'browndash-components'; -import { action, computed, observable } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import Select from 'react-select'; @@ -17,6 +17,7 @@ import './GroupManager.scss'; import { GroupMemberView } from './GroupMemberView'; import { SettingsManager } from './SettingsManager'; import { SharingManager, User } from './SharingManager'; +import { ObservableReactComponent } from '../views/ObservableReactComponent'; /** * Interface for options for the react-select component @@ -27,7 +28,7 @@ export interface UserOptions { } @observer -export class GroupManager extends React.Component<{}> { +export class GroupManager extends ObservableReactComponent<{}> { static Instance: GroupManager; @observable isOpen: boolean = false; // whether the GroupManager is to be displayed or not. @observable private users: string[] = []; // list of users populated from the database. @@ -41,6 +42,7 @@ export class GroupManager extends React.Component<{}> { constructor(props: Readonly<{}>) { super(props); + makeObservable(this); GroupManager.Instance = this; } diff --git a/src/client/util/PingManager.ts b/src/client/util/PingManager.ts index 4dd2fcd35..865f8bc02 100644 --- a/src/client/util/PingManager.ts +++ b/src/client/util/PingManager.ts @@ -1,4 +1,4 @@ -import { action, observable, runInAction } from 'mobx'; +import { action, makeObservable, observable, runInAction } from 'mobx'; import { Networking } from '../Network'; import { CurrentUserUtils } from './CurrentUserUtils'; export class PingManager { @@ -33,6 +33,7 @@ export class PingManager { private _interval: NodeJS.Timeout | null = null; INTERVAL_SECONDS = 1; constructor() { + makeObservable(this); PingManager._instance = this; this._interval = setInterval(this.sendPing, this.INTERVAL_SECONDS * 1000); } diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx index 495af6abd..f96d8a5df 100644 --- a/src/client/util/RTFMarkup.tsx +++ b/src/client/util/RTFMarkup.tsx @@ -1,4 +1,4 @@ -import { action, computed, observable } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { MainViewModal } from '../views/MainViewModal'; @@ -23,6 +23,7 @@ export class RTFMarkup extends React.Component<{}> { constructor(props: {}) { super(props); + makeObservable(this); RTFMarkup.Instance = this; } diff --git a/src/client/util/ReplayMovements.ts b/src/client/util/ReplayMovements.ts index d99630f82..b881f18b4 100644 --- a/src/client/util/ReplayMovements.ts +++ b/src/client/util/ReplayMovements.ts @@ -1,4 +1,4 @@ -import { IReactionDisposer, observable, reaction } from 'mobx'; +import { IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { Doc, IdToDoc } from '../../fields/Doc'; import { CollectionDockingView } from '../views/collections/CollectionDockingView'; import { CollectionFreeFormView } from '../views/collections/collectionFreeForm'; @@ -19,6 +19,7 @@ export class ReplayMovements { return ReplayMovements._instance; } constructor() { + makeObservable(this); // init the global instance ReplayMovements._instance = this; diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 4bd6647c0..07bbde36c 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -31,8 +31,7 @@ export class SelectionManager { this.Instance.SelectedSchemaDocument = doc; }; - @action - public static SelectView = (docView: DocumentView | undefined, extendSelection: boolean): void => { + public static SelectView = action((docView: DocumentView | undefined, extendSelection: boolean): void => { if (!docView) this.DeselectAll(); else if (!docView.SELECTED) { if (!extendSelection) this.DeselectAll(); @@ -40,16 +39,15 @@ export class SelectionManager { docView.SELECTED = true; docView._props.whenChildContentsActiveChanged(true); } - }; + }); - @action - public static DeselectView = (docView?: DocumentView): void => { + public static DeselectView = action((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); } - }; + }); public static DeselectAll = (except?: Doc): void => { const found = this.Instance.SelectedViews.find(dv => dv.Document === except); diff --git a/src/client/util/ServerStats.tsx b/src/client/util/ServerStats.tsx index 7d5e0458d..c8df9182d 100644 --- a/src/client/util/ServerStats.tsx +++ b/src/client/util/ServerStats.tsx @@ -1,4 +1,4 @@ -import { action, computed, observable } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { MainViewModal } from '../views/MainViewModal'; @@ -33,6 +33,7 @@ export class ServerStats extends React.Component<{}> { constructor(props: {}) { super(props); + makeObservable(this); ServerStats.Instance = this; } diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 7176b568e..ac7de9872 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button, IconButton, Size, Type } from 'browndash-components'; import { concat, intersection } from 'lodash'; -import { action, computed, observable, runInAction } from 'mobx'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import Select from 'react-select'; @@ -119,6 +119,7 @@ export class SharingManager extends React.Component<{}> { constructor(props: {}) { super(props); + makeObservable(this); SharingManager.Instance = this; } diff --git a/src/client/util/TrackMovements.ts b/src/client/util/TrackMovements.ts index 0e56ee1bc..0b197cf9a 100644 --- a/src/client/util/TrackMovements.ts +++ b/src/client/util/TrackMovements.ts @@ -1,4 +1,4 @@ -import { IReactionDisposer, observable, observe, reaction } from 'mobx'; +import { IReactionDisposer, makeObservable, observable, observe, reaction } from 'mobx'; import { NumCast } from '../../fields/Types'; import { Doc, DocListCast } from '../../fields/Doc'; import { CollectionDockingView } from '../views/collections/CollectionDockingView'; @@ -40,7 +40,7 @@ export class TrackMovements { constructor() { // init the global instance TrackMovements._instance = this; - + makeObservable(this); // init the instance variables this.currentPresentation = TrackMovements.NULL_PRESENTATION; this.tracking = false; diff --git a/src/client/util/reportManager/ReportManager.tsx b/src/client/util/reportManager/ReportManager.tsx index 738902a31..0c49aeed4 100644 --- a/src/client/util/reportManager/ReportManager.tsx +++ b/src/client/util/reportManager/ReportManager.tsx @@ -3,7 +3,7 @@ import * as uuid from 'uuid'; import '.././SettingsManager.scss'; import './ReportManager.scss'; import ReactLoading from 'react-loading'; -import { action, observable } from 'mobx'; +import { action, makeObservable, observable } from 'mobx'; import { BsX, BsArrowsAngleExpand, BsArrowsAngleContract } from 'react-icons/bs'; import { CgClose } from 'react-icons/cg'; import { HiOutlineArrowLeft } from 'react-icons/hi'; @@ -103,6 +103,7 @@ export class ReportManager extends React.Component<{}> { constructor(props: {}) { super(props); + makeObservable(this); ReportManager.Instance = this; // initializing Github connection diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index e55bf24a1..8dcdd80e5 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -37,8 +37,8 @@ export class ContextMenu extends ObservableReactComponent<{}> { constructor(props: any) { super(props); - ContextMenu.Instance = this; makeObservable(this); + ContextMenu.Instance = this; } public setIgnoreEvents(ignore: boolean) { diff --git a/src/client/views/DictationOverlay.tsx b/src/client/views/DictationOverlay.tsx index 0bdcdc303..e098bc361 100644 --- a/src/client/views/DictationOverlay.tsx +++ b/src/client/views/DictationOverlay.tsx @@ -1,4 +1,4 @@ -import { computed, observable, runInAction } from 'mobx'; +import { computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { DictationManager } from '../util/DictationManager'; @@ -19,6 +19,7 @@ export class DictationOverlay extends React.Component { constructor(props: any) { super(props); + makeObservable(this); DictationOverlay.Instance = this; } diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 50ca3af06..47829d12a 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -3,32 +3,26 @@ 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 { emptyFunction, returnFalse, setupMoveUpEvents, simulateMouseClick } from '../../Utils'; import { Doc } from '../../fields/Doc'; import { RichTextField } from '../../fields/RichTextField'; -import { Cast, DocCast, NumCast } from '../../fields/Types'; -import { emptyFunction, returnFalse, setupMoveUpEvents, simulateMouseClick } from '../../Utils'; -import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager'; -import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils'; -import { Docs, DocUtils } from '../documents/Documents'; +import { Cast, DocCast } from '../../fields/Types'; +import { DocUtils } from '../documents/Documents'; import { DragManager } from '../util/DragManager'; import { IsFollowLinkScript } from '../util/LinkFollower'; import { SelectionManager } from '../util/SelectionManager'; import { SharingManager } from '../util/SharingManager'; -import { undoBatch, UndoManager } from '../util/UndoManager'; -import { CollectionDockingView } from './collections/CollectionDockingView'; -import { TabDocView } from './collections/TabDocView'; +import { UndoManager, undoBatch } from '../util/UndoManager'; import './DocumentButtonBar.scss'; +import { ObservableReactComponent } from './ObservableReactComponent'; +import { TabDocView } from './collections/TabDocView'; import { Colors } from './global/globalEnums'; import { LinkPopup } from './linking/LinkPopup'; -import { MetadataEntryMenu } from './MetadataEntryMenu'; import { DocumentLinksButton } from './nodes/DocumentLinksButton'; -import { DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod } from './nodes/DocumentView'; +import { DocumentView, DocumentViewInternal, OpenWhere } from './nodes/DocumentView'; import { DashFieldView } from './nodes/formattedText/DashFieldView'; -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; @@ -60,10 +54,10 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( public static hasPushedHack = false; public static hasPulledHack = false; - constructor(props: { views: () => (DocumentView | undefined)[] }) { + constructor(props: any) { super(props); - DocumentButtonBar.Instance = this; makeObservable(this); + DocumentButtonBar.Instance = this; } public startPullOutcome = action((success: boolean) => { @@ -115,103 +109,6 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( return this._props.views()?.[0]; } - @computed - get considerGoogleDocsPush() { - const targetDoc = this.view0?.Document; - const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined; - const animation = this.isAnimatingPulse ? 'shadow-pulse 1s linear infinite' : 'none'; - return !targetDoc ? null : ( - <Tooltip - title={ - <> - <div className="dash-tooltip">{`${published ? 'Push' : 'Publish'} to Google Docs`}</div> - </> - }> - <div - className="documentButtonBar-button" - style={{ animation }} - onClick={async () => { - await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(); - !published && runInAction(() => (this.isAnimatingPulse = true)); - DocumentButtonBar.hasPushedHack = false; - targetDoc[Pushes] = NumCast(targetDoc[Pushes]) + 1; - }}> - <FontAwesomeIcon className="documentdecorations-icon" icon={published ? (this.pushIcon as any) : cloud} size={published ? 'sm' : 'xs'} /> - </div> - </Tooltip> - ); - } - - @computed - get considerGoogleDocsPull() { - const targetDoc = this.view0?.Document; - const dataDoc = targetDoc && Doc.GetProto(targetDoc); - const animation = this.isAnimatingFetch ? 'spin 0.5s linear infinite' : 'none'; - - const title = (() => { - switch (this.openHover) { - default: - case UtilityButtonState.Default: - return `${!dataDoc?.googleDocUnchanged ? 'Pull from' : 'Fetch'} Google Docs`; - case UtilityButtonState.OpenRight: - return 'Open in Right Split'; - case UtilityButtonState.OpenExternally: - return 'Open in new Browser Tab'; - } - })(); - - return !targetDoc || !dataDoc || !dataDoc[GoogleRef] ? null : ( - <Tooltip title={<div className="dash-tooltip">{title}</div>}> - <div - className="documentButtonBar-button" - style={{ backgroundColor: this.pullColor }} - onPointerEnter={action(e => { - if (e.altKey) { - this.openHover = UtilityButtonState.OpenExternally; - } else if (e.shiftKey) { - this.openHover = UtilityButtonState.OpenRight; - } - })} - onPointerLeave={action(() => (this.openHover = UtilityButtonState.Default))} - onClick={async e => { - const googleDocUrl = `https://docs.google.com/document/d/${dataDoc[GoogleRef]}/edit`; - if (e.shiftKey) { - e.preventDefault(); - let googleDoc = await Cast(dataDoc.googleDoc, Doc); - if (!googleDoc) { - const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, data_useCors: false }; - googleDoc = Docs.Create.WebDocument(googleDocUrl, options); - dataDoc.googleDoc = googleDoc; - } - CollectionDockingView.AddSplit(googleDoc, OpenWhereMod.right); - } else if (e.altKey) { - e.preventDefault(); - window.open(googleDocUrl); - } else { - this.clearPullColor(); - DocumentButtonBar.hasPulledHack = false; - targetDoc[Pulls] = NumCast(targetDoc[Pulls]) + 1; - dataDoc.googleDocUnchanged && runInAction(() => (this.isAnimatingFetch = true)); - } - }}> - <FontAwesomeIcon - className="documentdecorations-icon" - size="sm" - style={{ WebkitAnimation: animation, MozAnimation: animation }} - icon={(() => { - // prettier-ignore - switch (this.openHover) { - default: - case UtilityButtonState.Default: return dataDoc.googleDocUnchanged === false ? (this.pullIcon as any) : fetch; - case UtilityButtonState.OpenRight: return 'arrow-alt-circle-right'; - case UtilityButtonState.OpenExternally: return 'share'; - } - })()} - /> - </div> - </Tooltip> - ); - } @observable subFollow = ''; @computed get followLinkButton() { @@ -579,8 +476,6 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( if (!doc || !this.view0) return null; const isText = () => doc[this.view0!.LayoutFieldKey] instanceof RichTextField; - const considerPull = () => isText() && this.considerGoogleDocsPull; - const considerPush = () => isText() && this.considerGoogleDocsPush; return ( <div className="documentButtonBar"> <div className="documentButtonBar-button"> @@ -608,14 +503,6 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( <div className="documentButtonBar-button">{this.pinButton}</div> <div className="documentButtonBar-button">{this.recordButton}</div> {!Doc.UserDoc()['documentLinksButton-fullMenu'] ? null : <div className="documentButtonBar-button">{this.shareButton}</div>} - {!Doc.UserDoc()['documentLinksButton-fullMenu'] ? null : ( - <div className="documentButtonBar-button" style={{ display: !considerPush() ? 'none' : '' }}> - {this.considerGoogleDocsPush} - </div> - )} - <div className="documentButtonBar-button" style={{ display: !considerPull() ? 'none' : '' }}> - {this.considerGoogleDocsPull} - </div> <div className="documentButtonBar-button">{this.menuButton}</div> </div> ); diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 836a184eb..73ac1b032 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -94,6 +94,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> { } componentDidUpdate(prevProps: Readonly<EditableProps>) { + super.componentDidUpdate(prevProps); 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/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 214da5541..33cda6a62 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import * as fitCurve from 'fit-curve'; -import { action, computed, observable, runInAction } from 'mobx'; +import { action, computed, makeObservable, observable, runInAction, toJS } from 'mobx'; import { observer } from 'mobx-react'; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils'; import { Doc, Opt } from '../../fields/Doc'; @@ -31,12 +31,13 @@ import { } from './InkingStroke'; import { checkInksToGroup } from './global/globalScripts'; import { DocumentView } from './nodes/DocumentView'; +import { ObservableReactComponent } from './ObservableReactComponent'; interface GestureOverlayProps { isActive: boolean; } @observer -export class GestureOverlay extends React.Component<React.PropsWithChildren<GestureOverlayProps>> { +export class GestureOverlay extends ObservableReactComponent<React.PropsWithChildren<GestureOverlayProps>> { static Instance: GestureOverlay; static Instances: GestureOverlay[] = []; @@ -84,7 +85,7 @@ export class GestureOverlay extends React.Component<React.PropsWithChildren<Gest constructor(props: any) { super(props); - + makeObservable(this); GestureOverlay.Instances.push(this); } @@ -92,9 +93,9 @@ export class GestureOverlay extends React.Component<React.PropsWithChildren<Gest GestureOverlay.Instances.splice(GestureOverlay.Instances.indexOf(this), 1); GestureOverlay.Instance = GestureOverlay.Instances.lastElement(); } - componentDidMount = () => { + componentDidMount() { GestureOverlay.Instance = this; - }; + } @action onPointerDown = (e: React.PointerEvent) => { @@ -383,9 +384,9 @@ export class GestureOverlay extends React.Component<React.PropsWithChildren<Gest return GestureOverlay.getBounds(this._points); } - @computed get elements() { + get elements() { const selView = GestureOverlay.DownDocView; - const width = Number(ActiveInkWidth()) * NumCast(selView?.Document._freeform_scale, 1); // * (selView?.props.ScreenToLocalTransform().Scale || 1); + const width = Number(ActiveInkWidth()) * NumCast(selView?.Document._freeform_scale, 1); // * (selView?._props.ScreenToLocalTransform().Scale || 1); const rect = this._overlayRef.current?.getBoundingClientRect(); const B = { left: -20000, right: 20000, top: -20000, bottom: 20000, width: 40000, height: 40000 }; //this.getBounds(this._points, true); B.left = B.left - width / 2; @@ -499,7 +500,7 @@ export class GestureOverlay extends React.Component<React.PropsWithChildren<Gest render() { return ( - <div className="gestureOverlay-cont" style={{ pointerEvents: this.props.isActive ? 'all' : 'none' }} ref={this._overlayRef} onPointerDown={this.onPointerDown}> + <div className="gestureOverlay-cont" style={{ pointerEvents: this._props.isActive ? 'all' : 'none' }} ref={this._overlayRef} onPointerDown={this.onPointerDown}> {this.showMobileInkOverlay ? <MobileInkOverlay /> : null} {this.elements} diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index 884c74f9b..69c663a3e 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -1,5 +1,5 @@ import { Bezier } from 'bezier-js'; -import { action, observable, reaction } from 'mobx'; +import { action, makeObservable, observable, reaction } from 'mobx'; import { Doc, NumListCast, Opt } from '../../fields/Doc'; import { InkData, InkField, InkTool, PointData } from '../../fields/InkField'; import { List } from '../../fields/List'; @@ -25,6 +25,7 @@ export class InkStrokeProperties { constructor() { InkStrokeProperties._Instance = this; + makeObservable(this); reaction( () => this._controlButton, button => button && (Doc.ActiveTool = InkTool.None) diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index de2ce3189..98d1e58e5 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -1,7 +1,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Toggle, ToggleType, Type } from 'browndash-components'; -import { action, computed, observable, runInAction } from 'mobx'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, FieldResult, Opt } from '../../fields/Doc'; @@ -56,6 +56,7 @@ export class LightboxView extends React.Component<LightboxViewProps> { constructor(props: any) { super(props); + makeObservable(this); if (LightboxView.Instance) console.log('SDFSFASFASFSALFKJD:SLFJS:LDFJKS:LFJS:LDJFL:SDFJL:SDJF:LSJ'); LightboxView.Instance = this; } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index f65675792..636f8761f 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -230,7 +230,7 @@ export class MainView extends ObservableReactComponent<{}> { document.removeEventListener('linkAnnotationToDash', Hypothesis.linkListener); } - constructor(props: Readonly<{}>) { + constructor(props: any) { super(props); makeObservable(this); DocumentViewInternal.addDocTabFunc = MainView.addDocTabFunc_impl; diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index 2e27d1f70..285476b14 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -6,7 +6,7 @@ import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocData } from '../../field import { List } from '../../fields/List'; import { NumCast } from '../../fields/Types'; import { GetEffectiveAcl } from '../../fields/util'; -import { copyProps, unimplementedFunction, Utils } from '../../Utils'; +import { unimplementedFunction, Utils } from '../../Utils'; import { Docs, DocUtils } from '../documents/Documents'; import { DragManager } from '../util/DragManager'; import { FollowLinkScript } from '../util/LinkFollower'; diff --git a/src/client/views/ObservableReactComponent.tsx b/src/client/views/ObservableReactComponent.tsx index 2d8dc9af9..9b2b00903 100644 --- a/src/client/views/ObservableReactComponent.tsx +++ b/src/client/views/ObservableReactComponent.tsx @@ -1,8 +1,6 @@ -import { makeObservable, observable } from 'mobx'; +import { action, 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 @@ -10,12 +8,14 @@ export interface AntimodeMenuProps {} */ export abstract class ObservableReactComponent<T> extends React.Component<T, {}> { @observable _props: React.PropsWithChildren<T>; - constructor(props: React.PropsWithChildren<T>) { + constructor(props: any) { super(props); this._props = props; makeObservable(this); } componentDidUpdate(prevProps: Readonly<T>): void { - copyProps(this, prevProps); + Object.keys(prevProps).forEach(action(pkey => + (prevProps as any)[pkey] !== (this.props as any)[pkey] && + ((this._props as any)[pkey] = (this.props as any)[pkey]))); // prettier-ignore } } diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index c857c2d6b..2fcb5d12a 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -54,7 +54,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps private _widthUndo?: UndoManager.Batch; public static Instance: PropertiesView | undefined; - constructor(props: React.PropsWithChildren<PropertiesViewProps>) { + constructor(props: any) { super(props); makeObservable(this); PropertiesView.Instance = this; diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx index 416162aeb..086f40e96 100644 --- a/src/client/views/ScriptBox.tsx +++ b/src/client/views/ScriptBox.tsx @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, Opt } from '../../fields/Doc'; @@ -27,6 +27,7 @@ export class ScriptBox extends React.Component<ScriptBoxProps> { constructor(props: ScriptBoxProps) { super(props); + makeObservable(this); this._scriptText = props.initialText || ''; } diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx index 5f20bc745..acf0ecff4 100644 --- a/src/client/views/ScriptingRepl.tsx +++ b/src/client/views/ScriptingRepl.tsx @@ -35,13 +35,11 @@ export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps> const val = this._props.value; const proto = Object.getPrototypeOf(val); const name = (proto && proto.constructor && proto.constructor.name) || String(val); - const title = this._props.name ? ( + const title = ( <> - <b>{this._props.name} : </b> + {this.props.name ? <b>{this._props.name} : </b> : <></>} {name} </> - ) : ( - name ); if (this.collapsed) { return ( @@ -86,31 +84,19 @@ export class ScriptingValueDisplay extends ObservableReactComponent<replValuePro render() { const val = this._props.name ? this._props.value[this._props.name] : this._props.value; + const title = (name: string) => ( + <> + {this._props.name ? <b>{this._props.name} : </b> : <> </>} + {name} + </> + ); if (typeof val === 'object') { return <ScriptingObjectDisplay scrollToBottom={this._props.scrollToBottom} value={val} name={this._props.name} />; } else if (typeof val === 'function') { const name = '[Function]'; - const title = this._props.name ? ( - <> - <b>{this._props.name} : </b> - {name} - </> - ) : ( - name - ); - return <div className="scriptingObject-leaf">{title}</div>; - } else { - const name = String(val); - const title = this._props.name ? ( - <> - <b>{this._props.name} : </b> - {name} - </> - ) : ( - name - ); - return <div className="scriptingObject-leaf">{title}</div>; + return <div className="scriptingObject-leaf">{title('[Function]')}</div>; } + return <div className="scriptingObject-leaf">{title(String(val))}</div>; } } @@ -254,7 +240,8 @@ export class ScriptingRepl extends ObservableReactComponent<{}> { ele && ele.scroll({ behavior: 'auto', top: ele.scrollHeight }); } - componentDidUpdate() { + componentDidUpdate(prevProps: Readonly<{}>) { + super.componentDidUpdate(prevProps); if (this.shouldScroll) { this.shouldScroll = false; this.scrollToBottom(); diff --git a/src/client/views/animationtimeline/Region.tsx b/src/client/views/animationtimeline/Region.tsx index abbc8203d..b09456cd7 100644 --- a/src/client/views/animationtimeline/Region.tsx +++ b/src/client/views/animationtimeline/Region.tsx @@ -1,4 +1,4 @@ -import { action, computed, observable, runInAction } from 'mobx'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; @@ -185,6 +185,7 @@ export class Region extends React.Component<IProps> { constructor(props: any) { super(props); + makeObservable(this); } componentDidMount() { setTimeout(() => { diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx index 1769c41bd..97a571dc4 100644 --- a/src/client/views/animationtimeline/TimelineMenu.tsx +++ b/src/client/views/animationtimeline/TimelineMenu.tsx @@ -1,7 +1,7 @@ import { IconLookup } from '@fortawesome/fontawesome-svg-core'; import { faChartLine, faClipboard } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, observable } from 'mobx'; +import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Utils } from '../../../Utils'; @@ -16,8 +16,9 @@ export class TimelineMenu extends React.Component { @observable private _y = 0; @observable private _currentMenu: JSX.Element[] = []; - constructor(props: Readonly<{}>) { + constructor(props: any) { super(props); + makeObservable(this); TimelineMenu.Instance = this; } diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 0d3ff8bba..97d5cfc70 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -63,10 +63,10 @@ export class CollectionDockingView extends CollectionSubView() { private _goldenLayout: any = null; static _highlightStyleSheet: any = addStyleSheet(); - constructor(props: SubCollectionViewProps) { + constructor(props: any) { super(props); makeObservable(this); - if (this._props.renderDepth < 0) runInAction(() => (CollectionDockingView.Instance = this)); + if (this._props.renderDepth < 0) CollectionDockingView.Instance = this; //Why is this here? (window as any).React = React; (window as any).ReactDOM = ReactDOM; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 3ade2ab56..443aa3f17 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -2,14 +2,14 @@ import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { Toggle, ToggleType, Type } from 'browndash-components'; -import { action, computed, Lambda, observable, reaction, runInAction } from 'mobx'; +import { action, computed, Lambda, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; 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 { copyProps, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../../Utils'; +import { 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'; @@ -40,10 +40,11 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { constructor(props: any) { super(props); + makeObservable(this); this.FieldKey = ''; CollectionMenu.Instance = this; this._canFade = false; // don't let the inking menu fade away - runInAction(() => (this.Pinned = Cast(Doc.UserDoc()['menuCollections-pinned'], 'boolean', true))); + this.Pinned = Cast(Doc.UserDoc()['menuCollections-pinned'], 'boolean', true); this.jumpTo(300, 300); } diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index d37a942d0..fb8bc4da2 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -54,7 +54,7 @@ export enum TrimScope { } @observer -export class CollectionStackedTimeline extends CollectionSubView<SubCollectionViewProps & CollectionStackedTimelineProps>() { +export class CollectionStackedTimeline extends CollectionSubView<CollectionStackedTimelineProps>() { @observable static SelectingRegion: CollectionStackedTimeline | undefined = undefined; @observable public static CurrentlyPlaying: DocumentView[]; constructor(props: any) { @@ -695,7 +695,7 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch _lastTimecode: number; _disposer: IReactionDisposer | undefined; - constructor(props: React.PropsWithChildren<StackedTimelineAnchorProps>) { + constructor(props: any) { super(props); makeObservable(this); this._lastTimecode = this._props.currentTimecode(); diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 2302bfbc3..f9d575da2 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -58,7 +58,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< @observable _heading = ''; @observable _color = ''; - constructor(props: CSVFieldColumnProps) { + constructor(props: any) { super(props); makeObservable(this); this._heading = this._props.headingObject ? this._props.headingObject.heading : this._props.heading; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index f1ef52e60..0673b264b 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -121,7 +121,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab switch (type) { default: case CollectionViewType.Freeform: return <CollectionFreeFormView key="collview" {...props} />; - case CollectionViewType.Docking: return <CollectionDockingView key="collview" {...props} />; case CollectionViewType.Schema: return <CollectionSchemaView key="collview" {...props} />; case CollectionViewType.Docking: return <CollectionDockingView key="collview" {...props} />; case CollectionViewType.Tree: return <CollectionTreeView key="collview" {...props} />; diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 2eb13fd2f..783817b06 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -340,6 +340,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> { runInAction(() => TabDocView._allTabs.add(this)); } componentDidUpdate(prevProps: Readonly<TabDocViewProps>) { + super.componentDidUpdate(prevProps); this._view && DocumentManager.Instance.AddView(this._view); } diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 52ecdfbec..a7705ea7e 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -296,6 +296,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { } componentDidUpdate(prevProps: Readonly<TreeViewProps>) { + super.componentDidUpdate(prevProps); 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 0d5fcdaeb..66aa29de0 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx @@ -3,7 +3,6 @@ import { observer } from 'mobx-react'; import * as React from 'react'; 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. @@ -83,7 +82,7 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec this.initState(); } componentDidUpdate(prevProps: Readonly<CollectionFreeFormInfoStateProps>) { - copyProps(this, prevProps); + super.componentDidUpdate(prevProps); this.clearState(); this.initState(); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx index 4d3752c02..5637f9aeb 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx @@ -18,23 +18,19 @@ export interface CollectionFreeFormInfoUIProps { export class CollectionFreeFormInfoUI extends ObservableReactComponent<CollectionFreeFormInfoUIProps> { private _disposers: { [name: string]: IReactionDisposer } = {}; - @observable _currState: infoState | undefined = undefined; - get currState() { - return this._currState!; - } - set currState(val) { - this._currState = val; - } - constructor(props: any) { super(props); makeObservable(this); this.currState = this.setupStates(); } + @observable _currState: infoState | undefined = undefined; + get currState() { return this._currState!; } // prettier-ignore + set currState(val) { runInAction(() => (this._currState = val)); } // prettier-ignore + setCurrState = (state: infoState) => { if (state) { - runInAction(() => (this.currState = state)); + this.currState = state; this.currState[StateEntryFunc]?.(); } }; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index 7aa68b0d9..79cc534dc 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -1,6 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IconButton } from 'browndash-components'; -import { computed } from 'mobx'; +import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { unimplementedFunction } from '../../../../Utils'; @@ -18,8 +18,9 @@ export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> { public hideMarquee: () => void = unimplementedFunction; public pinWithView: (e: KeyboardEvent | React.PointerEvent | undefined) => void = unimplementedFunction; public isShown = () => this._opacity > 0; - constructor(props: Readonly<{}>) { + constructor(props: any) { super(props); + makeObservable(this); MarqueeOptionsMenu.Instance = this; } diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index b951a4b17..9132c0436 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -127,7 +127,7 @@ export class CollectionMulticolumnView extends CollectionSubView() { private get totalRatioAllocation(): number | undefined { const layoutInfoLen = this.resolvedLayoutInformation.widthSpecifiers.length; if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) { - return this.props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)) - 2 * NumCast(this.props.Document._xMargin); + return this._props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)) - 2 * NumCast(this._props.Document._xMargin); } } @@ -189,7 +189,7 @@ export class CollectionMulticolumnView extends CollectionSubView() { let offset = 0; for (const { layout: candidate } of this.childLayoutPairs) { if (candidate === layout) { - return this.props.ScreenToLocalTransform().translate(-offset / (this.props.NativeDimScaling?.() || 1), 0); + return this._props.ScreenToLocalTransform().translate(-offset / (this._props.NativeDimScaling?.() || 1), 0); } offset += this.lookupPixels(candidate) + resizerWidth; } @@ -223,8 +223,8 @@ export class CollectionMulticolumnView extends CollectionSubView() { if (this.childDocs.includes(d)) { if (dropInd > this.childDocs.indexOf(d)) dropInd--; } - Doc.RemoveDocFromList(this.dataDoc, this.props.fieldKey, d); - Doc.AddDocToList(this.dataDoc, this.props.fieldKey, d, DocListCast(this.dataDoc[this.props.fieldKey])[dropInd], undefined, dropInd === -1); + Doc.RemoveDocFromList(this.dataDoc, this._props.fieldKey, d); + Doc.AddDocToList(this.dataDoc, this._props.fieldKey, d, DocListCast(this.dataDoc[this._props.fieldKey])[dropInd], undefined, dropInd === -1); } }) ); @@ -237,56 +237,56 @@ export class CollectionMulticolumnView extends CollectionSubView() { onChildClickHandler = () => ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => ScriptCast(this.Document.onChildDoubleClick); - isContentActive = () => this.props.isSelected() || this.props.isContentActive() || this.props.isAnyChildContentActive(); + isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive(); isChildContentActive = () => { - const childDocsActive = this.props.childDocumentsActive?.() ?? this.Document.childDocumentsActive; - return this.props.isContentActive?.() === false || childDocsActive === false + const childDocsActive = this._props.childDocumentsActive?.() ?? this.Document.childDocumentsActive; + return this._props.isContentActive?.() === false || childDocsActive === false ? false // - : this.props.isDocumentActive?.() && childDocsActive + : this._props.isDocumentActive?.() && childDocsActive ? true : undefined; }; getDisplayDoc = (childLayout: Doc) => { const width = () => this.lookupPixels(childLayout); - const height = () => this.props.PanelHeight() - 2 * NumCast(this.layoutDoc._yMargin) - (BoolCast(this.layoutDoc.showWidthLabels) ? 20 : 0); + const height = () => this._props.PanelHeight() - 2 * NumCast(this.layoutDoc._yMargin) - (BoolCast(this.layoutDoc.showWidthLabels) ? 20 : 0); const dxf = () => this.lookupIndividualTransform(childLayout) .translate(-NumCast(this.layoutDoc._xMargin), -NumCast(this.layoutDoc._yMargin)) - .scale(this.props.NativeDimScaling?.() || 1); - const shouldNotScale = () => this.props.fitContentsToBox?.() || BoolCast(childLayout.freeform_fitContentsToBox); + .scale(this._props.NativeDimScaling?.() || 1); + const shouldNotScale = () => this._props.fitContentsToBox?.() || BoolCast(childLayout.freeform_fitContentsToBox); return ( <DocumentView Document={childLayout} TemplateDataDocument={childLayout.resolvedDataDoc as Doc} - styleProvider={this.props.styleProvider} - docViewPath={this.props.docViewPath} - LayoutTemplate={this.props.childLayoutTemplate} - LayoutTemplateString={this.props.childLayoutString} - renderDepth={this.props.renderDepth + 1} + styleProvider={this._props.styleProvider} + docViewPath={this._props.docViewPath} + LayoutTemplate={this._props.childLayoutTemplate} + LayoutTemplateString={this._props.childLayoutString} + renderDepth={this._props.renderDepth + 1} PanelWidth={width} PanelHeight={height} rootSelected={this.rootSelected} - dragAction={(this.props.Document.childDragAction ?? this.props.childDragAction) as dropActionType} + dragAction={(this._props.Document.childDragAction ?? this._props.childDragAction) as dropActionType} onClick={this.onChildClickHandler} onDoubleClick={this.onChildDoubleClickHandler} suppressSetHeight={true} ScreenToLocalTransform={dxf} isContentActive={this.isChildContentActive} - isDocumentActive={this.props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this.props.isDocumentActive : this.isContentActive} - hideResizeHandles={childLayout.layout_fitWidth || this.props.childHideResizeHandles ? true : false} - hideDecorationTitle={this.props.childHideDecorationTitle} - fitContentsToBox={this.props.fitContentsToBox} - focus={this.props.focus} + isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive} + hideResizeHandles={childLayout.layout_fitWidth || this._props.childHideResizeHandles ? true : false} + hideDecorationTitle={this._props.childHideDecorationTitle} + fitContentsToBox={this._props.fitContentsToBox} + focus={this._props.focus} childFilters={this.childDocFilters} childFiltersByRanges={this.childDocRangeFilters} searchFilterDocs={this.searchFilterDocs} - dontRegisterView={this.props.dontRegisterView} - addDocument={this.props.addDocument} - moveDocument={this.props.moveDocument} - removeDocument={this.props.removeDocument} - whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} - addDocTab={this.props.addDocTab} - pinToPres={this.props.pinToPres} + dontRegisterView={this._props.dontRegisterView} + addDocument={this._props.addDocument} + moveDocument={this._props.moveDocument} + removeDocument={this._props.removeDocument} + whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} + addDocTab={this._props.addDocTab} + pinToPres={this._props.pinToPres} bringToFront={returnFalse} dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as any} // 'y', 'x', 'xy' /> @@ -306,16 +306,16 @@ export class CollectionMulticolumnView extends CollectionSubView() { <Tooltip title={'Tab: ' + StrCast(layout.title)}> <div className="document-wrapper" key={'wrapper' + i} style={{ flexDirection: 'column', width: this.lookupPixels(layout) }}> {this.getDisplayDoc(layout)} - <Button tooltip="Remove document from header bar" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(e => this.props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} /> + <Button tooltip="Remove document from header bar" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(e => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} /> <WidthLabel layout={layout} collectionDoc={this.Document} /> </div> </Tooltip>, <ResizeBar width={resizerWidth} key={'resizer' + i} - styleProvider={this.props.styleProvider} - isContentActive={this.props.isContentActive} - select={this.props.select} + styleProvider={this._props.styleProvider} + isContentActive={this._props.isContentActive} + select={this._props.select} columnUnitLength={this.getColumnUnitLength} toLeft={layout} toRight={childLayoutPairs[i + 1]?.layout} @@ -332,12 +332,12 @@ export class CollectionMulticolumnView extends CollectionSubView() { className={'collectionMulticolumnView_contents'} ref={this.createDashEventsTarget} style={{ - width: `calc(100% - ${2 * NumCast(this.props.Document._xMargin)}px)`, - height: `calc(100% - ${2 * NumCast(this.props.Document._yMargin)}px)`, - marginLeft: NumCast(this.props.Document._xMargin), - marginRight: NumCast(this.props.Document._xMargin), - marginTop: NumCast(this.props.Document._yMargin), - marginBottom: NumCast(this.props.Document._yMargin), + width: `calc(100% - ${2 * NumCast(this.Document._xMargin)}px)`, + height: `calc(100% - ${2 * NumCast(this.Document._yMargin)}px)`, + marginLeft: NumCast(this.Document._xMargin), + marginRight: NumCast(this.Document._xMargin), + marginTop: NumCast(this.Document._yMargin), + marginBottom: NumCast(this.Document._yMargin), }}> {this.contents} </div> diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index f1c6c6e1e..cf65bf12a 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -123,7 +123,7 @@ export class CollectionMultirowView extends CollectionSubView() { private get totalRatioAllocation(): number | undefined { const layoutInfoLen = this.resolvedLayoutInformation.heightSpecifiers.length; if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) { - return this.props.PanelHeight() - (this.totalFixedAllocation + resizerHeight * (layoutInfoLen - 1)) - 2 * NumCast(this.props.Document._yMargin); + return this._props.PanelHeight() - (this.totalFixedAllocation + resizerHeight * (layoutInfoLen - 1)) - 2 * NumCast(this._props.Document._yMargin); } } @@ -185,7 +185,7 @@ export class CollectionMultirowView extends CollectionSubView() { let offset = 0; for (const { layout: candidate } of this.childLayoutPairs) { if (candidate === layout) { - return this.props.ScreenToLocalTransform().translate(0, -offset / (this.props.NativeDimScaling?.() || 1)); + return this._props.ScreenToLocalTransform().translate(0, -offset / (this._props.NativeDimScaling?.() || 1)); } offset += this.lookupPixels(candidate) + resizerHeight; } @@ -219,8 +219,8 @@ export class CollectionMultirowView extends CollectionSubView() { if (this.childDocs.includes(d)) { if (dropInd > this.childDocs.indexOf(d)) dropInd--; } - Doc.RemoveDocFromList(this.dataDoc, this.props.fieldKey, d); - Doc.AddDocToList(this.dataDoc, this.props.fieldKey, d, DocListCast(this.dataDoc[this.props.fieldKey])[dropInd], undefined, dropInd === -1); + Doc.RemoveDocFromList(this.dataDoc, this._props.fieldKey, d); + Doc.AddDocToList(this.dataDoc, this._props.fieldKey, d, DocListCast(this.dataDoc[this._props.fieldKey])[dropInd], undefined, dropInd === -1); } }) ); @@ -233,32 +233,32 @@ export class CollectionMultirowView extends CollectionSubView() { onChildClickHandler = () => ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => ScriptCast(this.Document.onChildDoubleClick); - isContentActive = () => this.props.isSelected() || this.props.isContentActive() || this.props.isAnyChildContentActive(); + isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive(); isChildContentActive = () => { - const childDocsActive = this.props.childDocumentsActive?.() ?? this.Document.childDocumentsActive; - return this.props.isContentActive?.() === false || childDocsActive === false + const childDocsActive = this._props.childDocumentsActive?.() ?? this.Document.childDocumentsActive; + return this._props.isContentActive?.() === false || childDocsActive === false ? false // - : this.props.isDocumentActive?.() && childDocsActive + : this._props.isDocumentActive?.() && childDocsActive ? true : undefined; }; getDisplayDoc = (layout: Doc) => { const height = () => this.lookupPixels(layout); - const width = () => this.props.PanelWidth() - 2 * NumCast(this.layoutDoc._xMargin) - (BoolCast(this.layoutDoc.showWidthLabels) ? 20 : 0); + const width = () => this._props.PanelWidth() - 2 * NumCast(this.layoutDoc._xMargin) - (BoolCast(this.layoutDoc.showWidthLabels) ? 20 : 0); const dxf = () => this.lookupIndividualTransform(layout) .translate(-NumCast(this.layoutDoc._xMargin), -NumCast(this.layoutDoc._yMargin)) - .scale(this.props.NativeDimScaling?.() || 1); - const shouldNotScale = () => this.props.fitContentsToBox?.() || BoolCast(layout.freeform_fitContentsToBox); + .scale(this._props.NativeDimScaling?.() || 1); + const shouldNotScale = () => this._props.fitContentsToBox?.() || BoolCast(layout.freeform_fitContentsToBox); return ( <DocumentView Document={layout} TemplateDataDocument={layout.resolvedDataDoc as Doc} - styleProvider={this.props.styleProvider} - docViewPath={this.props.docViewPath} - LayoutTemplate={this.props.childLayoutTemplate} - LayoutTemplateString={this.props.childLayoutString} - renderDepth={this.props.renderDepth + 1} + styleProvider={this._props.styleProvider} + docViewPath={this._props.docViewPath} + LayoutTemplate={this._props.childLayoutTemplate} + LayoutTemplateString={this._props.childLayoutString} + renderDepth={this._props.renderDepth + 1} PanelWidth={width} PanelHeight={height} rootSelected={this.rootSelected} @@ -267,22 +267,22 @@ export class CollectionMultirowView extends CollectionSubView() { onDoubleClick={this.onChildDoubleClickHandler} ScreenToLocalTransform={dxf} isContentActive={this.isChildContentActive} - isDocumentActive={this.props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this.props.isDocumentActive : this.isContentActive} - hideResizeHandles={layout.layout_fitWidth || this.props.childHideResizeHandles ? true : false} - hideDecorationTitle={this.props.childHideDecorationTitle} - fitContentsToBox={this.props.fitContentsToBox} - dragAction={this.props.childDragAction} - focus={this.props.focus} + isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive} + hideResizeHandles={layout.layout_fitWidth || this._props.childHideResizeHandles ? true : false} + hideDecorationTitle={this._props.childHideDecorationTitle} + fitContentsToBox={this._props.fitContentsToBox} + dragAction={this._props.childDragAction} + focus={this._props.focus} childFilters={this.childDocFilters} childFiltersByRanges={this.childDocRangeFilters} searchFilterDocs={this.searchFilterDocs} - dontRegisterView={this.props.dontRegisterView} - addDocument={this.props.addDocument} - moveDocument={this.props.moveDocument} - removeDocument={this.props.removeDocument} - whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} - addDocTab={this.props.addDocTab} - pinToPres={this.props.pinToPres} + dontRegisterView={this._props.dontRegisterView} + addDocument={this._props.addDocument} + moveDocument={this._props.moveDocument} + removeDocument={this._props.removeDocument} + whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} + addDocTab={this._props.addDocTab} + pinToPres={this._props.pinToPres} bringToFront={returnFalse} dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as any} // 'y', 'x', 'xy' /> @@ -305,8 +305,8 @@ export class CollectionMultirowView extends CollectionSubView() { </div>, <ResizeBar height={resizerHeight} - styleProvider={this.props.styleProvider} - isContentActive={this.props.isContentActive} + styleProvider={this._props.styleProvider} + isContentActive={this._props.isContentActive} key={'resizer' + i} columnUnitLength={this.getRowUnitLength} toTop={layout} @@ -323,12 +323,12 @@ export class CollectionMultirowView extends CollectionSubView() { <div className={'collectionMultirowView_contents'} style={{ - width: `calc(100% - ${2 * NumCast(this.props.Document._xMargin)}px)`, - height: `calc(100% - ${2 * NumCast(this.props.Document._yMargin)}px)`, - marginLeft: NumCast(this.props.Document._xMargin), - marginRight: NumCast(this.props.Document._xMargin), - marginTop: NumCast(this.props.Document._yMargin), - marginBottom: NumCast(this.props.Document._yMargin), + width: `calc(100% - ${2 * NumCast(this.Document._xMargin)}px)`, + height: `calc(100% - ${2 * NumCast(this.Document._yMargin)}px)`, + marginLeft: NumCast(this.Document._xMargin), + marginRight: NumCast(this.Document._xMargin), + marginTop: NumCast(this.Document._yMargin), + marginBottom: NumCast(this.Document._yMargin), }} ref={this.createDashEventsTarget}> {this.contents} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index c97c879af..548734dab 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -83,7 +83,8 @@ export class CollectionFreeFormDocumentViewWrapper extends DocComponent<Collecti PanelWidth = () => this._props.autoDim ? this._props.PanelWidth?.() : this.Width; // prettier-ignore PanelHeight = () => this._props.autoDim ? this._props.PanelHeight?.() : this.Height; // prettier-ignore - componentDidUpdate() { + componentDidUpdate(prevProps: Readonly<React.PropsWithChildren<CollectionFreeFormDocumentViewWrapperProps & { fieldKey: string }>>) { + super.componentDidUpdate(prevProps); this.WrapperKeys.forEach(action(keys => ((this as any)[keys.upper] = (this.props as any)[keys.lower]))); } render() { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 343f770d5..ab413e6f2 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1334,7 +1334,7 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> { return this._selected; } public set SELECTED(val) { - this._selected = val; + runInAction(() => (this._selected = val)); } @observable public static Interacting = false; @observable public static LongPress = false; diff --git a/src/client/views/nodes/FunctionPlotBox.tsx b/src/client/views/nodes/FunctionPlotBox.tsx index 29bffb583..c26579e66 100644 --- a/src/client/views/nodes/FunctionPlotBox.tsx +++ b/src/client/views/nodes/FunctionPlotBox.tsx @@ -24,7 +24,7 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps> _plotId = ''; _plotEle: any; - constructor(props: React.PropsWithChildren<FieldViewProps>) { + constructor(props: any) { super(props); makeObservable(this); this._plotId = 'graph' + FunctionPlotBox.GraphCount++; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index b1ccd38ba..876f13370 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -55,8 +55,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp private _marqueeref = React.createRef<MarqueeAnnotator>(); @observable _curSuffix = ''; - constructor(props: ViewBoxAnnotatableProps & FieldViewProps) { + constructor(props: any) { super(props); + makeObservable(this); this._props.setContentView?.(this); } diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index fa7a55bc7..d0a9f10b4 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -5,7 +5,7 @@ import { observer } from 'mobx-react'; import wiki from 'wikijs'; import { Doc, Opt } from '../../../fields/Doc'; import { Cast, DocCast, NumCast, PromiseValue, StrCast } from '../../../fields/Types'; -import { copyProps, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils'; import { DocServer } from '../../DocServer'; import { Docs } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; @@ -82,7 +82,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps this.updateHref(); } componentDidUpdate(prevProps: Readonly<LinkDocPreviewProps>) { - copyProps(this, prevProps); + super.componentDidUpdate(prevProps); if (prevProps.linkSrc !== this._props.linkSrc || prevProps.linkDoc !== this._props.linkDoc || prevProps.hrefs !== this._props.hrefs) this.init(); } componentDidMount() { diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx index b458e5a28..66c4dc7b8 100644 --- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx +++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { IReactionDisposer, ObservableMap, reaction } from 'mobx'; +import { IReactionDisposer, ObservableMap, makeObservable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../../Utils'; @@ -34,8 +34,9 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { return this._left > 0; } - constructor(props: Readonly<{}>) { + constructor(props: any) { super(props); + makeObservable(this); MapAnchorMenu.Instance = this; MapAnchorMenu.Instance._canFade = false; } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 213f88177..733febd2d 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -58,7 +58,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps return ImageCast(this.layoutDoc['thumb-frozen'], ImageCast(this.layoutDoc.thumb))?.url; } - constructor(props: ViewBoxAnnotatableProps & FieldViewProps) { + constructor(props: any) { super(props); makeObservable(this); const nw = Doc.NativeWidth(this.Document, this.dataDoc) || 927; diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx index c498a58d6..e75b1ab6f 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx @@ -202,7 +202,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP ]; } - componentDidUpdate() { + componentDidUpdate(prevProps: Readonly<React.PropsWithChildren<FieldViewProps>>) { + 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(); diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx index 99333991f..f5077a07e 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx @@ -1,4 +1,4 @@ -import { computed, IReactionDisposer, reaction } from 'mobx'; +import { computed, IReactionDisposer, makeObservable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import './PhysicsSimulationBox.scss'; import * as React from 'react'; @@ -93,6 +93,7 @@ interface IState { export default class Weight extends React.Component<IWeightProps, IState> { constructor(props: any) { super(props); + makeObservable(this); this.state = { angleLabel: 0, clickPositionX: 0, diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx index 191877cb5..061a46f03 100644 --- a/src/client/views/nodes/RadialMenu.tsx +++ b/src/client/views/nodes/RadialMenu.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import './RadialMenu.scss'; import { RadialMenuItem, RadialMenuProps } from './RadialMenuItem'; @@ -9,9 +9,9 @@ export class RadialMenu extends React.Component { static Instance: RadialMenu; static readonly buffer = 20; - constructor(props: Readonly<{}>) { + constructor(props: any) { super(props); - + makeObservable(this); RadialMenu.Instance = this; } diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index a7ff8ff8f..d5d31b407 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; // import { Canvas } from '@react-three/fiber'; -import { computed, observable, runInAction } from 'mobx'; +import { computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; // import { BufferAttribute, Camera, Vector2, Vector3 } from 'three'; import { DateField } from '../../../fields/DateField'; @@ -123,14 +123,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl constructor(props: any) { super(props); - if (this.dataDoc.videoWall) { - this.layoutDoc.nativeWidth = undefined; - this.layoutDoc.nativeHeight = undefined; - this.layoutDoc.popOff = 0; - this.layoutDoc.popOut = 1; - } else { - this.setupDictation(); - } + makeObservable(this); + this.setupDictation(); } getAnchor = (addAsAnnotation: boolean) => { const startTime = Cast(this.layoutDoc._layout_currentTimecode, 'number', null) || (this._videoRec ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined); @@ -173,7 +167,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl }; @computed get content() { - if (this.layoutDoc.videoWall) return null; return ( <video className={'videoBox-content'} diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index 127edaed7..7e7eaee45 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -1,5 +1,5 @@ let ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete').default; -import { action, computed, observable } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc } from '../../../fields/Doc'; @@ -60,6 +60,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable constructor(props: any) { super(props); + makeObservable(this); if (!this.compileParams.length) { const params = ScriptCast(this.dataDoc[this.props.fieldKey])?.script.options.params as { [key: string]: any }; if (params) { diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index ebe86318d..df73dffe4 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -68,7 +68,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp private _playRegionTimer: any = null; // timeout for playback private _controlsFadeTimer: any = null; // timeout for controls fade - constructor(props: ViewBoxAnnotatableProps & FieldViewProps) { + constructor(props: any) { super(props); makeObservable(this); this._props.setContentView?.(this); diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 2f92f1edb..57045e2af 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -98,7 +98,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps return Cast(this.Document[this._props.fieldKey], WebField)?.url; } - constructor(props: ViewBoxAnnotatableProps & FieldViewProps) { + constructor(props: any) { super(props); makeObservable(this); this._webUrl = this._url; // setting the weburl will change the src parameter of the embedded iframe and force a navigation to it. diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx index d6b053c8e..b7d2a24c2 100644 --- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx +++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx @@ -54,7 +54,7 @@ interface IDashDocCommentViewInternal { } export class DashDocCommentViewInternal extends React.Component<IDashDocCommentViewInternal> { - constructor(props: IDashDocCommentViewInternal) { + constructor(props: any) { super(props); this.onPointerLeaveCollapsed = this.onPointerLeaveCollapsed.bind(this); this.onPointerEnterCollapsed = this.onPointerEnterCollapsed.bind(this); diff --git a/src/client/views/nodes/formattedText/EquationEditor.tsx b/src/client/views/nodes/formattedText/EquationEditor.tsx index 07c70af77..b4102e08e 100644 --- a/src/client/views/nodes/formattedText/EquationEditor.tsx +++ b/src/client/views/nodes/formattedText/EquationEditor.tsx @@ -44,7 +44,7 @@ class EquationEditor extends Component<EquationEditorProps> { // Element needs to be in the class format and thus requires a constructor. The steps that are run // in the constructor is to make sure that React can succesfully communicate with the equation // editor. - constructor(props: EquationEditorProps) { + constructor(props: any) { super(props); this.element = createRef(); diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx index 5ee5d25c3..331ed1980 100644 --- a/src/client/views/nodes/formattedText/EquationView.tsx +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -8,6 +8,7 @@ import { StrCast } from '../../../../fields/Types'; import './DashFieldView.scss'; import { FormattedTextBox } from './FormattedTextBox'; import * as React from 'react'; +import { AnyArray } from 'mongoose'; export class EquationView { dom: HTMLDivElement; // container for label and value @@ -63,7 +64,7 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal> _fieldKey: string; _ref: React.RefObject<EquationEditor> = React.createRef(); - constructor(props: IEquationViewInternal) { + constructor(props: any) { super(props); this._fieldKey = this.props.fieldKey; this._textBoxDoc = this.props.tbox.props.Document; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 997c3f86d..ad2fab8b0 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -208,7 +208,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps return url.startsWith(document.location.origin) ? new URL(url).pathname.split('doc/').lastElement() : ''; // docId } - constructor(props: React.PropsWithChildren<FieldViewProps & FormattedTextBoxProps>) { + constructor(props: any) { super(props); makeObservable(this); FormattedTextBox.Instance = this; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 4ff816812..17993d88e 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, IReactionDisposer, observable, ObservableSet, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, DocListCast, FieldResult, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { Animation } from '../../../../fields/DocSymbols'; @@ -72,6 +72,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { constructor(props: any) { super(props); + makeObservable(this); if (!PresBox.navigateToDocScript) { PresBox.navigateToDocScript = ScriptField.MakeFunction('navigateToDoc(this.presentation_targetDoc, self)')!; } diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index a8c83ded6..d0688c338 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -23,7 +23,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> { private _commentRef = React.createRef<HTMLDivElement>(); private _cropRef = React.createRef<HTMLDivElement>(); - constructor(props: AntimodeMenuProps) { + constructor(props: any) { super(props); makeObservable(this); AnchorMenu.Instance = this; diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index 0cda36509..cdd0cb95a 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import './GPTPopup.scss'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, observable } from 'mobx'; +import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import ReactLoading from 'react-loading'; import { TypeAnimation } from 'react-type-animation'; @@ -14,6 +14,7 @@ import { AnchorMenu } from '../AnchorMenu'; import { gptImageCall } from '../../../apis/gpt/GPT'; import { Networking } from '../../../Network'; import { Utils } from '../../../../Utils'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; export enum GPTPopupMode { SUMMARY, @@ -24,7 +25,7 @@ export enum GPTPopupMode { interface GPTPopupProps {} @observer -export class GPTPopup extends React.Component<GPTPopupProps> { +export class GPTPopup extends ObservableReactComponent<GPTPopupProps> { static Instance: GPTPopup; @observable @@ -177,6 +178,7 @@ export class GPTPopup extends React.Component<GPTPopupProps> { constructor(props: GPTPopupProps) { super(props); + makeObservable(this); GPTPopup.Instance = this; } diff --git a/src/client/views/search/CheckBox.scss b/src/client/views/search/CheckBox.scss deleted file mode 100644 index 4892facbc..000000000 --- a/src/client/views/search/CheckBox.scss +++ /dev/null @@ -1,58 +0,0 @@ -@import '../global/globalCssVariables.module.scss'; - -.checkboxfilter { - display: flex; - margin-top: 0px; - padding: 3px; - - .outer { - display: flex; - position: relative; - justify-content: center; - align-items: center; - margin-top: 0px; - - .check-container:hover ~ .check-box { - background-color: $medium-blue; - } - - .check-container { - width: 40px; - height: 40px; - position: absolute; - z-index: 1000; - - .checkmark { - z-index: 1000; - position: absolute; - fill-opacity: 0; - stroke-width: 4px; - // stroke: white; - stroke: gray; - } - } - - .check-box { - z-index: 900; - position: relative; - height: 20px; - width: 20px; - overflow: visible; - background-color: transparent; - border-style: solid; - border-color: $medium-gray; - border-width: 2px; - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - } - } - - .checkbox-title { - display: flex; - align-items: center; - text-transform: capitalize; - margin-left: 15px; - } -} diff --git a/src/client/views/search/CheckBox.tsx b/src/client/views/search/CheckBox.tsx deleted file mode 100644 index 0a1e551ec..000000000 --- a/src/client/views/search/CheckBox.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import * as React from 'react'; -import { observer } from 'mobx-react'; -import { observable, action, runInAction, IReactionDisposer, reaction } from 'mobx'; -import "./CheckBox.scss"; - -interface CheckBoxProps { - originalStatus: boolean; - updateStatus(newStatus: boolean): void; - title: string; - parent: any; - numCount: number; - default: boolean; -} - -@observer -export class CheckBox extends React.Component<CheckBoxProps>{ - // true = checked, false = unchecked - @observable private _status: boolean; - // @observable private uncheckTimeline: anime.AnimeTimelineInstance; - // @observable private checkTimeline: anime.AnimeTimelineInstance; - @observable private checkRef: any; - @observable private _resetReaction?: IReactionDisposer; - - - constructor(props: CheckBoxProps) { - super(props); - this._status = this.props.originalStatus; - this.checkRef = React.createRef(); - - // this.checkTimeline = anime.timeline({ - // loop: false, - // autoplay: false, - // direction: "normal", - // }); this.uncheckTimeline = anime.timeline({ - // loop: false, - // autoplay: false, - // direction: "normal", - // }); - } - - // componentDidMount = () => { - // this.uncheckTimeline.add({ - // targets: this.checkRef.current, - // easing: "easeInOutQuad", - // duration: 500, - // opacity: 0, - // }); - // this.checkTimeline.add({ - // targets: this.checkRef.current, - // easing: "easeInOutQuad", - // duration: 500, - // strokeDashoffset: [anime.setDashoffset, 0], - // opacity: 1 - // }); - - // if (this.props.originalStatus) { - // this.checkTimeline.play(); - // this.checkTimeline.restart(); - // } - - // this._resetReaction = reaction( - // () => this.props.parent._resetBoolean, - // () => { - // if (this.props.parent._resetBoolean) { - // runInAction(() => { - // this.reset(); - // this.props.parent._resetCounter++; - // if (this.props.parent._resetCounter === this.props.numCount) { - // this.props.parent._resetCounter = 0; - // this.props.parent._resetBoolean = false; - // } - // }); - // } - // }, - // ); - // } - - // @action.bound - // reset() { - // if (this.props.default) { - // if (!this._status) { - // this._status = true; - // this.checkTimeline.play(); - // this.checkTimeline.restart(); - // } - // } - // else { - // if (this._status) { - // this._status = false; - // this.uncheckTimeline.play(); - // this.uncheckTimeline.restart(); - // } - // } - - // this.props.updateStatus(this.props.default); - // } - - @action.bound - onClick = () => { - // if (this._status) { - // this.uncheckTimeline.play(); - // this.uncheckTimeline.restart(); - // } - // else { - // this.checkTimeline.play(); - // this.checkTimeline.restart(); - - // } - // this._status = !this._status; - // this.props.updateStatus(this._status); - - } - - render() { - return ( - <div className="checkboxfilter" onClick={this.onClick}> - <div className="outer"> - <div className="check-container"> - <svg viewBox="0 12 40 40"> - <path ref={this.checkRef} className="checkmark" d="M14.1 27.2l7.1 7.2 16.7-18" /> - </svg> - </div> - <div className="check-box" /> - </div> - <div className="checkbox-title">{this.props.title}</div> - </div> - ); - } - -}
\ No newline at end of file diff --git a/src/client/views/search/CollectionFilters.scss b/src/client/views/search/CollectionFilters.scss deleted file mode 100644 index 6105df570..000000000 --- a/src/client/views/search/CollectionFilters.scss +++ /dev/null @@ -1,20 +0,0 @@ -@import '../global/globalCssVariables.module.scss'; - -.collection-filters { - display: flex; - flex-direction: row; - width: 100%; - - &.main { - width: 47%; - float: left; - } - - &.optional { - width: 60%; - display: grid; - grid-template-columns: 50% 50%; - float: right; - opacity: 0; - } -} diff --git a/src/client/views/search/CollectionFilters.tsx b/src/client/views/search/CollectionFilters.tsx deleted file mode 100644 index 48d0b2ddb..000000000 --- a/src/client/views/search/CollectionFilters.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import * as React from 'react'; -import { observable, action } from 'mobx'; -import { CheckBox } from './CheckBox'; -import "./CollectionFilters.scss"; -import * as anime from 'animejs'; - -interface CollectionFilterProps { - collectionStatus: boolean; - updateCollectionStatus(val: boolean): void; - collectionSelfStatus: boolean; - updateSelfCollectionStatus(val: boolean): void; - collectionParentStatus: boolean; - updateParentCollectionStatus(val: boolean): void; -} - -export class CollectionFilters extends React.Component<CollectionFilterProps> { - - static Instance: CollectionFilters; - - @observable public _resetBoolean = false; - @observable public _resetCounter: number = 0; - - @observable private _collectionsSelected = this.props.collectionStatus; - @observable private _timeline: anime.AnimeTimelineInstance; - @observable private _ref: any; - - constructor(props: CollectionFilterProps) { - super(props); - CollectionFilters.Instance = this; - this._ref = React.createRef(); - - this._timeline = anime.timeline({ - loop: false, - autoplay: false, - direction: "reverse", - }); - } - - componentDidMount = () => { - this._timeline.add({ - targets: this._ref.current, - easing: "easeInOutQuad", - duration: 500, - opacity: 1, - }); - - if (this._collectionsSelected) { - this._timeline.play(); - this._timeline.reverse(); - } - } - - @action.bound - resetCollectionFilters() { this._resetBoolean = true; } - - @action.bound - updateColStat(val: boolean) { - this.props.updateCollectionStatus(val); - - if (this._collectionsSelected !== val) { - this._timeline.play(); - this._timeline.reverse(); - } - - this._collectionsSelected = val; - } - - render() { - return ( - <div> - <div className="collection-filters"> - <div className="collection-filters main"> - <CheckBox default={false} title={"limit to current collection"} parent={this} numCount={3} updateStatus={this.updateColStat} originalStatus={this.props.collectionStatus} /> - </div> - <div className="collection-filters optional" ref={this._ref}> - <CheckBox default={true} title={"Search in self"} parent={this} numCount={3} updateStatus={this.props.updateSelfCollectionStatus} originalStatus={this.props.collectionSelfStatus} /> - <CheckBox default={true} title={"Search in parent"} parent={this} numCount={3} updateStatus={this.props.updateParentCollectionStatus} originalStatus={this.props.collectionParentStatus} /> - </div> - </div> - </div> - ); - } -}
\ No newline at end of file diff --git a/src/client/views/search/IconBar.scss b/src/client/views/search/IconBar.scss deleted file mode 100644 index 05aa099f7..000000000 --- a/src/client/views/search/IconBar.scss +++ /dev/null @@ -1,10 +0,0 @@ -@import '../global/globalCssVariables.module.scss'; - -.icon-bar { - display: flex; - flex-wrap: wrap; - justify-content: space-evenly; - height: auto; - width: 100%; - flex-direction: row-reverse; -} diff --git a/src/client/views/search/IconBar.tsx b/src/client/views/search/IconBar.tsx deleted file mode 100644 index 540c1b5e1..000000000 --- a/src/client/views/search/IconBar.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { action, observable } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { DocumentType } from '../../documents/DocumentTypes'; -import './IconBar.scss'; -import { IconButton } from './IconButton'; -import './IconButton.scss'; - -export interface IconBarProps { - setIcons: (icons: string[]) => void; -} - -@observer -export class IconBar extends React.Component<IconBarProps> { - public _allIcons: string[] = [DocumentType.AUDIO, DocumentType.COL, DocumentType.IMG, DocumentType.LINK, DocumentType.PDF, DocumentType.RTF, DocumentType.VID, DocumentType.WEB, DocumentType.MAP]; - - @observable private _icons: string[] = this._allIcons; - - static Instance: IconBar; - - @observable public _resetClicked: boolean = false; - @observable public _selectAllClicked: boolean = false; - @observable public _reset: number = 0; - @observable public _select: number = 0; - - @action.bound - updateIcon(newArray: string[]) { - this._icons = newArray; - this.props.setIcons?.(this._icons); - } - - @action.bound - getIcons(): string[] { - return this._icons; - } - - constructor(props: any) { - super(props); - IconBar.Instance = this; - } - - @action.bound - getList(): string[] { - return this.getIcons(); - } - - @action.bound - updateList(newList: string[]) { - this.updateIcon(newList); - } - - @action.bound - resetSelf = () => { - this._resetClicked = true; - this.updateList([]); - }; - - @action.bound - selectAll = () => { - this._selectAllClicked = true; - this.updateList(this._allIcons); - }; - - render() { - return ( - <div className="icon-bar"> - {this._allIcons.map((type: string) => ( - <IconButton key={type.toString()} type={type} /> - ))} - </div> - ); - } -} diff --git a/src/client/views/search/IconButton.scss b/src/client/views/search/IconButton.scss deleted file mode 100644 index d2a2ea369..000000000 --- a/src/client/views/search/IconButton.scss +++ /dev/null @@ -1,53 +0,0 @@ -@import '../global/globalCssVariables.module.scss'; - -.type-outer { - display: flex; - flex-direction: column; - align-items: center; - width: 30px; - - .type-icon { - height: 30px; - width: 30px; - color: $white; - // background-color: rgb(194, 194, 197); - background-color: gray; - border-radius: 50%; - display: flex; - justify-content: center; - align-items: center; - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - font-size: 2em; - - .fontawesome-icon { - height: 15px; - width: 15px; - } - } - - .filter-description { - text-transform: capitalize; - font-size: 10; - text-align: center; - height: 15px; - margin-top: 5px; - opacity: 1; - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - } - - .type-icon:hover { - transform: scale(1.1); - background-color: $medium-blue; - opacity: 1; - - + .filter-description { - opacity: 1; - } - } -} diff --git a/src/client/views/search/IconButton.tsx b/src/client/views/search/IconButton.tsx deleted file mode 100644 index 20084b64d..000000000 --- a/src/client/views/search/IconButton.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import * as _ from 'lodash'; -import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { DocumentType } from '../../documents/DocumentTypes'; -import '../global/globalCssVariables.module.scss'; -import { IconBar } from './IconBar'; -import './IconButton.scss'; -import './SearchBox.scss'; - -interface iconButtonProps { - type: string; -} - -@observer -export class IconButton extends React.Component<iconButtonProps> { - @observable private _isSelected: boolean = IconBar.Instance.getIcons().indexOf(this.props.type) !== -1; - @observable private _hover = false; - private _resetReaction?: IReactionDisposer; - private _selectAllReaction?: IReactionDisposer; - - static Instance: IconButton; - constructor(props: iconButtonProps) { - super(props); - IconButton.Instance = this; - } - - componentDidMount = () => { - this._resetReaction = reaction( - () => IconBar.Instance._resetClicked, - action(() => { - if (IconBar.Instance._resetClicked) { - this._isSelected = false; - IconBar.Instance._reset++; - if (IconBar.Instance._reset === 9) { - IconBar.Instance._reset = 0; - IconBar.Instance._resetClicked = false; - } - } - }) - ); - - this._selectAllReaction = reaction( - () => IconBar.Instance._selectAllClicked, - action(() => { - if (IconBar.Instance._selectAllClicked) { - this._isSelected = true; - IconBar.Instance._select++; - if (IconBar.Instance._select === 9) { - IconBar.Instance._select = 0; - IconBar.Instance._selectAllClicked = false; - } - } - }) - ); - }; - - @action.bound - getIcon() { - switch (this.props.type) { - case DocumentType.NONE: return 'ban'; - case DocumentType.AUDIO: return 'music'; - case DocumentType.COL: return 'object-group'; - case DocumentType.IMG: return 'image'; - case DocumentType.LINK: return 'link'; - case DocumentType.PDF: return 'file-pdf'; - case DocumentType.RTF: return 'sticky-note'; - case DocumentType.VID: return 'video'; - case DocumentType.WEB: return 'globe-asia'; - case DocumentType.MAP: return 'map-marker-alt'; - default: return 'caret-down'; - } // prettier-ignore - } - - @action.bound - onClick = () => { - const newList: string[] = IconBar.Instance.getIcons(); - - if (!this._isSelected) { - this._isSelected = true; - newList.push(this.props.type); - } else { - this._isSelected = false; - _.pull(newList, this.props.type); - } - - IconBar.Instance.updateIcon(newList); - }; - - selected = { - opacity: 1, - backgroundColor: '#121721', - //backgroundColor: "rgb(128, 128, 128)" - }; - - notSelected = { - opacity: 0.2, - backgroundColor: '#121721', - }; - - hoverStyle = { - opacity: 1, - backgroundColor: 'rgb(128, 128, 128)', - //backgroundColor: "rgb(178, 206, 248)" //$medium-blue - }; - - render() { - return ( - <div className="type-outer" id={this.props.type + '-filter'} onMouseEnter={() => (this._hover = true)} onMouseLeave={() => (this._hover = false)} onClick={this.onClick}> - <div className="type-icon" id={this.props.type + '-icon'} style={this._hover ? this.hoverStyle : this._isSelected ? this.selected : this.notSelected}> - <FontAwesomeIcon className="fontawesome-icon" icon={this.getIcon()} /> - </div> - {/* <div className="filter-description">{this.props.type}</div> */} - </div> - ); - } -} diff --git a/src/client/views/search/NaviconButton.scss b/src/client/views/search/NaviconButton.scss deleted file mode 100644 index 917635c0b..000000000 --- a/src/client/views/search/NaviconButton.scss +++ /dev/null @@ -1,69 +0,0 @@ -@import '../global/globalCssVariables.module.scss'; - -$height-icon: 15px; -$width-line: 30px; -$height-line: 4px; - -$transition-time: 0.4s; -$rotation: 45deg; -$translateY: calc($height-icon / 2); -$translateX: 0; - -#hamburger-icon { - width: $width-line; - height: $height-icon; - position: relative; - display: block; - transition: all $transition-time; - -webkit-transition: all $transition-time; - -moz-transition: all $transition-time; - - .line { - display: block; - background: $medium-gray; - width: $width-line; - height: $height-line; - position: absolute; - left: 0; - border-radius: calc($height-line / 2); - transition: all $transition-time; - -webkit-transition: all $transition-time; - -moz-transition: all $transition-time; - - &.line-1 { - top: 0; - } - - &.line-2 { - top: 50%; - } - - &.line-3 { - top: 100%; - } - } -} - -.filter-header.active { - .line-1 { - transform: translateY($translateY) translateX($translateX) rotate($rotation); - -webkit-transform: translateY($translateY) translateX($translateX) rotate($rotation); - -moz-transform: translateY($translateY) translateX($translateX) rotate($rotation); - } - - .line-2 { - opacity: 0; - } - - .line-3 { - transform: translateY($translateY * -1) translateX($translateX) rotate($rotation * -1); - -webkit-transform: translateY($translateY * -1) translateX($translateX) rotate($rotation * -1); - -moz-transform: translateY($translateY * -1) translateX($translateX) rotate($rotation * -1); - } -} - -.filter-header:hover #hamburger-icon { - transform: scale(1.1); - -webkit-transform: scale(1.1); - -moz-transform: scale(1.1); -} diff --git a/src/client/views/search/NaviconButton.tsx b/src/client/views/search/NaviconButton.tsx deleted file mode 100644 index 0fa4a0fca..000000000 --- a/src/client/views/search/NaviconButton.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from 'react'; -import { observer } from 'mobx-react'; -import "./NaviconButton.scss"; -import * as $ from 'jquery'; -import { observable } from 'mobx'; - -export interface NaviconProps { - onClick(): void; -} - -export class NaviconButton extends React.Component<NaviconProps> { - - @observable private _ref: React.RefObject<HTMLAnchorElement> = React.createRef(); - - componentDidMount = () => { - const that = this; - if (this._ref.current) { - this._ref.current.addEventListener("click", function (e) { - e.preventDefault(); - if (that._ref.current) { - that._ref.current.classList.toggle('active'); - return false; - } - }); - } - } - - render() { - return ( - <a id="hamburger-icon" href="#" ref={this._ref} title="Menu"> - <span className="line line-1"></span> - <span className="line line-2"></span> - <span className="line line-3"></span> - </a> - ); - } -}
\ No newline at end of file diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index a3c4bd2ed..09e459f7d 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -1,5 +1,4 @@ @import '../global/globalCssVariables.module.scss'; -@import './NaviconButton.scss'; .searchBox-container { width: 100%; diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 3172ff9c0..ccfccb771 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -1,5 +1,5 @@ import { Tooltip } from '@mui/material'; -import { action, computed, observable } from 'mobx'; +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'; @@ -61,6 +61,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() { */ constructor(props: any) { super(props); + makeObservable(this); SearchBox.Instance = this; } diff --git a/src/client/views/search/ToggleBar.scss b/src/client/views/search/ToggleBar.scss deleted file mode 100644 index 9e27db2bc..000000000 --- a/src/client/views/search/ToggleBar.scss +++ /dev/null @@ -1,41 +0,0 @@ -@import '../global/globalCssVariables.module.scss'; - -.toggle-title { - display: flex; - align-items: center; - color: $white; - text-transform: uppercase; - flex-direction: row; - justify-content: space-around; - padding: 5px; - - .toggle-option { - width: 50%; - text-align: center; - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - color: gray; - font-size: 13; - } -} - -.toggle-bar { - // height: 50px; - height: 30px; - width: 100px; - background-color: $medium-gray; - border-radius: 10px; - padding: 5px; - display: flex; - align-items: center; - - .toggle-button { - // width: 275px; - width: 40px; - height: 100%; - border-radius: 10px; - background-color: $white; - } -} diff --git a/src/client/views/search/ToggleBar.tsx b/src/client/views/search/ToggleBar.tsx deleted file mode 100644 index 466822eba..000000000 --- a/src/client/views/search/ToggleBar.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import * as React from 'react'; -import { observer } from 'mobx-react'; -import { observable, action, runInAction, computed } from 'mobx'; -import "./SearchBox.scss"; -import "./ToggleBar.scss"; -import * as anime from 'animejs'; - -export interface ToggleBarProps { - originalStatus: boolean; - optionOne: string; - optionTwo: string; - handleChange(): void; - getStatus(): boolean; -} - -@observer -export class ToggleBar extends React.Component<ToggleBarProps>{ - static Instance: ToggleBar; - - @observable private _forwardTimeline: anime.AnimeTimelineInstance; - @observable private _toggleButton: React.RefObject<HTMLDivElement>; - @observable private _originalStatus: boolean = this.props.originalStatus; - - constructor(props: ToggleBarProps) { - super(props); - ToggleBar.Instance = this; - this._toggleButton = React.createRef(); - this._forwardTimeline = anime.timeline({ - loop: false, - autoplay: false, - direction: "reverse", - }); - } - - componentDidMount = () => { - const totalWidth = 265; - - if (this._originalStatus) { - this._forwardTimeline.add({ - targets: this._toggleButton.current, - translateX: totalWidth, - easing: "easeInOutQuad", - duration: 500 - }); - } - else { - this._forwardTimeline.add({ - targets: this._toggleButton.current, - translateX: -totalWidth, - easing: "easeInOutQuad", - duration: 500 - }); - } - } - - @action.bound - onclick() { - this._forwardTimeline.play(); - this._forwardTimeline.reverse(); - this.props.handleChange(); - } - - @action.bound - public resetToggle = () => { - if (!this.props.getStatus()) { - this._forwardTimeline.play(); - this._forwardTimeline.reverse(); - this.props.handleChange(); - } - } - - render() { - return ( - <div> - <div className="toggle-title"> - <div className="toggle-option" style={{ opacity: (this.props.getStatus() ? 1 : .4) }}>{this.props.optionOne}</div> - <div className="toggle-option" style={{ opacity: (this.props.getStatus() ? .4 : 1) }}>{this.props.optionTwo}</div> - </div> - <div className="toggle-bar" id="toggle-bar" onClick={this.onclick} style={{ flexDirection: (this._originalStatus ? "row" : "row-reverse") }}> - <div className="toggle-button" id="toggle-button" ref={this._toggleButton} /> - </div> - </div> - ); - } -}
\ No newline at end of file diff --git a/src/fields/URLField.ts b/src/fields/URLField.ts index 8ac20b1e5..817b62373 100644 --- a/src/fields/URLField.ts +++ b/src/fields/URLField.ts @@ -34,7 +34,7 @@ export abstract class URLField extends ObjectField { if (Utils.prepend(this.url?.pathname) === this.url?.href) { return `new ${this.constructor.name}("${this.url.pathname}")`; } - return `new ${this.constructor.name}("${this.url.href}")`; + return `new ${this.constructor.name}("${this.url?.href}")`; } [ToString]() { if (Utils.prepend(this.url?.pathname) === this.url?.href) { diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts index ab3982cc5..cd9b635bd 100644 --- a/src/server/DashUploadUtils.ts +++ b/src/server/DashUploadUtils.ts @@ -121,8 +121,8 @@ export namespace DashUploadUtils { } function resolveExistingFile(name: string, pat: string, directory: Directory, mimetype?: string | null, duration?: number, rawText?: string): Upload.FileResponse<Upload.FileInformation> { - const data = { size: 0, filepath: pat, name, type: mimetype ?? '', originalFilename: name, newFilename: path.basename(pat), mimetype, hashAlgorithm: false as any }; - const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date(), mimetype, toJson: () => undefined as any }) }; + const data = { size: 0, filepath: pat, name, type: mimetype ?? '', originalFilename: name, newFilename: path.basename(pat), mimetype: mimetype || null, hashAlgorithm: false as any }; + const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date(), mimetype: mimetype || null, toJson: () => undefined as any }) }; return { source: file || null, result: { |