Skip to content

Commit d0503f0

Browse files
authored
Fix notification navigation (#9642)
1 parent 6e1b5fd commit d0503f0

File tree

6 files changed

+57
-12
lines changed

6 files changed

+57
-12
lines changed

desktop/src/main/start.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ ipcMain.on('send-notification', (_event: any, notificationParams: NotificationPa
340340

341341
notification.on('click', () => {
342342
mainWindow?.show()
343-
mainWindow?.webContents.send('handle-notification-navigation', notificationParams.application)
343+
mainWindow?.webContents.send('handle-notification-navigation', notificationParams)
344344
})
345345

346346
notification.show()

desktop/src/ui/index.ts

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ import {
1818
} from '@hcengineering/ui'
1919
import { handleDownloadItem } from '@hcengineering/desktop-downloads'
2020
import notification, { notificationId } from '@hcengineering/notification'
21+
import { inboxId } from '@hcengineering/inbox'
2122
import { workbenchId, logOut } from '@hcengineering/workbench'
23+
import { encodeObjectURI } from '@hcengineering/view'
24+
import { resolveLocation } from '@hcengineering/notification-resources'
2225

2326
import { isOwnerOrMaintainer } from '@hcengineering/core'
2427
import { configurePlatform } from './platform'
2528
import { setupTitleBarMenu } from './titleBarMenu'
2629
import { defineScreenShare, defineGetDisplayMedia } from './screenShare'
27-
import { CommandLogout, CommandSelectWorkspace, CommandOpenSettings, CommandOpenInbox, CommandOpenPlanner, CommandOpenOffice, CommandOpenApplication, LaunchApplication } from './types'
30+
import { CommandLogout, CommandSelectWorkspace, CommandOpenSettings, CommandOpenInbox, CommandOpenPlanner, CommandOpenOffice, CommandOpenApplication, LaunchApplication, NotificationParams } from './types'
2831
import { ipcMainExposed } from './typesUtils'
2932
import { themeStore } from '@hcengineering/theme'
3033

@@ -156,13 +159,46 @@ window.addEventListener('DOMContentLoaded', () => {
156159
navigate(parseLocation(urlObject))
157160
})
158161

159-
ipcMain.handleNotificationNavigation((application) => {
160-
// For now navigate only to Inbox
162+
function navigateToUrl (path: string): void {
161163
const frontUrl = getMetadata(presentation.metadata.FrontUrl) ?? window.location.origin
162-
const location = getCurrentResolvedLocation()
163-
const urlString = `${frontUrl}/${workbenchId}/${location.path[1]}/${application ?? notificationId}`
164-
const urlObject = new URL(urlString)
164+
const urlObject = new URL(`${frontUrl}/${path}`)
165165
navigate(parseLocation(urlObject))
166+
}
167+
168+
function getBasicNotificationPath (notificationParams: NotificationParams): string {
169+
return `${workbenchId}/${notificationParams.application ?? notificationId}/${notificationId}`
170+
}
171+
172+
ipcMain.handleNotificationNavigation((notificationParams: NotificationParams) => {
173+
// Support for new inbox with cardId (card-based)
174+
if (notificationParams.cardId != null) {
175+
const currentLocation = getCurrentResolvedLocation()
176+
navigateToUrl(`${workbenchId}/${currentLocation.path[1]}/${inboxId}/${notificationParams.cardId}`)
177+
return
178+
}
179+
180+
// Support for old inbox with objectId + objectClass (legacy)
181+
if (notificationParams.objectId != null && notificationParams.objectClass != null) {
182+
const encodedObjectURI = encodeObjectURI(notificationParams.objectId, notificationParams.objectClass)
183+
const notificationLocation = {
184+
path: [workbenchId, notificationParams.application, notificationId, encodedObjectURI],
185+
fragment: undefined,
186+
query: {}
187+
}
188+
189+
void resolveLocation(notificationLocation).then((resolvedLocation) => {
190+
if (resolvedLocation?.loc != null) {
191+
navigate(resolvedLocation.loc)
192+
} else {
193+
navigateToUrl(`${workbenchId}/${notificationParams.application}/${notificationId}/${encodedObjectURI}`)
194+
}
195+
}).catch(() => {
196+
navigateToUrl(getBasicNotificationPath(notificationParams))
197+
})
198+
} else {
199+
// Fallback to basic notification navigation
200+
navigateToUrl(getBasicNotificationPath(notificationParams))
201+
}
166202
})
167203

168204
ipcMain.handleUpdateDownloadProgress((progress) => {

desktop/src/ui/notifications.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,10 @@ export function configureNotifications (): void {
166166
silent: !preferences.playSound,
167167
application: inboxId,
168168
title: notification.content.title,
169-
body: `${notification.content.senderName}: ${notification.content.shortText}`
169+
body: `${notification.content.senderName}: ${notification.content.shortText}`,
170+
cardId: notification.cardId,
171+
objectId: notification.content.objectId,
172+
objectClass: notification.content.objectClass
170173
})
171174
}
172175
})
@@ -216,6 +219,8 @@ export function configureNotifications (): void {
216219
electronAPI.sendNotification({
217220
silent: !preferences.playSound,
218221
application: notificationId,
222+
objectId: notification.objectId,
223+
objectClass: notification.objectClass,
219224
...notificationData
220225
})
221226
}

desktop/src/ui/preload.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ const expose: IPCMainExposed = {
145145
},
146146

147147
handleNotificationNavigation: (callback) => {
148-
ipcRenderer.on('handle-notification-navigation', (event, application) => {
149-
callback(application)
148+
ipcRenderer.on('handle-notification-navigation', (event, notificationParams) => {
149+
callback(notificationParams)
150150
})
151151
},
152152

desktop/src/ui/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { DownloadItem } from '@hcengineering/desktop-downloads'
22
import { ScreenSource } from '@hcengineering/love'
33
import { Plugin } from '@hcengineering/platform'
4+
import { Ref, Class, Doc } from '@hcengineering/core'
45
import { IpcRendererEvent } from 'electron'
56

67
export interface Config {
@@ -95,6 +96,9 @@ export interface NotificationParams {
9596
body: string
9697
silent: boolean
9798
application: Plugin
99+
cardId?: string
100+
objectId?: Ref<Doc>
101+
objectClass?: Ref<Class<Doc>>
98102
}
99103

100104
export const MenuBarActions = ['settings', 'select-workspace', 'logout', 'exit', 'undo', 'redo', 'cut', 'copy', 'paste', 'delete', 'select-all', 'reload', 'force-reload', 'toggle-devtools'
@@ -121,7 +125,7 @@ export interface IPCMainExposed {
121125
branding: () => Promise<Branding>
122126
on: (event: string, op: (channel: any, args: any[]) => void) => void
123127
handleDeepLink: (callback: (url: string) => void) => void
124-
handleNotificationNavigation: (callback: (application: Plugin) => void) => void
128+
handleNotificationNavigation: (callback: (notificationParams: NotificationParams) => void) => void
125129
handleUpdateDownloadProgress: (callback: (progress: number) => void) => void
126130
setFrontCookie: (host: string, name: string, value: string) => Promise<void>
127131
dockBounce: () => void

plugins/view-resources/src/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1578,7 +1578,7 @@ export async function parseLinkId<T extends Doc> (
15781578
): Promise<Ref<T>> {
15791579
const hierarchy = getClient().getHierarchy()
15801580
const provider =
1581-
providers.find(({ _id }) => id === _class) ?? providers.find(({ _id }) => hierarchy.isDerived(_class, _id))
1581+
providers.find(({ _id }) => _id === _class) ?? providers.find(({ _id }) => hierarchy.isDerived(_class, _id))
15821582

15831583
if (provider === undefined) {
15841584
return id as Ref<T>

0 commit comments

Comments
 (0)