diff --git a/src/app/[slug]/page.tsx b/src/app/[slug]/page.tsx index d7b5893..01f5eb0 100644 --- a/src/app/[slug]/page.tsx +++ b/src/app/[slug]/page.tsx @@ -308,6 +308,8 @@ export default function RoomPage() { setShowParticipants(false)} onNavigateTo={handleNavigateTo} onSetMeetingPoint={() => setShowMeetingPoint(true)} diff --git a/src/components/room/ParticipantList.tsx b/src/components/room/ParticipantList.tsx index c6d78c4..b186fbd 100644 --- a/src/components/room/ParticipantList.tsx +++ b/src/components/room/ParticipantList.tsx @@ -1,10 +1,13 @@ 'use client'; +import { useState, useCallback } from 'react'; import type { Participant } from '@/types'; interface ParticipantListProps { participants: Participant[]; currentUserId?: string; + roomSlug: string; + syncUrl?: string; onClose: () => void; onNavigateTo: (participant: Participant) => void; onSetMeetingPoint?: () => void; @@ -13,10 +16,46 @@ interface ParticipantListProps { export default function ParticipantList({ participants, currentUserId, + roomSlug, + syncUrl, onClose, onNavigateTo, onSetMeetingPoint, }: ParticipantListProps) { + const [isRefreshing, setIsRefreshing] = useState(false); + const [refreshMessage, setRefreshMessage] = useState(null); + + const handleRefreshLocations = useCallback(async () => { + if (!syncUrl || isRefreshing) return; + + setIsRefreshing(true); + setRefreshMessage(null); + + try { + const httpUrl = syncUrl.replace('wss://', 'https://').replace('ws://', 'http://'); + const response = await fetch(`${httpUrl}/push/request-location`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ roomSlug }), + }); + + const data = await response.json(); + if (data.success) { + if (data.sent > 0) { + setRefreshMessage(`Pinged ${data.sent} friend${data.sent > 1 ? 's' : ''}`); + } else { + setRefreshMessage('No friends to ping'); + } + } + } catch (error) { + console.error('Failed to refresh locations:', error); + setRefreshMessage('Failed to ping'); + } finally { + setIsRefreshing(false); + // Clear message after 3 seconds + setTimeout(() => setRefreshMessage(null), 3000); + } + }, [syncUrl, roomSlug, isRefreshing]); const formatDistance = (participant: Participant, current: Participant | undefined) => { if (!participant.location || !current?.location) return null; @@ -50,21 +89,53 @@ export default function ParticipantList({ {/* Header */}

Friends ({participants.length})

- +
+ {/* Refresh locations button */} + {syncUrl && ( + + )} + +
+ {/* Refresh status message */} + {refreshMessage && ( +
+ {refreshMessage} +
+ )} + {/* Participant list */}
{participants.length === 0 ? (