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