From 58a80118b8b219417e4b22839b1d2bde197b0eb6 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 20 Mar 2025 14:34:32 -0400
Subject: mapbox cleanup.  fix runtime warnings for stacking view.

---
 src/client/views/nodes/MapBox/MapBox.tsx | 110 +++++++++++++------------------
 1 file changed, 45 insertions(+), 65 deletions(-)

(limited to 'src/client/views/nodes/MapBox/MapBox.tsx')

diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index d642784c0..11a709faf 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -1,8 +1,8 @@
-import { IconLookup, faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons';
+import { IconButton, Size, Type } from '@dash/components';
+import { faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Checkbox, FormControlLabel, TextField } from '@mui/material';
 import * as turf from '@turf/turf';
-import { IconButton, Size, Type } from '@dash/components';
 import * as d3 from 'd3';
 import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString } from 'geojson';
 import { LngLatBoundsLike, LngLatLike, MapLayerMouseEvent } from 'mapbox-gl';
@@ -14,7 +14,10 @@ import { Layer, MapProvider, MapRef, Map as MapboxMap, Marker, Source, ViewState
 import { ClientUtils, setupMoveUpEvents } from '../../../../ClientUtils';
 import { emptyFunction } from '../../../../Utils';
 import { Doc, DocListCast, Field, LinkedTo, Opt, StrListCast } from '../../../../fields/Doc';
+import { List } from '../../../../fields/List';
+import { RichTextField } from '../../../../fields/RichTextField';
 import { DocCast, NumCast, StrCast, toList } from '../../../../fields/Types';
+import { TraceMobx } from '../../../../fields/util';
 import { DocUtils } from '../../../documents/DocUtils';
 import { DocumentType } from '../../../documents/DocumentTypes';
 import { Docs } from '../../../documents/Documents';
@@ -34,8 +37,6 @@ import { MapAnchorMenu } from './MapAnchorMenu';
 import './MapBox.scss';
 import { MapboxApiUtility, TransportationType } from './MapboxApiUtility';
 import { MarkerIcons } from './MarkerIcons';
-import { RichTextField } from '../../../../fields/RichTextField';
-import { List } from '../../../../fields/List';
 // import { GeocoderControl } from './GeocoderControl';
 
 // amongus
@@ -657,9 +658,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                     MapAnchorMenu.Instance.Center = this.centerOnSelectedPin;
                     MapAnchorMenu.Instance.OnClick = this.createNoteAnnotation;
                     MapAnchorMenu.Instance.StartDrag = this.startAnchorDrag;
-
                     MapAnchorMenu.Instance.Reset();
-
                     MapAnchorMenu.Instance.setRouteDoc(routeDoc);
 
                     // TODO: Subject to change
@@ -822,10 +821,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
 
     @computed
     get preAnimationViewState() {
-        if (!this._isAnimating) {
-            return this.mapboxMapViewState;
-        }
-        return undefined;
+        return !this._isAnimating ? this.mapboxMapViewState : undefined;
     }
 
     @action
@@ -835,24 +831,15 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
 
     @action
     updateAnimationSpeed = () => {
-        let newAnimationSpeed: AnimationSpeed;
+        this._animationSpeed = (() => {
         switch (this._animationSpeed) {
-            case AnimationSpeed.SLOW:
-                newAnimationSpeed = AnimationSpeed.MEDIUM;
-                break;
-            case AnimationSpeed.MEDIUM:
-                newAnimationSpeed = AnimationSpeed.FAST;
-                break;
-            case AnimationSpeed.FAST:
-                newAnimationSpeed = AnimationSpeed.SLOW;
-                break;
-            default:
-                newAnimationSpeed = AnimationSpeed.MEDIUM;
-                break;
-        }
-        this._animationSpeed = newAnimationSpeed;
+            case AnimationSpeed.SLOW:   return AnimationSpeed.MEDIUM;
+            case AnimationSpeed.MEDIUM: return AnimationSpeed.FAST;
+            case AnimationSpeed.FAST:   return AnimationSpeed.SLOW;
+            default:                    return AnimationSpeed.MEDIUM;
+        }})(); // prettier-ignore
         if (this._animationUtility) {
-            this._animationUtility.updateAnimationSpeed(newAnimationSpeed);
+            this._animationUtility.updateAnimationSpeed(this._animationSpeed);
         }
     };
     @computed get animationSpeedTooltipText(): string {
@@ -879,19 +866,16 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         this._animationUtility?.updateIsStreetViewAnimation(newVal);
     };
 
-    getFeatureFromRouteDoc = (routeDoc: Doc): Feature<Geometry, GeoJsonProperties> => {
-        const geometry: LineString = {
+    getFeatureFromRouteDoc = (routeDoc: Doc): Feature<Geometry, GeoJsonProperties> => ({
+        type: 'Feature',
+        properties: {
+            routeTitle: routeDoc.title,
+        },
+        geometry: {
             type: 'LineString',
             coordinates: JSON.parse(StrCast(routeDoc.routeCoordinates)),
-        };
-        return {
-            type: 'Feature',
-            properties: {
-                routeTitle: routeDoc.title,
-            },
-            geometry: geometry,
-        };
-    };
+        },
+    });
 
     @action
     playAnimation = (status: AnimationStatus) => {
@@ -1014,7 +998,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                         this.playAnimation(AnimationStatus.START); // Play from the beginning
                     }
                 }}
-                icon={this._isAnimating && this._finishedFlyTo ? <FontAwesomeIcon icon={faPause as IconLookup} /> : <FontAwesomeIcon icon={faPlay as IconLookup} />}
+                icon={<FontAwesomeIcon icon={this._isAnimating && this._finishedFlyTo ? faPause : faPlay} />}
                 color="black"
                 size={Size.MEDIUM}
             />
@@ -1025,12 +1009,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                         this.stopAnimation(false);
                         this.playAnimation(AnimationStatus.START);
                     }}
-                    icon={<FontAwesomeIcon icon={faRotate as IconLookup} />}
+                    icon={<FontAwesomeIcon icon={faRotate} />}
                     color="black"
                     size={Size.MEDIUM}
                 />
             )}
-            <IconButton style={{ marginRight: '10px' }} tooltip="Stop and close animation" onPointerDown={() => this.stopAnimation(true)} icon={<FontAwesomeIcon icon={faCircleXmark as IconLookup} />} color="black" size={Size.MEDIUM} />
+            <IconButton style={{ marginRight: '10px' }} tooltip="Stop and close animation" onPointerDown={() => this.stopAnimation(true)} icon={<FontAwesomeIcon icon={faCircleXmark} />} color="black" size={Size.MEDIUM} />
             <div className="animation-suboptions">
                 <div>|</div>
                 <FormControlLabel className="first-person-label" label="1st person animation:" labelPlacement="start" control={<Checkbox color="success" checked={this._isStreetViewAnimation} onChange={this.toggleIsStreetViewAnimation} />} />
@@ -1125,16 +1109,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         this._showTerrain = !this._showTerrain;
     };
 
-    getMarkerIcon = (pinDoc: Doc): JSX.Element | null => {
-        const markerType = StrCast(pinDoc.markerType);
-        const markerColor = StrCast(pinDoc.markerColor);
-
-        return MarkerIcons.getFontAwesomeIcon(markerType, '2x', markerColor) ?? null;
-    };
+    getMarkerIcon = (pinDoc: Doc) => MarkerIcons.getFontAwesomeIcon(StrCast(pinDoc.markerType), '2x', StrCast(pinDoc.markerColor)) ?? null;
 
     render() {
-        const scale = this._props.NativeDimScaling?.() || 1;
-        const parscale = scale === 1 ? 1 : (this.ScreenToLocalBoxXf().Scale ?? 1);
+        TraceMobx();
+        const scale = (this._props.NativeDimScaling?.() || 1) + 0.001; // bcz: weird, but without this hack, MapBox doesn't locate map correctly
+        const parscale = this.ScreenToLocalBoxXf().Scale;
 
         return (
             <div className="mapBox" ref={this._ref}>
@@ -1142,13 +1122,13 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                     className="mapBox-wrapper"
                     onWheel={e => e.stopPropagation()}
                     onPointerDown={e => e.button === 0 && !e.ctrlKey && e.stopPropagation()}
-                    style={{ transformOrigin: 'top left', transform: `scale(${scale})`, width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}>
+                    style={{ transform: `scale(${scale})`, width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}>
                     {!this._routeToAnimate && (
                         <div className="mapBox-searchbar" style={{ width: `${100 / scale}%`, zIndex: 1, position: 'relative', background: 'lightGray' }}>
                             <TextField fullWidth placeholder="Enter a location" onKeyDown={this.searchbarKeyDown} onChange={e => this.handleSearchChange(e.target.value)} />
-                            <IconButton icon={<FontAwesomeIcon icon={faGear as IconLookup} size="1x" />} type={Type.TERT} onClick={() => this.toggleSettings()} />
+                            <IconButton icon={<FontAwesomeIcon icon={faGear} size="1x" />} type={Type.TERT} onClick={this.toggleSettings} />
                             <div style={{ opacity: 0 }}>
-                                <IconButton icon={<FontAwesomeIcon icon={faGear as IconLookup} size="1x" />} type={Type.TERT} onClick={() => this.toggleSettings()} />
+                                <IconButton icon={<FontAwesomeIcon icon={faGear} size="1x" />} type={Type.TERT} onClick={this.toggleSettings} />
                             </div>
                         </div>
                     )}
@@ -1214,9 +1194,10 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                     )}
                     <MapProvider>
                         <MapboxMap
+                            key={'' + this.Document.x + this.Document.y} // force map to rerender after dragging, otherwise it will display the wrong location until it gets re-rendered
                             ref={this._mapRef}
                             mapboxAccessToken={MAPBOX_ACCESS_TOKEN}
-                            viewState={this._isAnimating || this._routeToAnimate ? undefined : { ...this.mapboxMapViewState, width: NumCast(this.layoutDoc._width), height: NumCast(this.layoutDoc._height) }}
+                            viewState={this._isAnimating || this._routeToAnimate ? undefined : { ...this.mapboxMapViewState, width: this._props.PanelWidth(), height: this._props.PanelHeight() }}
                             mapStyle={this.dataDoc.map_style ? StrCast(this.dataDoc.map_style) : 'mapbox://styles/mapbox/streets-v11'}
                             style={{
                                 position: 'absolute',
@@ -1299,19 +1280,18 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                                     />
                                 </>
                             )}
-
-                            {!this._isAnimating &&
-                                this._animationPhase === 0 &&
-                                this.allPushpins // .filter(anno => !anno.layout_unrendered)
-                                    .map((pushpin, idx) => (
-                                        <Marker key={idx} longitude={NumCast(pushpin.longitude)} latitude={NumCast(pushpin.latitude)} anchor="bottom" onClick={e => this.handleMarkerClick(e.originalEvent.clientX, e.originalEvent.clientY, pushpin)}>
-                                            {this.getMarkerIcon(pushpin)}
-                                        </Marker>
-                                    ))}
-
-                            {/* {this.mapMarkers.length > 0 && this.mapMarkers.map((marker, idx) => (
-                                <Marker key={idx} longitude={marker.longitude} latitude={marker.latitude}/>
-                            ))} */}
+                            {this._isAnimating || this._animationPhase
+                                ? null
+                                : this.allPushpins.map(p => (
+                                      <Marker
+                                          key={'' + p.longitude + p.latitude}
+                                          longitude={NumCast(p.longitude)}
+                                          latitude={NumCast(p.latitude)}
+                                          anchor="bottom"
+                                          onClick={e => this.handleMarkerClick(e.originalEvent.clientX, e.originalEvent.clientY, p)}>
+                                          {this.getMarkerIcon(p)}
+                                      </Marker>
+                                  ))}
                         </MapboxMap>
                     </MapProvider>
                 </div>
-- 
cgit v1.2.3-70-g09d2

