@@ -2,6 +2,7 @@ import { type BroadcastDriver } from "laravel-echo";
22import { useCallback , useEffect , useRef } from "react" ;
33import { echo } from "../config" ;
44import type {
5+ BroadcastNotification ,
56 Channel ,
67 ChannelData ,
78 ChannelReturnType ,
@@ -167,6 +168,91 @@ export const useEcho = <
167168 } ;
168169} ;
169170
171+ export const useEchoNotification = <
172+ TPayload ,
173+ TDriver extends BroadcastDriver = BroadcastDriver ,
174+ > (
175+ channelName : string ,
176+ callback : ( payload : BroadcastNotification < TPayload > ) => void = ( ) => { } ,
177+ event : string | string [ ] = [ ] ,
178+ dependencies : any [ ] = [ ] ,
179+ ) => {
180+ const result = useEcho < BroadcastNotification < TPayload > , TDriver , "private" > (
181+ channelName ,
182+ [ ] ,
183+ callback ,
184+ dependencies ,
185+ "private" ,
186+ ) ;
187+
188+ const events = useRef (
189+ toArray ( event )
190+ . map ( ( e ) => {
191+ if ( e . includes ( "." ) ) {
192+ return [ e , e . replace ( / \. / g, "\\" ) ] ;
193+ }
194+
195+ return [ e , e . replace ( / \\ / g, "." ) ] ;
196+ } )
197+ . flat ( ) ,
198+ ) ;
199+ const listening = useRef ( false ) ;
200+ const initialized = useRef ( false ) ;
201+
202+ const cb = useCallback (
203+ ( notification : BroadcastNotification < TPayload > ) => {
204+ if ( ! listening . current ) {
205+ return ;
206+ }
207+
208+ if (
209+ events . current . length === 0 ||
210+ events . current . includes ( notification . type )
211+ ) {
212+ callback ( notification ) ;
213+ }
214+ } ,
215+ dependencies . concat ( events . current ) . concat ( [ callback ] ) ,
216+ ) ;
217+
218+ const listen = useCallback ( ( ) => {
219+ if ( listening . current ) {
220+ return ;
221+ }
222+
223+ if ( ! initialized . current ) {
224+ result . channel ( ) . notification ( cb ) ;
225+ }
226+
227+ listening . current = true ;
228+ initialized . current = true ;
229+ } , [ cb ] ) ;
230+
231+ const stopListening = useCallback ( ( ) => {
232+ if ( ! listening . current ) {
233+ return ;
234+ }
235+
236+ listening . current = false ;
237+ } , [ cb ] ) ;
238+
239+ useEffect ( ( ) => {
240+ listen ( ) ;
241+ } , dependencies . concat ( events . current ) ) ;
242+
243+ return {
244+ ...result ,
245+ /**
246+ * Stop listening for notification events
247+ */
248+ stopListening,
249+ /**
250+ * Listen for notification events
251+ */
252+ listen,
253+ } ;
254+ } ;
255+
170256export const useEchoPresence = <
171257 TPayload ,
172258 TDriver extends BroadcastDriver = BroadcastDriver ,
0 commit comments