feat: Zoom to location instead of opening Google Maps

Replace all Google Maps navigation links with in-app zoom functionality.
When clicking on a participant or waypoint to navigate, the map now
smoothly flies to their location at zoom level 17 instead of opening
an external Google Maps link.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2025-12-29 02:53:16 +01:00
parent 1dddf16c6a
commit 40cfea26a2
3 changed files with 29 additions and 9 deletions

View File

@ -37,6 +37,7 @@ export default function RoomPage() {
const [selectedParticipant, setSelectedParticipant] = useState<Participant | null>(null);
const [selectedWaypoint, setSelectedWaypoint] = useState<Waypoint | null>(null);
const [shouldAutoStartSharing, setShouldAutoStartSharing] = useState(false);
const [zoomToLocation, setZoomToLocation] = useState<{ latitude: number; longitude: number } | null>(null);
// Load user and sharing preference from localStorage
useEffect(() => {
@ -263,17 +264,16 @@ export default function RoomPage() {
};
}, [leave]);
// Navigate to participant - opens Google Maps navigation
// Navigate to participant - zoom to their location on the map
const handleNavigateTo = (participant: Participant) => {
if (!participant.location) {
console.log('No location for participant:', participant.name);
return;
}
const { latitude, longitude } = participant.location;
window.open(
`https://www.google.com/maps/dir/?api=1&destination=${latitude},${longitude}`,
'_blank'
);
setZoomToLocation({ latitude, longitude });
setSelectedParticipant(participant);
setShowParticipants(false); // Close participant list to show map
};
// Loading state
@ -335,6 +335,7 @@ export default function RoomPage() {
eventId="39c3"
isSharing={isSharing}
onToggleSharing={handleToggleSharing}
zoomToLocation={zoomToLocation}
onParticipantClick={(p) => {
setSelectedParticipant(p);
setShowParticipants(true);
@ -397,10 +398,7 @@ export default function RoomPage() {
}}
onNavigate={() => {
const { latitude, longitude } = selectedWaypoint.location;
window.open(
`https://www.google.com/maps/dir/?api=1&destination=${latitude},${longitude}`,
'_blank'
);
setZoomToLocation({ latitude, longitude });
setSelectedWaypoint(null);
}}
/>

View File

@ -42,6 +42,8 @@ interface DualMapViewProps {
isSharing?: boolean;
/** Callback to toggle location sharing */
onToggleSharing?: () => void;
/** Location to zoom/fly to */
zoomToLocation?: { latitude: number; longitude: number } | null;
}
// CCC venue bounds (Hamburg Congress Center)
@ -64,6 +66,7 @@ export default function DualMapView({
onIndoorPositionSet,
isSharing = false,
onToggleSharing,
zoomToLocation,
}: DualMapViewProps) {
const [mode, setMode] = useState<MapMode>(initialMode);
const [activeView, setActiveView] = useState<'outdoor' | 'indoor'>('outdoor');
@ -129,6 +132,7 @@ export default function DualMapView({
currentUserId={currentUserId}
onParticipantClick={handleParticipantClick}
onWaypointClick={handleWaypointClick}
zoomToLocation={zoomToLocation}
routeSegments={activeRoute?.segments}
routeLoading={activeRoute?.isLoading}
routeError={activeRoute?.error}

View File

@ -17,6 +17,8 @@ interface MapViewProps {
onMapClick?: (lngLat: { lng: number; lat: number }) => void;
/** Auto-center on current user's location when first available */
autoCenterOnUser?: boolean;
/** Location to zoom/fly to */
zoomToLocation?: { latitude: number; longitude: number } | null;
/** Active route segments to display */
routeSegments?: RouteSegment[];
/** Route loading state */
@ -64,6 +66,7 @@ export default function MapView({
onWaypointClick,
onMapClick,
autoCenterOnUser = true,
zoomToLocation,
routeSegments = [],
routeLoading = false,
routeError,
@ -233,6 +236,21 @@ export default function MapView({
}
}, [participants, mapLoaded, currentUserId, onParticipantClick, autoCenterOnUser]);
// Fly to location when zoomToLocation changes
useEffect(() => {
if (!map.current || !mapLoaded || !zoomToLocation) return;
const { latitude, longitude } = zoomToLocation;
if (isValidCoordinate(latitude, longitude)) {
console.log('Flying to location:', latitude, longitude);
map.current.flyTo({
center: [longitude, latitude],
zoom: 17,
duration: 1500,
});
}
}, [zoomToLocation, mapLoaded]);
// Update waypoint markers
useEffect(() => {
if (!map.current || !mapLoaded) return;