@@ -2,45 +2,17 @@ import { useCallback, useEffect, useMemo, useState } from "react";
22import { apiFetch } from "../api/client" ;
33import { listServices , type Service } from "../api/listServices" ;
44import { mapService } from "../api/mapServices" ;
5- import { listNotifications , markNotificationRead , type Notification } from "../api/notifications" ;
6- import type { NotificationSocketMessage } from "../api/notificationsSocket" ;
75import { deletePin , putPin } from "../api/pin" ;
86import type { ServiceSocketMessage } from "../api/servicesSocket" ;
97import { createWebSocketClient } from "../api/ws" ;
108
11- type AppSocketMessage = ServiceSocketMessage | NotificationSocketMessage ;
12-
139export function useLaunchpadData ( user : unknown ) {
1410 const [ services , setServices ] = useState < Service [ ] > ( [ ] ) ;
15- const [ notifications , setNotifications ] = useState < Notification [ ] > ( [ ] ) ;
1611
1712 useEffect ( ( ) => {
1813 listServices ( ) . then ( setServices ) . catch ( console . error ) ;
19- listNotifications ( ) . then ( setNotifications ) . catch ( console . error ) ;
2014 } , [ user ] ) ;
2115
22- const onNotificationsViewed = useCallback ( async ( ids : string [ ] ) => {
23- const uniqueIds = [ ...new Set ( ids ) ] ;
24- if ( uniqueIds . length === 0 ) return ;
25-
26- setNotifications ( ( prev ) =>
27- prev . map ( ( notification ) =>
28- uniqueIds . includes ( notification . id ) ? { ...notification , read : true } : notification ,
29- ) ,
30- ) ;
31-
32- try {
33- await Promise . all ( uniqueIds . map ( ( id ) => markNotificationRead ( id ) ) ) ;
34- } catch ( err ) {
35- console . error ( "markNotificationRead failed" , err ) ;
36- setNotifications ( ( prev ) =>
37- prev . map ( ( notification ) =>
38- uniqueIds . includes ( notification . id ) ? { ...notification , read : false } : notification ,
39- ) ,
40- ) ;
41- }
42- } , [ ] ) ;
43-
4416 const onTogglePin = useCallback ( async ( serviceId : string , nextPinned : boolean ) => {
4517 let previousPinned : boolean | undefined ;
4618
@@ -84,7 +56,7 @@ export function useLaunchpadData(user: unknown) {
8456 const appSocket = useMemo ( ( ) => {
8557 const isAuthenticated = Boolean ( user ) ;
8658
87- return createWebSocketClient < AppSocketMessage > ( {
59+ return createWebSocketClient < ServiceSocketMessage > ( {
8860 path : "/ws" ,
8961 // Fetch a fresh single-use ticket before each connect (and each reconnect).
9062 // Browsers cannot send Authorization headers on WebSocket upgrade requests,
@@ -106,23 +78,9 @@ export function useLaunchpadData(user: unknown) {
10678 onClose : ( ) => console . log ( "app websocket disconnected" ) ,
10779 onError : ( event ) => console . error ( "app websocket error" , event ) ,
10880 onMessage : ( message ) => {
109- if ( message . type === "notification.created" ) {
110- const nextNotification : Notification = {
111- id : message . notification . id ,
112- title : message . notification . title ,
113- message : message . notification . message ,
114- createdAt : message . notification . createdAt ,
115- image : message . notification . image ?? "" ,
116- read : message . notification . read ?? false ,
117- } ;
118-
119- setNotifications ( ( prev ) => {
120- const exists = prev . some ( ( n ) => n . id === nextNotification . id ) ;
121- return exists ? prev : [ nextNotification , ...prev ] ;
122- } ) ;
123-
124- return ;
125- }
81+ // The backend WebSocket also carries other event types. Ignore any
82+ // frame that is not a service event without changing React state.
83+ if ( ! message . service ) return ;
12684
12785 const nextService = mapService ( message . service ) ;
12886
@@ -174,8 +132,6 @@ export function useLaunchpadData(user: unknown) {
174132
175133 return {
176134 services,
177- notifications,
178- onNotificationsViewed,
179135 onTogglePin,
180136 } ;
181137}
0 commit comments