feat: Add push notifications for background friend pings
- Auto-subscribe to push notifications when location sharing starts - Use C3NavEmbed (iframe) for faster indoor map loading - Set event to 39c3 for current congress - Increase c3nav API cache to 1 hour with stale-while-revalidate - Add strong vibration pattern and sound for notifications 🤖 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
7410246a01
commit
4f110a7604
|
|
@ -103,9 +103,14 @@ self.addEventListener('push', (event) => {
|
|||
badge: data.badge || '/icon-192.png',
|
||||
tag: data.tag || 'rmaps-notification',
|
||||
data: data.data || {},
|
||||
vibrate: [100, 50, 100],
|
||||
// Strong vibration pattern: buzz-pause-buzz-pause-long buzz
|
||||
vibrate: [200, 100, 200, 100, 400],
|
||||
actions: data.actions || [],
|
||||
requireInteraction: data.requireInteraction || false,
|
||||
// Use default system notification sound
|
||||
silent: false,
|
||||
// Renotify even if same tag (so user hears it again)
|
||||
renotify: true,
|
||||
};
|
||||
|
||||
event.waitUntil(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import dynamic from 'next/dynamic';
|
|||
import { useRoom } from '@/hooks/useRoom';
|
||||
import { useLocationSharing } from '@/hooks/useLocationSharing';
|
||||
import { useServiceWorkerMessages } from '@/hooks/useServiceWorkerMessages';
|
||||
import { usePushNotifications } from '@/hooks/usePushNotifications';
|
||||
import ParticipantList from '@/components/room/ParticipantList';
|
||||
import RoomHeader from '@/components/room/RoomHeader';
|
||||
import ShareModal from '@/components/room/ShareModal';
|
||||
|
|
@ -140,6 +141,23 @@ export default function RoomPage() {
|
|||
},
|
||||
});
|
||||
|
||||
// Push notifications for background pings
|
||||
const syncUrl = process.env.NEXT_PUBLIC_SYNC_URL;
|
||||
const { subscribe: subscribePush, isSubscribed: isPushSubscribed } = usePushNotifications({
|
||||
syncUrl,
|
||||
roomSlug: slug,
|
||||
});
|
||||
|
||||
// Auto-subscribe to push when location sharing starts
|
||||
useEffect(() => {
|
||||
if (isSharing && !isPushSubscribed && syncUrl) {
|
||||
console.log('Auto-subscribing to push notifications for background pings');
|
||||
subscribePush().catch((err) => {
|
||||
console.warn('Push subscription failed (user may have denied):', err.message);
|
||||
});
|
||||
}
|
||||
}, [isSharing, isPushSubscribed, subscribePush, syncUrl]);
|
||||
|
||||
// Restore last known location immediately when connected
|
||||
const hasRestoredLocationRef = useRef(false);
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
|
|||
return NextResponse.json(data, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Cache-Control': 'public, max-age=300', // Cache for 5 minutes
|
||||
'Cache-Control': 'public, max-age=3600, stale-while-revalidate=86400', // Cache 1 hour, stale 24h
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ const MapView = dynamic(() => import('./MapView'), {
|
|||
loading: () => <MapLoading />,
|
||||
});
|
||||
|
||||
const IndoorMapView = dynamic(() => import('./IndoorMapView'), {
|
||||
const C3NavEmbed = dynamic(() => import('./C3NavEmbed'), {
|
||||
ssr: false,
|
||||
loading: () => <MapLoading />,
|
||||
});
|
||||
|
|
@ -139,13 +139,11 @@ export default function DualMapView({
|
|||
onClearRoute={clearRoute}
|
||||
/>
|
||||
) : (
|
||||
<IndoorMapView
|
||||
<C3NavEmbed
|
||||
eventId={eventId}
|
||||
participants={participants}
|
||||
currentUserId={currentUserId}
|
||||
onParticipantClick={handleParticipantClick}
|
||||
onSwitchToOutdoor={goOutdoor}
|
||||
onPositionSet={onIndoorPositionSet}
|
||||
onToggleOutdoor={goOutdoor}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue