diff --git a/package.json b/package.json index c0a1581ff..2aaf35c75 100644 --- a/package.json +++ b/package.json @@ -148,7 +148,7 @@ "i18next-http-backend": "^1.4.0", "knex": "^2.4.2", "leaflet": "1.9.4", - "leaflet.locatecontrol": "^0.73.0", + "leaflet.locatecontrol": "^0.79.0", "lodash.debounce": "^4.0.8", "moment-timezone": "^0.5.43", "morgan": "^1.10.0", diff --git a/src/assets/css/main.css b/src/assets/css/main.css index 1f9128227..fea0c289e 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -55,6 +55,11 @@ body { border-radius: 0.5rem !important; } +.leaflet-control-locate > a { + font-size: 16.8px; + padding-left: 1.5px; +} + .table-pvp { margin-left: auto; margin-right: auto; diff --git a/src/components/Layers.jsx b/src/components/Layers.jsx index c4f5185cb..4000e596b 100644 --- a/src/components/Layers.jsx +++ b/src/components/Layers.jsx @@ -1,6 +1,6 @@ // @ts-check import * as React from 'react' -import { TileLayer, ZoomControl, useMap } from 'react-leaflet' +import { TileLayer, useMap } from 'react-leaflet' import { control } from 'leaflet' import { useStore } from '@hooks/useStore' @@ -12,10 +12,21 @@ export function ControlledTileLayer() { } export function ControlledZoomLayer() { + const map = useMap() const navSetting = useStore( (state) => state.settings.navigationControls === 'leaflet', ) - return navSetting ? : null + + React.useLayoutEffect(() => { + if (navSetting) { + const zoom = control.zoom({ position: 'bottomright' }).addTo(map) + return () => { + zoom.remove() + } + } + }, [navSetting]) + + return null } export function ControlledLocate() { diff --git a/src/components/layout/FloatingBtn.jsx b/src/components/layout/FloatingBtn.jsx index 570e5e75c..3981303f4 100644 --- a/src/components/layout/FloatingBtn.jsx +++ b/src/components/layout/FloatingBtn.jsx @@ -65,7 +65,7 @@ const handleClick = (name) => () => { } } -export default function FloatingButtons() { +export function FloatingButtons() { const { t } = useTranslation() const { data } = useQuery(FAB_BUTTONS, { fetchPolicy: 'cache-first', @@ -258,3 +258,5 @@ export default function FloatingButtons() { ) } + +export const FloatingButtonsMemo = React.memo(FloatingButtons, () => true) diff --git a/src/components/layout/Nav.jsx b/src/components/layout/Nav.jsx index 7da23364b..9ad718095 100644 --- a/src/components/layout/Nav.jsx +++ b/src/components/layout/Nav.jsx @@ -2,7 +2,7 @@ import * as React from 'react' import { useStatic } from '@hooks/useStore' -import FloatingBtn from './FloatingBtn' +import { FloatingButtonsMemo } from './FloatingBtn' import Sidebar from './drawer/Drawer' import FilterMenu from './dialogs/filters/FilterMenu' import UserOptions from './dialogs/UserOptions' @@ -30,7 +30,7 @@ export const Nav = React.memo( return ( <> - + diff --git a/src/components/layout/dialogs/webhooks/human/Location.jsx b/src/components/layout/dialogs/webhooks/human/Location.jsx index 06026feda..a62ddac6b 100644 --- a/src/components/layout/dialogs/webhooks/human/Location.jsx +++ b/src/components/layout/dialogs/webhooks/human/Location.jsx @@ -19,6 +19,7 @@ import { setHuman } from '@services/queries/webhook' import { WEBHOOK_NOMINATIM } from '@services/queries/geocoder' import useLocation from '@hooks/useLocation' import { Loading } from '@components/layout/general/Loading' +import { basicEqualFn } from '@hooks/useStore' import { setModeBtn, useWebhookStore } from '../store' import { useSyncData } from '../hooks' @@ -27,7 +28,7 @@ const Location = () => { const { lc, color } = useLocation() const { t } = useTranslation() - const webhookLocation = useWebhookStore((s) => s.location) + const webhookLocation = useWebhookStore((s) => s.location, basicEqualFn) const { data: { latitude, longitude }, loading: loadingHuman, @@ -46,9 +47,11 @@ const Location = () => { /** @param {[number, number]} location */ const handleLocationChange = (location) => { if (location.every((x) => x !== 0)) { - useWebhookStore.setState({ - location: [location[0] ?? 0, location[1] ?? 0], - }) + useWebhookStore.setState((prev) => ({ + location: prev.location.some((x, i) => x !== location[i]) + ? [location[0] ?? 0, location[1] ?? 0] + : prev.location, + })) save({ variables: { category: 'setLocation', @@ -194,6 +197,6 @@ const Location = () => { ) } -const MemoizedLocation = React.memo(Location, () => true) +const LocationMemo = React.memo(Location, () => true) -export default MemoizedLocation +export default LocationMemo diff --git a/src/components/layout/dialogs/webhooks/human/index.jsx b/src/components/layout/dialogs/webhooks/human/index.jsx index 6bc2bae95..7f4a9a43a 100644 --- a/src/components/layout/dialogs/webhooks/human/index.jsx +++ b/src/components/layout/dialogs/webhooks/human/index.jsx @@ -20,4 +20,6 @@ const Human = () => ( ) -export default Human +const HumanMemo = React.memo(Human, () => true) + +export default HumanMemo diff --git a/src/hooks/useLocation.js b/src/hooks/useLocation.js index 374a0ae5d..44ddde7b3 100644 --- a/src/hooks/useLocation.js +++ b/src/hooks/useLocation.js @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { useMemo, useState } from 'react' import { LayerGroup, DomEvent, DomUtil, Control } from 'leaflet' import { useTranslation } from 'react-i18next' import { useMap } from 'react-leaflet' @@ -13,7 +13,7 @@ export default function useLocation() { const [color, setColor] = useState('inherit') const { t } = useTranslation() - const [lc] = useState(() => { + const lc = useMemo(() => { const LocateFab = Control.Locate.extend({ _setClasses(state) { if (state === 'requesting') setColor('secondary') @@ -76,6 +76,6 @@ export default function useLocation() { }, }).addTo(map) return result - }) + }, [map, t]) return { lc, color } } diff --git a/yarn.lock b/yarn.lock index 90d896679..76233ea34 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5859,10 +5859,10 @@ language-tags@^1.0.9: dependencies: language-subtag-registry "^0.3.20" -leaflet.locatecontrol@^0.73.0: - version "0.73.0" - resolved "https://registry.yarnpkg.com/leaflet.locatecontrol/-/leaflet.locatecontrol-0.73.0.tgz#768d9edb0470f86c913ea6c2a70ec62380fd45c5" - integrity sha512-e6v6SyDU2nzG5AiH80eH7qhXw5J+EfgmEFHkuzTRC9jqCSbfAm/3HlZDuoa9WYsaZbn5ovvqNeaLW/JSMsgg5g== +leaflet.locatecontrol@^0.79.0: + version "0.79.0" + resolved "https://registry.yarnpkg.com/leaflet.locatecontrol/-/leaflet.locatecontrol-0.79.0.tgz#0236b87c699a49f9ddb2f289941fbc0d3c3f8b62" + integrity sha512-h64QIHFkypYdr90lkSfjKvPvvk8/b8UnP3m9WuoWdp5p2AaCWC0T1NVwyuj4rd5U4fBW3tQt4ppmZ2LceHMIDg== leaflet@1.9.4: version "1.9.4"