58 lines
1.9 KiB
TypeScript
58 lines
1.9 KiB
TypeScript
import { useCallback, useEffect } from "react";
|
|
import { ensureTopicData, fromServerMessage } from "@/utils/common";
|
|
import { EVENT_WS_MESSAGE } from "@/utils/constants";
|
|
import { App } from "antd";
|
|
|
|
export const useServerMessageHandler = () => {
|
|
const { notification } = App.useApp();
|
|
const processCustomEvent = useCallback(async (msg: string) => {
|
|
const { topic, data } = fromServerMessage(msg);
|
|
console.debug('Handle ws message, topic: %s', topic, data);
|
|
switch (topic) {
|
|
case "MEMBER_CHANGE": {
|
|
break;
|
|
}
|
|
case "MY_CLIENT_ONLINE": {
|
|
break;
|
|
}
|
|
case "DEBUG_MSG":
|
|
break;
|
|
case "EVENT_MEMBER_CHANGE":
|
|
case "MSG": {
|
|
const msgData = ensureTopicData<'MSG'>(data);
|
|
const hasPermission = await Notification.requestPermission();
|
|
if (hasPermission === 'granted') {
|
|
const options = {
|
|
body: `有新的消息`,
|
|
icon: "https://example.com/icon.png", // 通知图标
|
|
badge: "https://example.com/badge.png", // 移动端状态栏图标
|
|
tag: `MSG`, // 相同 tag 的通知会覆盖,防止刷屏
|
|
renotify: true // 覆盖旧通知时是否再次振动/提醒
|
|
};
|
|
new Notification("新消息提醒", options);
|
|
return;
|
|
}
|
|
notification.info({
|
|
key: 'MSG',
|
|
title: 'You have a new message',
|
|
description: `from: ${msgData?.name}`
|
|
});
|
|
break;
|
|
}
|
|
case "SERVER_PUSH": {
|
|
const { title, options = {} } = ensureTopicData<'SERVER_PUSH'>(data) ?? {};
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}, []);
|
|
useEffect(() => {
|
|
const handler = (e: Event) => {
|
|
const { message } = (e as CustomEvent).detail;
|
|
processCustomEvent(message);
|
|
};
|
|
window.addEventListener(EVENT_WS_MESSAGE, handler);
|
|
return () => window.removeEventListener(EVENT_WS_MESSAGE, handler);
|
|
}, [processCustomEvent]);
|
|
}; |