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:
parent
1dddf16c6a
commit
40cfea26a2
|
|
@ -37,6 +37,7 @@ export default function RoomPage() {
|
||||||
const [selectedParticipant, setSelectedParticipant] = useState<Participant | null>(null);
|
const [selectedParticipant, setSelectedParticipant] = useState<Participant | null>(null);
|
||||||
const [selectedWaypoint, setSelectedWaypoint] = useState<Waypoint | null>(null);
|
const [selectedWaypoint, setSelectedWaypoint] = useState<Waypoint | null>(null);
|
||||||
const [shouldAutoStartSharing, setShouldAutoStartSharing] = useState(false);
|
const [shouldAutoStartSharing, setShouldAutoStartSharing] = useState(false);
|
||||||
|
const [zoomToLocation, setZoomToLocation] = useState<{ latitude: number; longitude: number } | null>(null);
|
||||||
|
|
||||||
// Load user and sharing preference from localStorage
|
// Load user and sharing preference from localStorage
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -263,17 +264,16 @@ export default function RoomPage() {
|
||||||
};
|
};
|
||||||
}, [leave]);
|
}, [leave]);
|
||||||
|
|
||||||
// Navigate to participant - opens Google Maps navigation
|
// Navigate to participant - zoom to their location on the map
|
||||||
const handleNavigateTo = (participant: Participant) => {
|
const handleNavigateTo = (participant: Participant) => {
|
||||||
if (!participant.location) {
|
if (!participant.location) {
|
||||||
console.log('No location for participant:', participant.name);
|
console.log('No location for participant:', participant.name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { latitude, longitude } = participant.location;
|
const { latitude, longitude } = participant.location;
|
||||||
window.open(
|
setZoomToLocation({ latitude, longitude });
|
||||||
`https://www.google.com/maps/dir/?api=1&destination=${latitude},${longitude}`,
|
setSelectedParticipant(participant);
|
||||||
'_blank'
|
setShowParticipants(false); // Close participant list to show map
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Loading state
|
// Loading state
|
||||||
|
|
@ -335,6 +335,7 @@ export default function RoomPage() {
|
||||||
eventId="39c3"
|
eventId="39c3"
|
||||||
isSharing={isSharing}
|
isSharing={isSharing}
|
||||||
onToggleSharing={handleToggleSharing}
|
onToggleSharing={handleToggleSharing}
|
||||||
|
zoomToLocation={zoomToLocation}
|
||||||
onParticipantClick={(p) => {
|
onParticipantClick={(p) => {
|
||||||
setSelectedParticipant(p);
|
setSelectedParticipant(p);
|
||||||
setShowParticipants(true);
|
setShowParticipants(true);
|
||||||
|
|
@ -397,10 +398,7 @@ export default function RoomPage() {
|
||||||
}}
|
}}
|
||||||
onNavigate={() => {
|
onNavigate={() => {
|
||||||
const { latitude, longitude } = selectedWaypoint.location;
|
const { latitude, longitude } = selectedWaypoint.location;
|
||||||
window.open(
|
setZoomToLocation({ latitude, longitude });
|
||||||
`https://www.google.com/maps/dir/?api=1&destination=${latitude},${longitude}`,
|
|
||||||
'_blank'
|
|
||||||
);
|
|
||||||
setSelectedWaypoint(null);
|
setSelectedWaypoint(null);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ interface DualMapViewProps {
|
||||||
isSharing?: boolean;
|
isSharing?: boolean;
|
||||||
/** Callback to toggle location sharing */
|
/** Callback to toggle location sharing */
|
||||||
onToggleSharing?: () => void;
|
onToggleSharing?: () => void;
|
||||||
|
/** Location to zoom/fly to */
|
||||||
|
zoomToLocation?: { latitude: number; longitude: number } | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CCC venue bounds (Hamburg Congress Center)
|
// CCC venue bounds (Hamburg Congress Center)
|
||||||
|
|
@ -64,6 +66,7 @@ export default function DualMapView({
|
||||||
onIndoorPositionSet,
|
onIndoorPositionSet,
|
||||||
isSharing = false,
|
isSharing = false,
|
||||||
onToggleSharing,
|
onToggleSharing,
|
||||||
|
zoomToLocation,
|
||||||
}: DualMapViewProps) {
|
}: DualMapViewProps) {
|
||||||
const [mode, setMode] = useState<MapMode>(initialMode);
|
const [mode, setMode] = useState<MapMode>(initialMode);
|
||||||
const [activeView, setActiveView] = useState<'outdoor' | 'indoor'>('outdoor');
|
const [activeView, setActiveView] = useState<'outdoor' | 'indoor'>('outdoor');
|
||||||
|
|
@ -129,6 +132,7 @@ export default function DualMapView({
|
||||||
currentUserId={currentUserId}
|
currentUserId={currentUserId}
|
||||||
onParticipantClick={handleParticipantClick}
|
onParticipantClick={handleParticipantClick}
|
||||||
onWaypointClick={handleWaypointClick}
|
onWaypointClick={handleWaypointClick}
|
||||||
|
zoomToLocation={zoomToLocation}
|
||||||
routeSegments={activeRoute?.segments}
|
routeSegments={activeRoute?.segments}
|
||||||
routeLoading={activeRoute?.isLoading}
|
routeLoading={activeRoute?.isLoading}
|
||||||
routeError={activeRoute?.error}
|
routeError={activeRoute?.error}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ interface MapViewProps {
|
||||||
onMapClick?: (lngLat: { lng: number; lat: number }) => void;
|
onMapClick?: (lngLat: { lng: number; lat: number }) => void;
|
||||||
/** Auto-center on current user's location when first available */
|
/** Auto-center on current user's location when first available */
|
||||||
autoCenterOnUser?: boolean;
|
autoCenterOnUser?: boolean;
|
||||||
|
/** Location to zoom/fly to */
|
||||||
|
zoomToLocation?: { latitude: number; longitude: number } | null;
|
||||||
/** Active route segments to display */
|
/** Active route segments to display */
|
||||||
routeSegments?: RouteSegment[];
|
routeSegments?: RouteSegment[];
|
||||||
/** Route loading state */
|
/** Route loading state */
|
||||||
|
|
@ -64,6 +66,7 @@ export default function MapView({
|
||||||
onWaypointClick,
|
onWaypointClick,
|
||||||
onMapClick,
|
onMapClick,
|
||||||
autoCenterOnUser = true,
|
autoCenterOnUser = true,
|
||||||
|
zoomToLocation,
|
||||||
routeSegments = [],
|
routeSegments = [],
|
||||||
routeLoading = false,
|
routeLoading = false,
|
||||||
routeError,
|
routeError,
|
||||||
|
|
@ -233,6 +236,21 @@ export default function MapView({
|
||||||
}
|
}
|
||||||
}, [participants, mapLoaded, currentUserId, onParticipantClick, autoCenterOnUser]);
|
}, [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
|
// Update waypoint markers
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!map.current || !mapLoaded) return;
|
if (!map.current || !mapLoaded) return;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue