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 {
|
||||
// Outside circle → deselect, no new selection
|
||||
// Outside circle → clear current selection and fall through to select new
|
||||
store.clearClickMarker()
|
||||
store.clearSelectedPlace()
|
||||
// Clear boundary when deselecting
|
||||
if (updateBoundaryRef.current) updateBoundaryRef.current(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')
|
||||
|
||||
const { lng, lat } = e.lngLat
|
||||
|
|
@ -2414,7 +2420,15 @@ const MapView = forwardRef(function MapView(_, ref) {
|
|||
// Validate bounds before fitting
|
||||
if (minLng >= -180 && maxLng <= 180 && minLat >= -90 && maxLat <= 90 &&
|
||||
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,
|
||||
duration: 700,
|
||||
maxZoom: 16,
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ export const useStore = create((set, get) => ({
|
|||
autocompleteOpen: false,
|
||||
theme: 'dark', // 'dark' | 'light' (resolved value — what's actually applied)
|
||||
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 }),
|
||||
setViewMode: (mode) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue