From 6294e1de412255c2949bf4dc6b02739220b0586f Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Sun, 28 Dec 2025 23:47:44 +0100 Subject: [PATCH] feat: Persist location sharing across browser sessions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remember location sharing preference per room - Auto-start sharing when returning to a room - Restore last known location immediately on page load (if < 1 hour old) - Location updates are saved to localStorage for faster reload 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/app/[slug]/page.tsx | 73 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/src/app/[slug]/page.tsx b/src/app/[slug]/page.tsx index 8e3107e..394c8ca 100644 --- a/src/app/[slug]/page.tsx +++ b/src/app/[slug]/page.tsx @@ -31,8 +31,9 @@ export default function RoomPage() { const [showMeetingPoint, setShowMeetingPoint] = useState(false); const [currentUser, setCurrentUser] = useState<{ name: string; emoji: string } | null>(null); const [selectedParticipant, setSelectedParticipant] = useState(null); + const [shouldAutoStartSharing, setShouldAutoStartSharing] = useState(false); - // Load user from localStorage + // Load user and sharing preference from localStorage useEffect(() => { const stored = localStorage.getItem('rmaps_user'); if (stored) { @@ -40,8 +41,15 @@ export default function RoomPage() { } else { // Redirect to home if no user info router.push('/'); + return; } - }, [router]); + + // Check if user had location sharing enabled for this room + const sharingPref = localStorage.getItem(`rmaps_sharing_${slug}`); + if (sharingPref === 'true') { + setShouldAutoStartSharing(true); + } + }, [router, slug]); // Room hook (only initialize when we have user info) const { @@ -77,13 +85,24 @@ export default function RoomPage() { updateLocationRef.current = updateLocation; }, [updateLocation]); - // Stable callback that always uses latest refs + // Stable callback that always uses latest refs - also persists location const handleLocationUpdate = useCallback((location: ParticipantLocation) => { console.log('Location update received:', location.latitude, location.longitude, 'connected:', isConnectedRef.current); if (isConnectedRef.current) { updateLocationRef.current(location); + // Persist last known location for faster reload + try { + localStorage.setItem(`rmaps_last_location_${slug}`, JSON.stringify({ + latitude: location.latitude, + longitude: location.longitude, + accuracy: location.accuracy, + timestamp: location.timestamp.toISOString(), + })); + } catch { + // Ignore storage errors + } } - }, []); + }, [slug]); // Location sharing hook const { @@ -97,18 +116,58 @@ export default function RoomPage() { highAccuracy: true, }); - // Location sharing is opt-in - user must click to start - // Handler for toggling location sharing + // Restore last known location immediately when connected + const hasRestoredLocationRef = useRef(false); + useEffect(() => { + if (isConnected && !hasRestoredLocationRef.current) { + hasRestoredLocationRef.current = true; + try { + const savedLocation = localStorage.getItem(`rmaps_last_location_${slug}`); + if (savedLocation) { + const loc = JSON.parse(savedLocation); + // Only restore if less than 1 hour old + const age = Date.now() - new Date(loc.timestamp).getTime(); + if (age < 60 * 60 * 1000) { + console.log('Restoring last known location:', loc.latitude, loc.longitude); + updateLocation({ + latitude: loc.latitude, + longitude: loc.longitude, + accuracy: loc.accuracy || 100, + timestamp: new Date(loc.timestamp), + source: 'gps', + }); + } + } + } catch { + // Ignore restore errors + } + } + }, [isConnected, slug, updateLocation]); + + // Auto-start location sharing if user had it enabled before + useEffect(() => { + if (shouldAutoStartSharing && isConnected && !isSharing) { + console.log('Auto-starting location sharing from saved preference'); + startSharing(); + setShouldAutoStartSharing(false); // Only auto-start once + } + }, [shouldAutoStartSharing, isConnected, isSharing, startSharing]); + + // Handler for toggling location sharing - persists preference const handleToggleSharing = useCallback(() => { if (isSharing) { console.log('Stopping location sharing and clearing location'); stopSharing(); clearLocation(); + // Save preference + localStorage.setItem(`rmaps_sharing_${slug}`, 'false'); } else { console.log('Starting location sharing'); startSharing(); + // Save preference + localStorage.setItem(`rmaps_sharing_${slug}`, 'true'); } - }, [isSharing, startSharing, stopSharing, clearLocation]); + }, [isSharing, startSharing, stopSharing, clearLocation, slug]); // Track if we've centered on user's location yet const hasCenteredRef = useRef(false);