diff --git a/client/web/plugins/com.msgbyte.notify/src/notify.ts b/client/web/plugins/com.msgbyte.notify/src/notify.ts index e5d209f3..84e2bcf2 100644 --- a/client/web/plugins/com.msgbyte.notify/src/notify.ts +++ b/client/web/plugins/com.msgbyte.notify/src/notify.ts @@ -3,6 +3,7 @@ import { getGlobalState, getCachedUserInfo, getServiceWorkerRegistration, + navigate, } from '@capital/common'; import { Translate } from './translate'; import { hasSilent } from './silent'; @@ -12,6 +13,18 @@ export function initNotify() { Notification.requestPermission(); } + const registration: ServiceWorkerRegistration | null = + getServiceWorkerRegistration(); + + if (registration) { + registration.addEventListener('notificationclick', (e: any) => { + const tag = e.notification.tag; + const data = e.notification.data; + + handleMessageNotifyClick(tag, data); + }); + } + regSocketEventListener({ eventName: 'chat.message.add', eventFn: (message) => { @@ -34,21 +47,26 @@ export function initNotify() { const icon = userInfo?.avatar ?? undefined; const content = message.content; - const registration: ServiceWorkerRegistration | null = - getServiceWorkerRegistration(); - const title = `${Translate.from} ${nickname}`; const options: NotificationOptions = { body: content, icon, tag: 'tailchat-message', renotify: true, + data: message, }; + if (registration && registration.showNotification) { registration.showNotification(title, options); } else { // fallback - new Notification(title, options); + const notification = new Notification(title, options); + notification.onclick = (e: any) => { + const tag = e.target.tag; + const data = e.target.data; + + handleMessageNotifyClick(tag, data); + }; } } ); @@ -57,3 +75,28 @@ export function initNotify() { }, }); } + +/** + * 点击通知栏事件 + */ +function handleMessageNotifyClick(tag, data) { + if (tag === 'tailchat-message') { + const message = data; + + window.focus(); + const { converseId, groupId } = message ?? {}; + if (!converseId) { + console.warn('[notify] Not found converseId'); + return; + } + if (groupId) { + // 群组消息 + navigate(`/main/group/${groupId}/${converseId}`); + } else { + // 私信会话 + navigate(`/main/personal/converse/${converseId}`); + } + } + + console.log(tag, data); +} diff --git a/client/web/src/App.tsx b/client/web/src/App.tsx index 9033d83c..d552cf00 100644 --- a/client/web/src/App.tsx +++ b/client/web/src/App.tsx @@ -22,6 +22,7 @@ import { LoadingSpinner } from './components/LoadingSpinner'; import { pluginRootRoute } from './plugin/common'; import { PortalHost as FallbackPortalHost } from './components/Portal'; import isElectron from 'is-electron'; +import { AppRouterApi } from './components/AppRouterApi'; const AppRouter: any = isElectron() ? HashRouter : BrowserRouter; @@ -108,6 +109,7 @@ export const App: React.FC = React.memo(() => { + { + throw new Error('route navigate not init'); +}; + +export const AppRouterApi: React.FC = React.memo(() => { + const _navigate = useNavigate(); + navigate = _navigate; + + return null; +}); +AppRouterApi.displayName = 'AppRouterApi'; diff --git a/client/web/src/plugin/common/index.ts b/client/web/src/plugin/common/index.ts index aa5dbd2a..ef0a584e 100644 --- a/client/web/src/plugin/common/index.ts +++ b/client/web/src/plugin/common/index.ts @@ -56,6 +56,7 @@ export { joinArray, } from 'tailchat-shared'; +export { navigate } from '@/components/AppRouterApi'; export { useLocation, useNavigate } from 'react-router'; export {