Skip to content

Commit 6f56305

Browse files
committed
handle dotted and slashed notification types
1 parent 0ef148f commit 6f56305

File tree

4 files changed

+102
-14
lines changed

4 files changed

+102
-14
lines changed

packages/react/src/hooks/use-echo.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,17 @@ export const useEchoNotification = <
181181
"private",
182182
);
183183

184-
const events = toArray(event);
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+
);
185195
const listening = useRef(false);
186196
const initialized = useRef(false);
187197

@@ -191,11 +201,14 @@ export const useEchoNotification = <
191201
return;
192202
}
193203

194-
if (events.length === 0 || events.includes(notification.type)) {
204+
if (
205+
events.current.length === 0 ||
206+
events.current.includes(notification.type)
207+
) {
195208
callback(notification);
196209
}
197210
},
198-
dependencies.concat(events).concat([callback]),
211+
dependencies.concat(events.current).concat([callback]),
199212
);
200213

201214
const listen = useCallback(() => {
@@ -221,7 +234,7 @@ export const useEchoNotification = <
221234

222235
useEffect(() => {
223236
listen();
224-
}, dependencies.concat(events));
237+
}, dependencies.concat(events.current));
225238

226239
return {
227240
...result,

packages/react/tests/use-echo.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,35 @@ describe("useEchoNotification hook", async () => {
977977
expect(mockCallback).not.toHaveBeenCalledWith(notification3);
978978
});
979979

980+
it("handles dotted and slashed notification event types", async () => {
981+
const mockCallback = vi.fn();
982+
const channelName = "test-channel";
983+
const events = [
984+
"App.Notifications.First",
985+
"App\\Notifications\\Second",
986+
];
987+
988+
renderHook(() =>
989+
echoModule.useEchoNotification(channelName, mockCallback, events),
990+
);
991+
992+
const channel = echoInstance.private(channelName);
993+
expect(channel.notification).toHaveBeenCalled();
994+
995+
const notificationCallback = vi.mocked(channel.notification).mock
996+
.calls[0][0];
997+
998+
const notification1 = { type: "App\\Notifications\\First", data: {} };
999+
const notification2 = { type: "App\\Notifications\\Second", data: {} };
1000+
1001+
notificationCallback(notification1);
1002+
notificationCallback(notification2);
1003+
1004+
expect(mockCallback).toHaveBeenCalledWith(notification1);
1005+
expect(mockCallback).toHaveBeenCalledWith(notification2);
1006+
expect(mockCallback).toHaveBeenCalledTimes(2);
1007+
});
1008+
9801009
it("accepts all notifications when no event types specified", async () => {
9811010
const mockCallback = vi.fn();
9821011
const channelName = "test-channel";

packages/vue/src/composables/useEcho.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,21 @@ export const useEchoNotification = <
196196
"private",
197197
);
198198

199-
const events = toArray(event);
200-
let listening = false;
201-
let initialized = false;
199+
const events = toArray(event)
200+
.map((e) => {
201+
if (e.includes(".")) {
202+
return [e, e.replace(/\./g, "\\")];
203+
}
204+
205+
return [e, e.replace(/\\/g, ".")];
206+
})
207+
.flat();
208+
209+
const listening = ref(false);
210+
const initialized = ref(false);
202211

203212
const cb = (notification: BroadcastNotification<TPayload>) => {
204-
if (!listening) {
213+
if (!listening.value) {
205214
return;
206215
}
207216

@@ -211,24 +220,24 @@ export const useEchoNotification = <
211220
};
212221

213222
const listen = () => {
214-
if (listening) {
223+
if (listening.value) {
215224
return;
216225
}
217226

218-
if (!initialized) {
227+
if (!initialized.value) {
219228
result.channel().notification(cb);
220229
}
221230

222-
listening = true;
223-
initialized = true;
231+
listening.value = true;
232+
initialized.value = true;
224233
};
225234

226235
const stopListening = () => {
227-
if (!listening) {
236+
if (!listening.value) {
228237
return;
229238
}
230239

231-
listening = false;
240+
listening.value = false;
232241
};
233242

234243
onMounted(() => {

packages/vue/tests/useEcho.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,43 @@ describe("useEchoNotification hook", async () => {
849849
expect(mockCallback).not.toHaveBeenCalledWith(notification3);
850850
});
851851

852+
it("handles dotted and slashed notification event types", async () => {
853+
const mockCallback = vi.fn();
854+
const channelName = "test-channel";
855+
const events = [
856+
"App.Notifications.First",
857+
"App\\Notifications\\Second",
858+
];
859+
860+
wrapper = getNotificationTestComponent(
861+
channelName,
862+
mockCallback,
863+
events,
864+
);
865+
866+
const channel = echoInstance.private(channelName);
867+
expect(channel.notification).toHaveBeenCalled();
868+
869+
const notificationCallback = vi.mocked(channel.notification).mock
870+
.calls[0][0];
871+
872+
const notification1 = {
873+
type: "App\\Notifications\\First",
874+
data: {},
875+
};
876+
const notification2 = {
877+
type: "App\\Notifications\\Second",
878+
data: {},
879+
};
880+
881+
notificationCallback(notification1);
882+
notificationCallback(notification2);
883+
884+
expect(mockCallback).toHaveBeenCalledWith(notification1);
885+
expect(mockCallback).toHaveBeenCalledWith(notification2);
886+
expect(mockCallback).toHaveBeenCalledTimes(2);
887+
});
888+
852889
it("accepts all notifications when no event types specified", async () => {
853890
const mockCallback = vi.fn();
854891
const channelName = "test-channel";

0 commit comments

Comments
 (0)