diff --git a/src/client/api/socketio.ts b/src/client/api/socketio.ts index ef3662e..5508954 100644 --- a/src/client/api/socketio.ts +++ b/src/client/api/socketio.ts @@ -3,7 +3,7 @@ import { getJWT } from './auth'; import type { SubscribeEventMap, SocketEventMap } from '../../server/ws/shared'; import { create } from 'zustand'; import { useEvent } from '../hooks/useEvent'; -import { useEffect, useState } from 'react'; +import { useEffect, useReducer, useState } from 'react'; const useSocketStore = create<{ socket: Socket | null; @@ -109,3 +109,35 @@ export function useSocketSubscribe( return data; } + +interface UseSocketSubscribeListOptions { + filter?: (data: T) => boolean; +} +const defaultFilter = () => true; +export function useSocketSubscribeList< + K extends keyof SubscribeEventMap = keyof SubscribeEventMap, + T = SubscribeEventData +>(name: K, options: UseSocketSubscribeListOptions = {}): T[] { + const { filter = defaultFilter } = options; + const { subscribe } = useSocket(); + const [list, push] = useReducer( + (state: T[], data: T) => [...state, data], + [] as T[] + ); + + const cb = useEvent((_data) => { + if (filter(_data)) { + push(_data); + } + }); + + useEffect(() => { + const unsubscribe = subscribe(name, cb); + + return () => { + unsubscribe(); + }; + }, [name]); + + return list; +}