feat: Persist location sharing across browser sessions
- 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 <noreply@anthropic.com>
This commit is contained in:
parent
912104f740
commit
6294e1de41
|
|
@ -31,8 +31,9 @@ export default function RoomPage() {
|
||||||
const [showMeetingPoint, setShowMeetingPoint] = useState(false);
|
const [showMeetingPoint, setShowMeetingPoint] = useState(false);
|
||||||
const [currentUser, setCurrentUser] = useState<{ name: string; emoji: string } | null>(null);
|
const [currentUser, setCurrentUser] = useState<{ name: string; emoji: string } | null>(null);
|
||||||
const [selectedParticipant, setSelectedParticipant] = useState<Participant | null>(null);
|
const [selectedParticipant, setSelectedParticipant] = useState<Participant | null>(null);
|
||||||
|
const [shouldAutoStartSharing, setShouldAutoStartSharing] = useState(false);
|
||||||
|
|
||||||
// Load user from localStorage
|
// Load user and sharing preference from localStorage
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const stored = localStorage.getItem('rmaps_user');
|
const stored = localStorage.getItem('rmaps_user');
|
||||||
if (stored) {
|
if (stored) {
|
||||||
|
|
@ -40,8 +41,15 @@ export default function RoomPage() {
|
||||||
} else {
|
} else {
|
||||||
// Redirect to home if no user info
|
// Redirect to home if no user info
|
||||||
router.push('/');
|
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)
|
// Room hook (only initialize when we have user info)
|
||||||
const {
|
const {
|
||||||
|
|
@ -77,13 +85,24 @@ export default function RoomPage() {
|
||||||
updateLocationRef.current = updateLocation;
|
updateLocationRef.current = updateLocation;
|
||||||
}, [updateLocation]);
|
}, [updateLocation]);
|
||||||
|
|
||||||
// Stable callback that always uses latest refs
|
// Stable callback that always uses latest refs - also persists location
|
||||||
const handleLocationUpdate = useCallback((location: ParticipantLocation) => {
|
const handleLocationUpdate = useCallback((location: ParticipantLocation) => {
|
||||||
console.log('Location update received:', location.latitude, location.longitude, 'connected:', isConnectedRef.current);
|
console.log('Location update received:', location.latitude, location.longitude, 'connected:', isConnectedRef.current);
|
||||||
if (isConnectedRef.current) {
|
if (isConnectedRef.current) {
|
||||||
updateLocationRef.current(location);
|
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
|
// Location sharing hook
|
||||||
const {
|
const {
|
||||||
|
|
@ -97,18 +116,58 @@ export default function RoomPage() {
|
||||||
highAccuracy: true,
|
highAccuracy: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Location sharing is opt-in - user must click to start
|
// Restore last known location immediately when connected
|
||||||
// Handler for toggling location sharing
|
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(() => {
|
const handleToggleSharing = useCallback(() => {
|
||||||
if (isSharing) {
|
if (isSharing) {
|
||||||
console.log('Stopping location sharing and clearing location');
|
console.log('Stopping location sharing and clearing location');
|
||||||
stopSharing();
|
stopSharing();
|
||||||
clearLocation();
|
clearLocation();
|
||||||
|
// Save preference
|
||||||
|
localStorage.setItem(`rmaps_sharing_${slug}`, 'false');
|
||||||
} else {
|
} else {
|
||||||
console.log('Starting location sharing');
|
console.log('Starting location sharing');
|
||||||
startSharing();
|
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
|
// Track if we've centered on user's location yet
|
||||||
const hasCenteredRef = useRef(false);
|
const hasCenteredRef = useRef(false);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue