Skip to content

Commit bb5a158

Browse files
authored
FCE-2767 fetch older events on room join (#52)
* preserve game state * display toast on error * format
1 parent 3ce154c commit bb5a158

4 files changed

Lines changed: 47 additions & 38 deletions

File tree

deep-sea-stories/packages/backend/src/controllers/notifications.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ import { tracked } from '@trpc/server';
44
import { z } from 'zod';
55
import { publicProcedure } from '../trpc.js';
66

7+
export const getEvents = publicProcedure
8+
.input(z.object({ roomId: z.string() }))
9+
.query(({ ctx, input }) => {
10+
const history = ctx.notifierService.getEventHistory(input.roomId);
11+
const lastEventId =
12+
history.length > 0 ? history[history.length - 1].id.toString() : null;
13+
return {
14+
events: history.map(({ event }) => event),
15+
lastEventId,
16+
};
17+
});
18+
719
export const Notifications = publicProcedure
820
.input(
921
z.object({

deep-sea-stories/packages/backend/src/router.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Notifications } from './controllers/notifications.js';
1+
import { Notifications, getEvents } from './controllers/notifications.js';
22
import { createPeer } from './controllers/peers.js';
33
import { createRoom } from './controllers/rooms.js';
44
import {
@@ -18,6 +18,7 @@ export const appRouter = router({
1818
stopGame,
1919
getStories,
2020
Notifications,
21+
getEvents,
2122
muteVoiceAgent,
2223
});
2324

deep-sea-stories/packages/web/src/assets/elevenlabs.svg

Lines changed: 0 additions & 14 deletions
This file was deleted.

deep-sea-stories/packages/web/src/hooks/useAgentEvents.ts

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { AgentEvent } from '@deep-sea-stories/common';
22
import { useEffect, useState } from 'react';
33
import { useTRPCClient } from '@/contexts/trpc';
4+
import { toast } from '@/components/ui/sonner';
5+
import { X } from 'lucide-react';
46

57
export const useAgentEvents = (roomId?: string) => {
68
const [events, setEvents] = useState<AgentEvent[]>([]);
@@ -11,31 +13,39 @@ export const useAgentEvents = (roomId?: string) => {
1113

1214
setEvents([]);
1315

14-
const subscription = trpcClient.Notifications.subscribe(
15-
{ roomId, lastEventId: undefined },
16-
{
17-
onStarted: () => {
18-
console.log(
19-
'[useAgentEvents] Subscription started successfully for',
20-
roomId,
21-
);
22-
},
23-
onData: (data: unknown) => {
24-
const event =
25-
data && typeof data === 'object' && 'data' in data
26-
? (data as { data: AgentEvent }).data
27-
: (data as AgentEvent);
28-
setEvents((prev) => [...prev, event]);
29-
},
30-
onError: (error: unknown) => {
31-
console.error('[useAgentEvents] Subscription error:', error);
32-
},
33-
},
34-
);
16+
let subscription:
17+
| ReturnType<typeof trpcClient.Notifications.subscribe>
18+
| undefined;
19+
let active = true;
20+
21+
trpcClient.getEvents
22+
.query({ roomId })
23+
.then(({ events: pastEvents, lastEventId }) => {
24+
if (!active) return;
25+
26+
setEvents(pastEvents);
27+
28+
subscription = trpcClient.Notifications.subscribe(
29+
{ roomId, lastEventId },
30+
{
31+
onData: (data: unknown) => {
32+
const event =
33+
data && typeof data === 'object' && 'data' in data
34+
? (data as { data: AgentEvent }).data
35+
: (data as AgentEvent);
36+
setEvents((prev) => [...prev, event]);
37+
},
38+
onError: (error: unknown) => {
39+
console.error('[useAgentEvents] Subscription error:', error);
40+
},
41+
},
42+
);
43+
})
44+
.catch(() => toast('Failed to fetch events', X));
3545

3646
return () => {
37-
console.log('[useAgentEvents] Unsubscribing from', roomId);
38-
subscription.unsubscribe();
47+
active = false;
48+
subscription?.unsubscribe();
3949
};
4050
}, [trpcClient, roomId]);
4151

0 commit comments

Comments
 (0)