diff --git a/desktop/src/preload.js b/desktop/src/preload.js --- a/desktop/src/preload.js +++ b/desktop/src/preload.js @@ -23,6 +23,18 @@ }, updateToNewVersion: () => ipcRenderer.send('update-to-new-version'), platform: { win32: 'windows', darwin: 'macos' }[process.platform], + onDeviceTokenRegistered: callback => { + const withEvent = (event, ...args) => callback(...args); + ipcRenderer.on('on-device-token-registered', withEvent); + return () => + ipcRenderer.removeListener('on-device-token-registered', withEvent); + }, + onNotificationClicked: callback => { + const withEvent = (event, ...args) => callback(...args); + ipcRenderer.on('on-notification-clicked', withEvent); + return () => + ipcRenderer.removeListener('on-notification-clicked', withEvent); + }, }; contextBridge.exposeInMainWorld('electronContextBridge', bridge); diff --git a/lib/types/electron-types.js b/lib/types/electron-types.js --- a/lib/types/electron-types.js +++ b/lib/types/electron-types.js @@ -7,6 +7,10 @@ type OnNewVersionAvailableListener = (version: string) => void; +type OnDeviceTokenRegisteredListener = (token: ?string) => void; + +type OnNotificationClickedListener = (data: { threadID: string }) => void; + export type ElectronBridge = { // Returns a callback that you can call to remove the listener +onNavigate: OnNavigateListener => () => void, @@ -18,4 +22,6 @@ +onNewVersionAvailable?: OnNewVersionAvailableListener => () => void, +updateToNewVersion?: () => void, +platform?: 'windows' | 'macos', + +onDeviceTokenRegistered?: OnDeviceTokenRegisteredListener => () => void, + +onNotificationClicked?: OnNotificationClickedListener => () => void, }; diff --git a/web/push-notif/push-notifs-handler.js b/web/push-notif/push-notifs-handler.js --- a/web/push-notif/push-notifs-handler.js +++ b/web/push-notif/push-notifs-handler.js @@ -19,6 +19,38 @@ import { updateNavInfoActionType } from '../redux/action-types.js'; import { useSelector } from '../redux/redux-utils.js'; +function useCreateDesktopPushSubscription() { + const dispatchActionPromise = useDispatchActionPromise(); + const callSetDeviceToken = useServerCall(setDeviceToken); + + React.useEffect( + () => + electron?.onDeviceTokenRegistered?.(token => { + dispatchActionPromise( + setDeviceTokenActionTypes, + callSetDeviceToken(token), + ); + }), + [callSetDeviceToken, dispatchActionPromise], + ); + + const dispatch = useDispatch(); + + React.useEffect( + () => + electron?.onNotificationClicked?.(({ threadID }) => { + const payload = { + chatMode: 'view', + activeChatThreadID: threadID, + tab: 'chat', + }; + + dispatch({ type: updateNavInfoActionType, payload }); + }), + [dispatch], + ); +} + function useCreatePushSubscription(): () => Promise { const publicKey = useSelector(state => state.pushApiPublicKey); @@ -48,6 +80,7 @@ } function PushNotificationsHandler(): React.Node { + useCreateDesktopPushSubscription(); const createPushSubscription = useCreatePushSubscription(); const modalContext = useModalContext();