@@ -2,6 +2,7 @@ import { type BroadcastDriver } from "laravel-echo";
2
2
import { useCallback , useEffect , useRef } from "react" ;
3
3
import { echo } from "../config" ;
4
4
import type {
5
+ BroadcastNotification ,
5
6
Channel ,
6
7
ChannelData ,
7
8
ChannelReturnType ,
@@ -167,6 +168,91 @@ export const useEcho = <
167
168
} ;
168
169
} ;
169
170
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
+
170
256
export const useEchoPresence = <
171
257
TPayload ,
172
258
TDriver extends BroadcastDriver = BroadcastDriver ,
0 commit comments