Skip to content

Commit 05f4d57

Browse files
imorlandclaude
andcommitted
fix: prevent error and aborted XHR on export notification click
The export notification href was a full external URL, causing the browser to navigate away on click. This aborted the concurrent mark-as-read XHR (status 0 / NS_BINDING_ABORTED), surfacing a spurious error dialog. Override href() to return '#' to prevent page navigation, and override markAsRead() to open the download via window.open(_blank) instead. The mark-as-read XHR then completes cleanly without being aborted. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 24f5163 commit 05f4d57

1 file changed

Lines changed: 19 additions & 3 deletions

File tree

js/src/forum/components/ExportAvailableNotification.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ export default class ExportAvailableNotification extends Notification {
88
return 'fas fa-file-export';
99
}
1010

11-
href() {
11+
exportUrl() {
1212
const exportModel = this.attrs.notification.subject() as Export;
13-
14-
// Building the full url scheme so that Mithril treats this as an external link, so the download will work correctly.
1513
return app.forum.attribute<string>('baseUrl') + `/gdpr/export/${exportModel.file()}`;
1614
}
1715

16+
href() {
17+
// Return a non-navigating href; the download is opened via window.open() in
18+
// markAsRead() so the mark-as-read XHR is not aborted by a page navigation.
19+
return '#';
20+
}
21+
1822
content() {
1923
const notification = this.attrs.notification;
2024
return app.translator.trans('flarum-gdpr.forum.notification.export-ready', {
@@ -25,4 +29,16 @@ export default class ExportAvailableNotification extends Notification {
2529
excerpt() {
2630
return null;
2731
}
32+
33+
markAsRead() {
34+
// Open the download in a new tab so the current page is not navigated away
35+
// from, keeping the mark-as-read XHR alive.
36+
window.open(this.exportUrl(), '_blank');
37+
38+
if (this.attrs.notification.isRead()) return;
39+
40+
app.session.user?.pushAttributes({ unreadNotificationCount: (app.session.user.unreadNotificationCount() ?? 1) - 1 });
41+
42+
this.attrs.notification.save({ isRead: true });
43+
}
2844
}

0 commit comments

Comments
 (0)