From 380ee1acac1c0b7972d7d423cf804af146dc0edf Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 10 Dec 2023 20:19:27 -0500
Subject: massive changes to use mobx 6 which means not accessing props
 directly in @computed functions.

---
 src/client/views/PreviewCursor.tsx | 135 ++++++++++++++++++++-----------------
 1 file changed, 72 insertions(+), 63 deletions(-)

(limited to 'src/client/views/PreviewCursor.tsx')

diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index d1bd0500b..6e1a2cfb1 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -1,4 +1,4 @@
-import { action, observable, runInAction } from 'mobx';
+import { action, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc, Opt } from '../../fields/Doc';
@@ -12,30 +12,38 @@ import './PreviewCursor.scss';
 
 @observer
 export class PreviewCursor extends React.Component<{}> {
-    static _onKeyPress?: (e: KeyboardEvent) => void;
-    static _getTransform: () => Transform;
-    static _addDocument: (doc: Doc | Doc[]) => boolean;
-    static _addLiveTextDoc: (doc: Doc) => void;
-    static _nudge?: undefined | ((x: number, y: number) => boolean);
-    static _slowLoadDocuments?: (files: File[] | string, options: DocumentOptions, generatedDocuments: Doc[], text: string, completed: ((doc: Doc[]) => void) | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => Promise<void>;
-    @observable static _clickPoint = [0, 0];
-    @observable public static Visible = false;
-    public static Doc: Opt<Doc>;
+    static _instance: PreviewCursor;
+    public static get Instance() {
+        return PreviewCursor._instance;
+    }
+
+    _onKeyPress?: (e: KeyboardEvent) => void;
+    _getTransform?: () => Transform;
+    _addDocument?: (doc: Doc | Doc[]) => boolean;
+    _addLiveTextDoc?: (doc: Doc) => void;
+    _nudge?: undefined | ((x: number, y: number) => boolean);
+    _slowLoadDocuments?: (files: File[] | string, options: DocumentOptions, generatedDocuments: Doc[], text: string, completed: ((doc: Doc[]) => void) | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => Promise<void>;
+    @observable _clickPoint: number[];
+    @observable public Visible = false;
+    public Doc: Opt<Doc>;
     constructor(props: any) {
         super(props);
+        PreviewCursor._instance = this;
+        makeObservable(this);
+        this._clickPoint = observable([0, 0]);
         document.addEventListener('keydown', this.onKeyPress);
         document.addEventListener('paste', this.paste, true);
     }
 
     paste = async (e: ClipboardEvent) => {
-        if (PreviewCursor.Visible && e.clipboardData) {
-            const newPoint = PreviewCursor._getTransform().transformPoint(PreviewCursor._clickPoint[0], PreviewCursor._clickPoint[1]);
-            runInAction(() => (PreviewCursor.Visible = false));
+        if (this.Visible && e.clipboardData) {
+            const newPoint = this._getTransform?.().transformPoint(this._clickPoint[0], this._clickPoint[1]);
+            runInAction(() => (this.Visible = false));
 
             // tests for URL and makes web document
             const re: any = /^https?:\/\//g;
             const plain = e.clipboardData.getData('text/plain');
-            if (plain) {
+            if (plain && newPoint) {
                 // tests for youtube and makes video document
                 if (plain.indexOf('www.youtube.com/watch') !== -1) {
                     const batch = UndoManager.StartBatch('youtube upload');
@@ -47,21 +55,22 @@ export class PreviewCursor extends React.Component<{}> {
                         x: newPoint[0],
                         y: newPoint[1],
                     };
-                    PreviewCursor._slowLoadDocuments?.(plain.split('v=')[1].split('&')[0], options, generatedDocuments, '', undefined, PreviewCursor._addDocument).then(batch.end);
+                    this._slowLoadDocuments?.(plain.split('v=')[1].split('&')[0], options, generatedDocuments, '', undefined, this._addDocument ?? returnFalse).then(batch.end);
                 } else if (re.test(plain)) {
                     const url = plain;
                     if (!url.startsWith(window.location.href)) {
-                        undoBatch(() =>
-                            PreviewCursor._addDocument(
-                                Docs.Create.WebDocument(url, {
-                                    title: url,
-                                    _width: 500,
-                                    _height: 300,
-                                    data_useCors: true,
-                                    x: newPoint[0],
-                                    y: newPoint[1],
-                                })
-                            )
+                        undoBatch(
+                            () =>
+                                this._addDocument?.(
+                                    Docs.Create.WebDocument(url, {
+                                        title: url,
+                                        _width: 500,
+                                        _height: 300,
+                                        data_useCors: true,
+                                        x: newPoint[0],
+                                        y: newPoint[1],
+                                    })
+                                )
                         )();
                     } else alert('cannot paste dash into itself');
                 } else if (plain.startsWith('__DashDocId(') || plain.startsWith('__DashCloneId(')) {
@@ -70,13 +79,13 @@ export class PreviewCursor extends React.Component<{}> {
                     const strs = docids[0].split(','); // hack!  docids[0] is the top left of the selection rectangle
                     const ptx = Number(strs[0].substring((clone ? '__DashCloneId(' : '__DashDocId(').length));
                     const pty = Number(strs[1].substring(0, strs[1].length - 1));
-                    Doc.Paste(docids.slice(1), clone, PreviewCursor._addDocument, ptx, pty, newPoint);
+                    this._addDocument && Doc.Paste(docids.slice(1), clone, this._addDocument, ptx, pty, newPoint);
 
                     e.stopPropagation();
                 } else {
                     FormattedTextBox.PasteOnLoad = e;
                     if (e.clipboardData.getData('dash/pdfAnchor')) e.preventDefault();
-                    UndoManager.RunInBatch(() => PreviewCursor._addLiveTextDoc(DocUtils.GetNewTextDoc('', newPoint[0], newPoint[1], 500, undefined, undefined, undefined, 750)), 'paste');
+                    UndoManager.RunInBatch(() => this._addLiveTextDoc?.(DocUtils.GetNewTextDoc('', newPoint[0], newPoint[1], 500, undefined, undefined, undefined, 750)), 'paste');
                 }
             }
             //pasting in images
@@ -84,17 +93,19 @@ export class PreviewCursor extends React.Component<{}> {
                 const re: any = /<img src="(.*?)"/g;
                 const arr: any[] = re.exec(e.clipboardData.getData('text/html'));
 
-                undoBatch(() => {
-                    const doc = Docs.Create.ImageDocument(arr[1], {
-                        _width: 300,
-                        title: arr[1],
-                        x: newPoint[0],
-                        y: newPoint[1],
-                    });
-                    ImageUtils.ExtractExif(doc);
-                    PreviewCursor._addDocument(doc);
-                })();
-            } else if (e.clipboardData.items.length) {
+                if (newPoint) {
+                    undoBatch(() => {
+                        const doc = Docs.Create.ImageDocument(arr[1], {
+                            _width: 300,
+                            title: arr[1],
+                            x: newPoint[0],
+                            y: newPoint[1],
+                        });
+                        ImageUtils.ExtractExif(doc);
+                        this._addDocument?.(doc);
+                    })();
+                }
+            } else if (e.clipboardData.items.length && newPoint) {
                 const batch = UndoManager.StartBatch('collection view drop');
                 const files: File[] = [];
                 Array.from(e.clipboardData.items).forEach(item => {
@@ -102,7 +113,7 @@ export class PreviewCursor extends React.Component<{}> {
                     file && files.push(file);
                 });
                 const generatedDocuments = await DocUtils.uploadFilesToDocs(files, { x: newPoint[0], y: newPoint[1] });
-                generatedDocuments.forEach(PreviewCursor._addDocument);
+                this._addDocument && generatedDocuments.forEach(this._addDocument);
                 batch.end();
             }
         }
@@ -135,25 +146,25 @@ export class PreviewCursor extends React.Component<{}> {
         ) {
             if ((!e.metaKey && !e.ctrlKey) || (e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 65 && e.keyCode <= 90)) {
                 //  /^[a-zA-Z0-9$*^%#@+-=_|}{[]"':;?/><.,}]$/.test(e.key)) {
-                PreviewCursor.Visible && PreviewCursor._onKeyPress?.(e);
-                ((!e.ctrlKey && !e.metaKey) || e.key !== 'v') && (PreviewCursor.Visible = false);
+                this.Visible && this._onKeyPress?.(e);
+                ((!e.ctrlKey && !e.metaKey) || e.key !== 'v') && (this.Visible = false);
             }
-        } else if (PreviewCursor.Visible) {
+        } else if (this.Visible) {
             if (e.key === 'ArrowRight') {
-                PreviewCursor._nudge?.(1 * (e.shiftKey ? 2 : 1), 0) && e.stopPropagation();
+                this._nudge?.(1 * (e.shiftKey ? 2 : 1), 0) && e.stopPropagation();
             } else if (e.key === 'ArrowLeft') {
-                PreviewCursor._nudge?.(-1 * (e.shiftKey ? 2 : 1), 0) && e.stopPropagation();
+                this._nudge?.(-1 * (e.shiftKey ? 2 : 1), 0) && e.stopPropagation();
             } else if (e.key === 'ArrowUp') {
-                PreviewCursor._nudge?.(0, 1 * (e.shiftKey ? 2 : 1)) && e.stopPropagation();
+                this._nudge?.(0, 1 * (e.shiftKey ? 2 : 1)) && e.stopPropagation();
             } else if (e.key === 'ArrowDown') {
-                PreviewCursor._nudge?.(0, -1 * (e.shiftKey ? 2 : 1)) && e.stopPropagation();
+                this._nudge?.(0, -1 * (e.shiftKey ? 2 : 1)) && e.stopPropagation();
             }
         }
     };
 
     //when focus is lost, this will remove the preview cursor
     @action onBlur = (): void => {
-        PreviewCursor.Visible = false;
+        this.Visible = false;
     };
 
     @action
@@ -167,23 +178,21 @@ export class PreviewCursor extends React.Component<{}> {
         nudge: undefined | ((nudgeX: number, nudgeY: number) => boolean),
         slowLoadDocuments: (files: File[] | string, options: DocumentOptions, generatedDocuments: Doc[], text: string, completed: ((doc: Doc[]) => void) | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => Promise<void>
     ) {
-        this._clickPoint = [x, y];
-        this._onKeyPress = onKeyPress;
-        this._addLiveTextDoc = addLiveText;
-        this._getTransform = getTransform;
-        this._addDocument = addDocument || returnFalse;
-        this._nudge = nudge;
-        this._slowLoadDocuments = slowLoadDocuments;
-        this.Visible = true;
+        const self = PreviewCursor.Instance;
+        if (self) {
+            self._clickPoint = [x, y];
+            self._onKeyPress = onKeyPress;
+            self._addLiveTextDoc = addLiveText;
+            self._getTransform = getTransform;
+            self._addDocument = addDocument || returnFalse;
+            self._nudge = nudge;
+            self._slowLoadDocuments = slowLoadDocuments;
+            self.Visible = true;
+        }
     }
     render() {
-        return !PreviewCursor._clickPoint || !PreviewCursor.Visible ? null : (
-            <div
-                className="previewCursor"
-                onBlur={this.onBlur}
-                tabIndex={0}
-                ref={e => e?.focus()}
-                style={{ color: lightOrDark(PreviewCursor.Doc?.backgroundColor ?? 'white'), transform: `translate(${PreviewCursor._clickPoint[0]}px, ${PreviewCursor._clickPoint[1]}px)` }}>
+        return !this._clickPoint || !this.Visible ? null : (
+            <div className="previewCursor" onBlur={this.onBlur} tabIndex={0} ref={e => e?.focus()} style={{ color: lightOrDark(this.Doc?.backgroundColor ?? 'white'), transform: `translate(${this._clickPoint[0]}px, ${this._clickPoint[1]}px)` }}>
                 I
             </div>
         );
-- 
cgit v1.2.3-70-g09d2

