mirror of
https://github.com/zvx-echo6/navi.git
synced 2026-05-20 14:44:51 +02:00
fix(ux): Three UX improvements for feature selection
Fix 1: Never zoom out when clicking a feature - preserves user's intentional zoom level by checking cameraForBounds before fitBounds Fix 2: Single-click to switch between features - clicking outside the current feature's circle clears selection and selects new feature Fix 3: View mode toggle reflects saved state on load - initialize viewMode from localStorage on store creation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
cd080b42f3
commit
869391ee4e
2 changed files with 19 additions and 5 deletions
|
|
@ -2097,15 +2097,21 @@ const MapView = forwardRef(function MapView(_, ref) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Outside circle → deselect, no new selection
|
// Outside circle → clear current selection and fall through to select new
|
||||||
store.clearClickMarker()
|
store.clearClickMarker()
|
||||||
store.clearSelectedPlace()
|
store.clearSelectedPlace()
|
||||||
// Clear boundary when deselecting
|
// Clear boundary when deselecting
|
||||||
if (updateBoundaryRef.current) updateBoundaryRef.current(null)
|
if (updateBoundaryRef.current) updateBoundaryRef.current(null)
|
||||||
setSelectedHighlight(map, null)
|
setSelectedHighlight(map, null)
|
||||||
|
// Fall through to State A to select new feature at click point
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// State A: nothing selected → select
|
|
||||||
|
// Select new feature at click point (State A or after clearing previous selection)
|
||||||
|
{
|
||||||
|
const store = useStore.getState() // refresh store state after potential clear
|
||||||
|
if (store.clickMarker) return // already handled above
|
||||||
|
|
||||||
if (window.innerWidth < 768) setSheetState('collapsed')
|
if (window.innerWidth < 768) setSheetState('collapsed')
|
||||||
|
|
||||||
const { lng, lat } = e.lngLat
|
const { lng, lat } = e.lngLat
|
||||||
|
|
@ -2414,7 +2420,15 @@ const MapView = forwardRef(function MapView(_, ref) {
|
||||||
// Validate bounds before fitting
|
// Validate bounds before fitting
|
||||||
if (minLng >= -180 && maxLng <= 180 && minLat >= -90 && maxLat <= 90 &&
|
if (minLng >= -180 && maxLng <= 180 && minLat >= -90 && maxLat <= 90 &&
|
||||||
minLng < maxLng && minLat < maxLat) {
|
minLng < maxLng && minLat < maxLat) {
|
||||||
map.fitBounds([[minLng, minLat], [maxLng, maxLat]], {
|
const bounds = [[minLng, minLat], [maxLng, maxLat]]
|
||||||
|
const currentZoom = map.getZoom()
|
||||||
|
const target = map.cameraForBounds(bounds, { padding: 50 })
|
||||||
|
// NEVER zoom out - user's zoom level is intentional
|
||||||
|
if (target && target.zoom < currentZoom) {
|
||||||
|
// Would zoom out — just draw the boundary without moving camera
|
||||||
|
return
|
||||||
|
}
|
||||||
|
map.fitBounds(bounds, {
|
||||||
padding: 50,
|
padding: 50,
|
||||||
duration: 700,
|
duration: 700,
|
||||||
maxZoom: 16,
|
maxZoom: 16,
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ export const useStore = create((set, get) => ({
|
||||||
autocompleteOpen: false,
|
autocompleteOpen: false,
|
||||||
theme: 'dark', // 'dark' | 'light' (resolved value — what's actually applied)
|
theme: 'dark', // 'dark' | 'light' (resolved value — what's actually applied)
|
||||||
themeOverride: null, // null | 'dark' | 'light' (manual override, persisted)
|
themeOverride: null, // null | 'dark' | 'light' (manual override, persisted)
|
||||||
viewMode: 'map', // 'map' | 'satellite' | 'hybrid'
|
viewMode: (typeof localStorage !== 'undefined' && localStorage.getItem('navi-view-mode')) || 'map', // 'map' | 'satellite' | 'hybrid'
|
||||||
|
|
||||||
setSheetState: (s) => set({ sheetState: s }),
|
setSheetState: (s) => set({ sheetState: s }),
|
||||||
setViewMode: (mode) => {
|
setViewMode: (mode) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue