From 4574b7f03ccc85c4bebdbfd9475788456086704f Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 8 Aug 2024 12:27:40 -0400
Subject: many changes to add typing in place of 'any's etc

---
 src/client/views/ScriptingRepl.tsx | 54 ++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 25 deletions(-)

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

diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx
index 1a2eb460f..2de867746 100644
--- a/src/client/views/ScriptingRepl.tsx
+++ b/src/client/views/ScriptingRepl.tsx
@@ -1,6 +1,4 @@
 /* eslint-disable react/no-array-index-key */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
@@ -14,21 +12,26 @@ import { OverlayView } from './OverlayView';
 import './ScriptingRepl.scss';
 import { DocumentIconContainer } from './nodes/DocumentIcon';
 import { DocumentView } from './nodes/DocumentView';
+import { returnFalse, setupMoveUpEvents } from '../../ClientUtils';
+import { emptyFunction } from '../../Utils';
+import { ObjectField } from '../../fields/ObjectField';
+import { RefField } from '../../fields/RefField';
+import { Doc, FieldResult, FieldType, Opt } from '../../fields/Doc';
 
 interface replValueProps {
     scrollToBottom: () => void;
-    value: any;
+    value: Opt<FieldResult | Promise<RefField | undefined>>;
     name?: string;
 }
 @observer
 export class ScriptingValueDisplay extends ObservableReactComponent<replValueProps> {
-    constructor(props: any) {
+    constructor(props: replValueProps) {
         super(props);
         makeObservable(this);
     }
 
     render() {
-        const val = this._props.name ? this._props.value[this._props.name] : this._props.value;
+        const val = this._props.value instanceof Doc && this._props.name ? this._props.value[this._props.name] : this._props.value;
         const title = (name: string) => (
             <>
                 {this._props.name ? <b>{this._props.name} : </b> : <> </>}
@@ -47,13 +50,14 @@ export class ScriptingValueDisplay extends ObservableReactComponent<replValuePro
 }
 interface ReplProps {
     scrollToBottom: () => void;
-    value: { [key: string]: any };
+    value: Opt<FieldResult | Promise<RefField | undefined>>;
     name?: string;
 }
+@observer
 export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps> {
     @observable collapsed = true;
 
-    constructor(props: any) {
+    constructor(props: ReplProps) {
         super(props);
         makeObservable(this);
     }
@@ -74,10 +78,12 @@ export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps>
                 {name}
             </>
         );
+        if (val === undefined) return '--undefined--';
+        if (val instanceof Promise) return '...Promise...';
         if (this.collapsed) {
             return (
                 <div className="scriptingObject-collapsed">
-                    <span onClick={this.toggle} className="scriptingObject-icon scriptingObject-iconCollapsed">
+                    <span onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.toggle)} className="scriptingObject-icon scriptingObject-iconCollapsed">
                         <FontAwesomeIcon icon="caret-right" size="sm" />
                     </span>
                     {title} (+{Object.keys(val).length})
@@ -94,8 +100,7 @@ export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps>
                 </div>
                 <div className="scriptingObject-fields">
                     {Object.keys(val).map(key => (
-                        // eslint-disable-next-line react/jsx-props-no-spreading
-                        <ScriptingValueDisplay {...this._props} name={key} />
+                        <ScriptingValueDisplay name={key} key={key} value={this._props.value} scrollToBottom={this._props.scrollToBottom} />
                     ))}
                 </div>
             </div>
@@ -104,13 +109,13 @@ export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps>
 }
 
 @observer
-export class ScriptingRepl extends ObservableReactComponent<{}> {
-    constructor(props: any) {
+export class ScriptingRepl extends ObservableReactComponent<object> {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
     }
 
-    @observable private commands: { command: string; result: any }[] = [];
+    @observable private commands: { command: string; result: unknown }[] = [];
     private commandsHistory: string[] = [];
 
     @observable private commandString: string = '';
@@ -120,13 +125,11 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
 
     private commandsRef = React.createRef<HTMLDivElement>();
 
-    private args: any = {};
-
     getTransformer = (): Transformer => ({
         transformer: context => {
             const knownVars: { [name: string]: number } = {};
             const usedDocuments: number[] = [];
-            ScriptingGlobals.getGlobals().forEach((global: any) => {
+            ScriptingGlobals.getGlobals().forEach((global: string) => {
                 knownVars[global] = 1;
             });
             return root => {
@@ -168,7 +171,7 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
         switch (e.key) {
             case 'Enter': {
                 e.stopPropagation();
-                const docGlobals: { [name: string]: any } = {};
+                const docGlobals: { [name: string]: FieldType } = {};
                 DocumentView.allViews().forEach((dv, i) => {
                     docGlobals[`d${i}`] = dv.Document;
                 });
@@ -176,19 +179,20 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
                 const script = CompileScript(this.commandString, { typecheck: false, addReturn: true, editable: true, params: { args: 'any' }, transformer: this.getTransformer(), globals });
                 if (!script.compiled) {
                     this.commands.push({ command: this.commandString, result: script.errors });
+                    this.maybeScrollToBottom();
                     return;
                 }
-                const result = undoable(() => script.run({ args: this.args }, () => this.commands.push({ command: this.commandString, result: e.toString() })), 'run:' + this.commandString)();
+                const result = undoable(() => script.run({}, e => this.commands.push({ command: this.commandString, result: e as string })), 'run:' + this.commandString)();
                 if (result.success) {
                     this.commands.push({ command: this.commandString, result: result.result });
                     this.commandsHistory.push(this.commandString);
 
-                    this.maybeScrollToBottom();
-
                     this.commandString = '';
                     this.commandBuffer = '';
                     this.historyIndex = -1;
                 }
+
+                this.maybeScrollToBottom();
                 break;
             }
             case 'ArrowUp': {
@@ -232,7 +236,7 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
     private shouldScroll: boolean = false;
     private maybeScrollToBottom = () => {
         const ele = this.commandsRef.current;
-        if (ele && ele.scrollTop === ele.scrollHeight - ele.offsetHeight) {
+        if (ele && Math.abs(Math.ceil(ele.scrollTop) - (ele.scrollHeight - ele.offsetHeight)) < 2) {
             this.shouldScroll = true;
             this.forceUpdate();
         }
@@ -240,14 +244,14 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
 
     private scrollToBottom() {
         const ele = this.commandsRef.current;
-        ele && ele.scroll({ behavior: 'auto', top: ele.scrollHeight });
+        ele?.scroll({ behavior: 'smooth', top: ele.scrollHeight });
     }
 
-    componentDidUpdate(prevProps: Readonly<{}>) {
+    componentDidUpdate(prevProps: Readonly<object>) {
         super.componentDidUpdate(prevProps);
         if (this.shouldScroll) {
             this.shouldScroll = false;
-            this.scrollToBottom();
+            setTimeout(() => this.scrollToBottom(), 0);
         }
     }
 
@@ -269,7 +273,7 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
                                 {command || <br />}
                             </div>
                             <div className="scriptingRepl-commandResult" style={{ background: SnappingManager.userBackgroundColor }}>
-                                <ScriptingValueDisplay scrollToBottom={this.maybeScrollToBottom} value={result} />
+                                <ScriptingValueDisplay scrollToBottom={this.maybeScrollToBottom} value={result as ObjectField | RefField} />
                             </div>
                         </div>
                     ))}
-- 
cgit v1.2.3-70-g09d2

