Fix location sharing: opt-in by default, stop button clears location from map

This commit is contained in:
Jeff Emmett 2025-12-15 15:47:31 -05:00
parent 6d55e1c5a9
commit 1a996931b5
3 changed files with 32 additions and 9 deletions

View File

@ -51,6 +51,7 @@ export default function RoomPage() {
currentParticipantId, currentParticipantId,
roomName, roomName,
updateLocation, updateLocation,
clearLocation,
setStatus, setStatus,
addWaypoint, addWaypoint,
removeWaypoint, removeWaypoint,
@ -93,16 +94,18 @@ export default function RoomPage() {
highAccuracy: true, highAccuracy: true,
}); });
// Auto-start location sharing when connected (only once) // Location sharing is opt-in - user must click to start
const hasAutoStartedRef = useRef(false); // Handler for toggling location sharing
const handleToggleSharing = useCallback(() => {
useEffect(() => { if (isSharing) {
if (isConnected && currentUser && !hasAutoStartedRef.current) { console.log('Stopping location sharing and clearing location');
console.log('Auto-starting location sharing (first time)'); stopSharing();
hasAutoStartedRef.current = true; clearLocation();
} else {
console.log('Starting location sharing');
startSharing(); startSharing();
} }
}, [isConnected, currentUser, startSharing]); }, [isSharing, startSharing, stopSharing, clearLocation]);
// Track if we've centered on user's location yet // Track if we've centered on user's location yet
const hasCenteredRef = useRef(false); const hasCenteredRef = useRef(false);
@ -188,7 +191,7 @@ export default function RoomPage() {
roomSlug={slug} roomSlug={slug}
participantCount={participants.length} participantCount={participants.length}
isSharing={isSharing} isSharing={isSharing}
onToggleSharing={() => (isSharing ? stopSharing() : startSharing())} onToggleSharing={handleToggleSharing}
onShare={() => setShowShare(true)} onShare={() => setShowShare(true)}
onToggleParticipants={() => setShowParticipants(!showParticipants)} onToggleParticipants={() => setShowParticipants(!showParticipants)}
/> />

View File

@ -42,6 +42,7 @@ interface UseRoomReturn {
currentParticipantId: string | null; currentParticipantId: string | null;
roomName: string; roomName: string;
updateLocation: (location: ParticipantLocation) => void; updateLocation: (location: ParticipantLocation) => void;
clearLocation: () => void;
setStatus: (status: Participant['status']) => void; setStatus: (status: Participant['status']) => void;
addWaypoint: (waypoint: Omit<Waypoint, 'id' | 'createdAt' | 'createdBy'>) => void; addWaypoint: (waypoint: Omit<Waypoint, 'id' | 'createdAt' | 'createdBy'>) => void;
removeWaypoint: (waypointId: string) => void; removeWaypoint: (waypointId: string) => void;
@ -136,6 +137,12 @@ export function useRoom({ slug, userName, userEmoji }: UseRoomOptions): UseRoomR
syncRef.current.updateLocation(locationState); syncRef.current.updateLocation(locationState);
}, []); }, []);
// Clear location (when user stops sharing)
const clearLocation = useCallback(() => {
if (!syncRef.current) return;
syncRef.current.clearLocation();
}, []);
// Set status // Set status
const setStatus = useCallback((status: Participant['status']) => { const setStatus = useCallback((status: Participant['status']) => {
if (!syncRef.current) return; if (!syncRef.current) return;
@ -187,6 +194,7 @@ export function useRoom({ slug, userName, userEmoji }: UseRoomOptions): UseRoomR
currentParticipantId: participantIdRef.current, currentParticipantId: participantIdRef.current,
roomName, roomName,
updateLocation, updateLocation,
clearLocation,
setStatus, setStatus,
addWaypoint, addWaypoint,
removeWaypoint, removeWaypoint,

View File

@ -281,6 +281,18 @@ export class RoomSync {
} }
} }
clearLocation(): void {
console.log('RoomSync.clearLocation called');
if (this.state.participants[this.participantId]) {
delete this.state.participants[this.participantId].location;
this.state.participants[this.participantId].lastSeen = new Date().toISOString();
// Broadcast a null location to clear it for other participants
this.send({ type: 'location', participantId: this.participantId, location: null as any });
console.log('Location cleared for participant:', this.participantId);
this.notifyStateChange();
}
}
updateStatus(status: string): void { updateStatus(status: string): void {
if (this.state.participants[this.participantId]) { if (this.state.participants[this.participantId]) {
this.state.participants[this.participantId].status = status; this.state.participants[this.participantId].status = status;