diff options
Diffstat (limited to 'src/client/views/nodes/MapBox/MapAnchorMenu.tsx')
-rw-r--r-- | src/client/views/nodes/MapBox/MapAnchorMenu.tsx | 340 |
1 files changed, 121 insertions, 219 deletions
diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx index f4e24d9c1..b1fb3368c 100644 --- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx +++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx @@ -1,6 +1,6 @@ -import React = require('react'); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { IReactionDisposer, ObservableMap, action, observable, reaction, runInAction } from 'mobx'; +import * as React from 'react'; +import { IReactionDisposer, ObservableMap, action, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, NumListCast, Opt } from '../../../../fields/Doc'; import { returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../../Utils'; @@ -11,29 +11,14 @@ import { Button, IconButton } from 'browndash-components'; import { SettingsManager } from '../../../util/SettingsManager'; import './MapAnchorMenu.scss'; import { NumCast, StrCast } from '../../../../fields/Types'; -import { - IconLookup, - faDiamondTurnRight, - faCalendarDays, - faEdit, - faAdd, - faRoute, - faArrowLeft, - faLocationDot, - faArrowDown, - faCar, - faBicycle, - faPersonWalking, - faUpload, - faArrowsRotate, - } from '@fortawesome/free-solid-svg-icons'; +import { IconLookup, faDiamondTurnRight, faCalendarDays, faEdit, faAdd, faRoute, faArrowLeft, faLocationDot, faArrowDown, faCar, faBicycle, faPersonWalking, faUpload, faArrowsRotate } from '@fortawesome/free-solid-svg-icons'; import { DirectionsAnchorMenu } from './DirectionsAnchorMenu'; import { Autocomplete, Checkbox, FormControlLabel, TextField } from '@mui/material'; import { MapboxApiUtility, TransportationType } from './MapboxApiUtility'; import { MapBox } from './MapBox'; import { List } from '../../../../fields/List'; import { MarkerIcons } from './MarkerIcons'; -import { CirclePicker, ColorState } from 'react-color'; +import { CirclePicker, ColorResult } from 'react-color'; import { Position } from 'geojson'; type MapAnchorMenuType = 'standard' | 'routeCreation' | 'calendar' | 'customize' | 'route'; @@ -75,8 +60,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { @action public setMenuType = (menuType: MapAnchorMenuType) => { this.menuType = menuType; - } - + }; private allMapPinDocs: Doc[] = []; @@ -86,31 +70,30 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { private title: string | undefined = undefined; - - public setPinDoc(pinDoc: Doc){ + public setPinDoc(pinDoc: Doc) { this.pinDoc = pinDoc; - this.title = StrCast(pinDoc.title ? pinDoc.title : `${NumCast(pinDoc.longitude)}, ${NumCast(pinDoc.latitude)}`) ; + this.title = StrCast(pinDoc.title ? pinDoc.title : `${NumCast(pinDoc.longitude)}, ${NumCast(pinDoc.latitude)}`); } - public setRouteDoc(routeDoc: Doc){ + public setRouteDoc(routeDoc: Doc) { this.routeDoc = routeDoc; - this.title = StrCast(routeDoc.title ?? 'Map route') + this.title = StrCast(routeDoc.title ?? 'Map route'); } public setAllMapboxPins(pinDocs: Doc[]) { this.allMapPinDocs = pinDocs; pinDocs.forEach((p, idx) => { console.log(`Pin ${idx}: ${p.title}`); - }) - } + }); + } public get Active() { return this._left > 0; } - constructor(props: Readonly<{}>) { + constructor(props: any) { super(props); - + makeObservable(this); MapAnchorMenu.Instance = this; MapAnchorMenu.Instance._canFade = false; } @@ -125,7 +108,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { componentDidMount() { this._disposer = reaction( - () => SelectionManager.Views().slice(), + () => SelectionManager.Views.slice(), sel => MapAnchorMenu.Instance.fadeOut(true) ); } @@ -164,55 +147,52 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { // return this.top // } - - @action DirectionsClick = () => { this.menuType = 'routeCreation'; - } + }; @action CustomizeClick = () => { this.currentRouteInfoMap = undefined; this.menuType = 'customize'; - } + }; @action BackClick = () => { this.currentRouteInfoMap = undefined; this.menuType = 'standard'; - } + }; @action TriggerFileInputClick = () => { if (this._fileInputRef) { this._fileInputRef.current?.click(); // Trigger the file input click event - } - } + } + }; - @action - onMarkerColorChange = (color: ColorState) => { - if (this.pinDoc){ + @action + onMarkerColorChange = (color: ColorResult) => { + if (this.pinDoc) { this.pinDoc.markerColor = color.hex; } - } + }; revertToOriginalMarker = () => { if (this.pinDoc) { - this.pinDoc.markerType = "MAP_PIN"; - this.pinDoc.markerColor = "#ff5722"; + this.pinDoc.markerType = 'MAP_PIN'; + this.pinDoc.markerColor = '#ff5722'; } - } + }; onMarkerIconChange = (iconKey: string) => { if (this.pinDoc) { this.pinDoc.markerType = iconKey; } - } - + }; @observable - destinationFeatures: any[] = [] + destinationFeatures: any[] = []; @observable destinationSelected: boolean = false; @@ -220,7 +200,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { @observable selectedDestinationFeature: any = undefined; - @observable + @observable createPinForDestination: boolean = true; @observable @@ -231,98 +211,85 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { @action handleTransportationTypeChange = (newType: TransportationType) => { - if (newType !== this.selectedTransportationType){ + if (newType !== this.selectedTransportationType) { this.selectedTransportationType = newType; this.DisplayRoute(this.currentRouteInfoMap, newType); } - - } + }; @action handleSelectedDestinationFeature = (destinationFeature: any) => { this.selectedDestinationFeature = destinationFeature; - } + }; @action toggleCreatePinForDestinationCheckbox = () => { this.createPinForDestination = !this.createPinForDestination; - } + }; @action handleDestinationSearchChange = async (searchText: string) => { if (this.selectedDestinationFeature !== undefined) this.selectedDestinationFeature = undefined; const features = await MapboxApiUtility.forwardGeocodeForFeatures(searchText); - if (features){ + if (features) { runInAction(() => { this.destinationFeatures = features; - - }) + }); } - } + }; getRoutes = async (destinationFeature: any) => { const currentPinLong: number = NumCast(this.pinDoc?.longitude); const currentPinLat: number = NumCast(this.pinDoc?.latitude); - if (currentPinLong && currentPinLat && destinationFeature.center){ + if (currentPinLong && currentPinLat && destinationFeature.center) { const routeInfoMap = await MapboxApiUtility.getDirections([currentPinLong, currentPinLat], destinationFeature.center); if (routeInfoMap) { runInAction(() => { this.currentRouteInfoMap = routeInfoMap; - }) + }); this.DisplayRoute(routeInfoMap, 'driving'); } } - // get route menu, set it equal to here - // create a temporary route + // get route menu, set it equal to here + // create a temporary route // create pin if createPinForDestination was clicked - } + }; HandleAddRouteClick = () => { - if (this.currentRouteInfoMap && this.selectedTransportationType && this.selectedDestinationFeature){ + if (this.currentRouteInfoMap && this.selectedTransportationType && this.selectedDestinationFeature) { const coordinates = this.currentRouteInfoMap[this.selectedTransportationType].coordinates; console.log(coordinates); console.log(this.selectedDestinationFeature); - this.AddNewRouteToMap(coordinates, this.title ?? "", this.selectedDestinationFeature, this.createPinForDestination); + this.AddNewRouteToMap(coordinates, this.title ?? '', this.selectedDestinationFeature, this.createPinForDestination); this.HideRoute(); } - } + }; getMarkerIcon = (): JSX.Element | undefined => { - if (this.pinDoc){ + if (this.pinDoc) { const markerType = StrCast(this.pinDoc.markerType); const markerColor = StrCast(this.pinDoc.markerColor); return MarkerIcons.getFontAwesomeIcon(markerType, '2x', markerColor); } return undefined; - } - + }; render() { const buttons = ( - <div className='menu-buttons' style={{display: 'flex'}}> - {this.menuType === 'standard' && + <div className="menu-buttons" style={{ display: 'flex' }}> + {this.menuType === 'standard' && ( <> <IconButton - tooltip="Delete Pin" // - onPointerDown={this.Delete} - icon={<FontAwesomeIcon icon="trash-alt" />} - color={SettingsManager.userColor} - /> - <IconButton - tooltip='Get directions' - onPointerDown={this.DirectionsClick} /**TODO: fix */ - icon={<FontAwesomeIcon icon={faDiamondTurnRight as IconLookup}/>} - color={SettingsManager.userColor} - /> - <IconButton - tooltip='Add to calendar' - onPointerDown={this.Delete} /**TODO: fix */ - icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup}/>} + tooltip="Delete Pin" // + onPointerDown={this.Delete} + icon={<FontAwesomeIcon icon="trash-alt" />} color={SettingsManager.userColor} /> + <IconButton tooltip="Get directions" onPointerDown={this.DirectionsClick} /**TODO: fix */ icon={<FontAwesomeIcon icon={faDiamondTurnRight as IconLookup} />} color={SettingsManager.userColor} /> + <IconButton tooltip="Add to calendar" onPointerDown={this.Delete} /**TODO: fix */ icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} color={SettingsManager.userColor} /> <div ref={this._commentRef}> <IconButton tooltip="Link Note to Pin" // @@ -331,12 +298,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { color={SettingsManager.userColor} /> </div> - <IconButton - tooltip="Customize pin" - onPointerDown={this.CustomizeClick} - icon={<FontAwesomeIcon icon={faEdit as IconLookup}/>} - color={SettingsManager.userColor} - /> + <IconButton tooltip="Customize pin" onPointerDown={this.CustomizeClick} icon={<FontAwesomeIcon icon={faEdit as IconLookup} />} color={SettingsManager.userColor} /> <IconButton tooltip="Center on pin" // onPointerDown={this.Center} @@ -344,8 +306,8 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { color={SettingsManager.userColor} /> </> - } - {this.menuType === 'routeCreation' && + )} + {this.menuType === 'routeCreation' && ( <> <IconButton tooltip="Go back" // @@ -360,8 +322,8 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { color={SettingsManager.userColor} /> </> - } - {this.menuType === 'route' && + )} + {this.menuType === 'route' && ( <> <IconButton tooltip="Delete Route" // @@ -369,12 +331,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { icon={<FontAwesomeIcon icon="trash-alt" />} color={SettingsManager.userColor} /> - <IconButton - tooltip='Animate route' - onPointerDown={() => this.OpenAnimationPanel(this.routeDoc)} /**TODO: fix */ - icon={<FontAwesomeIcon icon={faRoute as IconLookup}/>} - color={SettingsManager.userColor} - /> + <IconButton tooltip="Animate route" onPointerDown={() => this.OpenAnimationPanel(this.routeDoc)} /**TODO: fix */ icon={<FontAwesomeIcon icon={faRoute as IconLookup} />} color={SettingsManager.userColor} /> <div ref={this._commentRef}> <IconButton tooltip="Link Note to Pin" // @@ -383,17 +340,10 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { color={SettingsManager.userColor} /> </div> - <IconButton - tooltip='Add to calendar' - onPointerDown={this.Delete} /**TODO: fix */ - icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup}/>} - color={SettingsManager.userColor} - /> - + <IconButton tooltip="Add to calendar" onPointerDown={this.Delete} /**TODO: fix */ icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} color={SettingsManager.userColor} /> </> - - } - {this.menuType === 'customize' && + )} + {this.menuType === 'customize' && ( <> <IconButton tooltip="Go back" // @@ -408,9 +358,8 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { color={SettingsManager.userColor} /> </> - } - - + )} + {/* {this.IsTargetToggler !== returnFalse && ( <Toggle tooltip={'Make target visibility toggle on click'} @@ -432,68 +381,37 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { // ) return this.getElement( - <div - ref={MapAnchorMenu.top} - className='map-anchor-menu-container'> - {this.menuType === 'standard' && - <div>{this.title}</div> - } - {this.menuType === 'routeCreation' && - <div className='direction-inputs' style={{display: 'flex', flexDirection: 'column'}}> - <TextField - fullWidth - disabled - value={this.title} - /> - <FontAwesomeIcon icon={faArrowDown as IconLookup} size='xs'/> + <div ref={MapAnchorMenu.top} className="map-anchor-menu-container"> + {this.menuType === 'standard' && <div>{this.title}</div>} + {this.menuType === 'routeCreation' && ( + <div className="direction-inputs" style={{ display: 'flex', flexDirection: 'column' }}> + <TextField fullWidth disabled value={this.title} /> + <FontAwesomeIcon icon={faArrowDown as IconLookup} size="xs" /> <Autocomplete fullWidth id="route-destination-searcher" - - onInputChange={(e, searchText) => this.handleDestinationSearchChange(searchText)} - onChange={(e, feature, reason) => { - if (reason === 'clear'){ + onInputChange={(e: any, searchText: any) => this.handleDestinationSearchChange(searchText)} + onChange={(e: any, feature: any, reason: any) => { + if (reason === 'clear') { this.handleSelectedDestinationFeature(undefined); - } else if (reason === 'selectOption'){ + } else if (reason === 'selectOption') { this.handleSelectedDestinationFeature(feature); } }} - options={this.destinationFeatures - .filter(feature => feature.place_name) - .map(feature => feature)} - getOptionLabel={(feature) => feature.place_name} - renderInput={(params) => ( - <TextField - {...params} - placeholder='Enter a destination' - /> - )} + options={this.destinationFeatures.filter(feature => feature.place_name).map(feature => feature)} + getOptionLabel={(feature: any) => feature.place_name} + renderInput={(params: any) => <TextField {...params} placeholder="Enter a destination" />} /> - {this.selectedDestinationFeature && + {this.selectedDestinationFeature && ( <> - {!this.allMapPinDocs.some(pinDoc => pinDoc.title === this.selectedDestinationFeature.place_name) && - <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '5px'}}> - <FormControlLabel - label='Create pin for destination?' - control={ - <Checkbox - color='success' - checked={this.createPinForDestination} - onChange={this.toggleCreatePinForDestinationCheckbox} - /> - } - /> - </div> - } + {!this.allMapPinDocs.some(pinDoc => pinDoc.title === this.selectedDestinationFeature.place_name) && ( + <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '5px' }}> + <FormControlLabel label="Create pin for destination?" control={<Checkbox color="success" checked={this.createPinForDestination} onChange={this.toggleCreatePinForDestinationCheckbox} />} /> + </div> + )} </> - - - } - <button - id='get-routes-button' - disabled={this.selectedDestinationFeature ? false : true} - onClick={() => this.getRoutes(this.selectedDestinationFeature)} - > + )} + <button id="get-routes-button" disabled={this.selectedDestinationFeature ? false : true} onClick={() => this.getRoutes(this.selectedDestinationFeature)}> Get routes </button> @@ -501,74 +419,58 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> { placeholder="Origin" /> */} </div> - } - {this.currentRouteInfoMap && - <div className='current-route-info-container'> - <div className='transportation-icons-container'> + )} + {this.currentRouteInfoMap && ( + <div className="current-route-info-container"> + <div className="transportation-icons-container"> <IconButton - tooltip="Driving route" + tooltip="Driving route" onPointerDown={() => this.handleTransportationTypeChange('driving')} - icon={<FontAwesomeIcon icon={faCar as IconLookup}/>} - color={this.selectedTransportationType === 'driving' ? 'lightblue': 'grey'} + icon={<FontAwesomeIcon icon={faCar as IconLookup} />} + color={this.selectedTransportationType === 'driving' ? 'lightblue' : 'grey'} /> <IconButton - tooltip="Cycling route" + tooltip="Cycling route" onPointerDown={() => this.handleTransportationTypeChange('cycling')} - icon={<FontAwesomeIcon icon={faBicycle as IconLookup}/>} - color={this.selectedTransportationType === 'cycling' ? 'lightblue': 'grey'} + icon={<FontAwesomeIcon icon={faBicycle as IconLookup} />} + color={this.selectedTransportationType === 'cycling' ? 'lightblue' : 'grey'} /> <IconButton - tooltip="Walking route" + tooltip="Walking route" onPointerDown={() => this.handleTransportationTypeChange('walking')} - icon={<FontAwesomeIcon icon={faPersonWalking as IconLookup}/>} - color={this.selectedTransportationType === 'walking' ? 'lightblue': 'grey'} + icon={<FontAwesomeIcon icon={faPersonWalking as IconLookup} />} + color={this.selectedTransportationType === 'walking' ? 'lightblue' : 'grey'} /> </div> - <div className='selected-route-details-container'> + <div className="selected-route-details-container"> <div>Duration: {this.currentRouteInfoMap[this.selectedTransportationType].duration}</div> <div>Distance: {this.currentRouteInfoMap[this.selectedTransportationType].distance}</div> </div> </div> - - - } - {this.menuType === 'customize' && - <div className='customized-marker-container'> - <div className='current-marker-container'> - <div>Current Marker: </div> - <div> - {this.getMarkerIcon()} + )} + {this.menuType === 'customize' && ( + <div className="customized-marker-container"> + <div className="current-marker-container"> + <div>Current Marker: </div> + <div>{this.getMarkerIcon()}</div> </div> + <div className="color-picker-container" style={{ marginBottom: '10px' }}> + <CirclePicker circleSize={15} circleSpacing={7} width="100%" onChange={color => this.onMarkerColorChange(color)} /> + </div> + <div className="all-markers-container"> + {Object.keys(MarkerIcons.FAMarkerIconsMap).map(iconKey => ( + <div key={iconKey} className="marker-icon"> + <IconButton onPointerDown={() => this.onMarkerIconChange(iconKey)} icon={MarkerIcons.getFontAwesomeIcon(iconKey, '1x', 'white')} /> + </div> + ))} + </div> + <div style={{ width: '100%', height: '3px', color: 'white' }}></div> </div> - <div className='color-picker-container' style={{marginBottom: '10px'}}> - <CirclePicker - circleSize={15} - circleSpacing={7} - width='100%' - onChange={(color) => this.onMarkerColorChange(color)} - /> - </div> - <div className='all-markers-container'> - {Object.keys(MarkerIcons.FAMarkerIconsMap).map((iconKey) => ( - <div key={iconKey} className='marker-icon'> - <IconButton - onPointerDown={() => this.onMarkerIconChange(iconKey)} - icon={MarkerIcons.getFontAwesomeIcon(iconKey, '1x', 'white')} - /> - </div> - ))} - </div> - <div style={{width: '100%', height:'3px', color: 'white'}}></div> - </div> - } - {this.menuType === 'route' && this.routeDoc && - <div> - {StrCast(this.routeDoc.title)} - </div> - - } + )} + {this.menuType === 'route' && this.routeDoc && <div>{StrCast(this.routeDoc.title)}</div>} {buttons} - </div> - , true); + </div>, + true + ); } } |