This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/app/initializers/subscribe-user-notifications.js
Dan Ungureanu f3fdc7a6e8
FIX: Maintain notification order by priority (#13186)
When the client received a new notification, it prioritized only PM
notifications instead of maintaining the priority order. Later, the
check for missing notification deleted all notifications that were
in the wrong order because it could not match the IDs.

The correct order puts high_priority AND unread notifications first.
Low priority or read notifications (including high priority, but read
notifications) come after.
2021-05-31 09:27:13 +03:00

153 lines
4.8 KiB
JavaScript

import EmberObject, { set } from "@ember/object";
// Subscribes to user events on the message bus
import {
alertChannel,
disable as disableDesktopNotifications,
init as initDesktopNotifications,
onNotification,
} from "discourse/lib/desktop-notifications";
import {
isPushNotificationsEnabled,
register as registerPushNotifications,
unsubscribe as unsubscribePushNotifications,
} from "discourse/lib/push-notifications";
import { isTesting } from "discourse-common/config/environment";
export default {
name: "subscribe-user-notifications",
after: "message-bus",
initialize(container) {
const user = container.lookup("current-user:main");
const bus = container.lookup("message-bus:main");
const appEvents = container.lookup("service:app-events");
if (user) {
bus.subscribe("/reviewable_counts", (data) => {
user.set("reviewable_count", data.reviewable_count);
});
bus.subscribe(
`/notification/${user.get("id")}`,
(data) => {
const store = container.lookup("service:store");
const oldUnread = user.get("unread_notifications");
const oldHighPriority = user.get(
"unread_high_priority_notifications"
);
user.setProperties({
unread_notifications: data.unread_notifications,
unread_high_priority_notifications:
data.unread_high_priority_notifications,
read_first_notification: data.read_first_notification,
});
if (
oldUnread !== data.unread_notifications ||
oldHighPriority !== data.unread_high_priority_notifications
) {
appEvents.trigger("notifications:changed");
if (
site.mobileView &&
(data.unread_notifications - oldUnread > 0 ||
data.unread_high_priority_notifications - oldHighPriority > 0)
) {
appEvents.trigger("header:update-topic", null, 5000);
}
}
const stale = store.findStale(
"notification",
{},
{ cacheKey: "recent-notifications" }
);
const lastNotification =
data.last_notification && data.last_notification.notification;
if (stale && stale.hasResults && lastNotification) {
const oldNotifications = stale.results.get("content");
const staleIndex = oldNotifications.findIndex(
(n) => n.id === lastNotification.id
);
if (staleIndex === -1) {
// high priority and unread notifications are first
let insertPosition = 0;
if (!lastNotification.high_priority || lastNotification.read) {
const nextPosition = oldNotifications.findIndex(
(n) => !n.high_priority || n.read
);
if (nextPosition !== -1) {
insertPosition = nextPosition;
}
}
oldNotifications.insertAt(
insertPosition,
EmberObject.create(lastNotification)
);
}
for (let idx = 0; idx < data.recent.length; idx++) {
let old;
while ((old = oldNotifications[idx])) {
const info = data.recent[idx];
if (old.get("id") !== info[0]) {
oldNotifications.removeAt(idx);
} else {
if (old.get("read") !== info[1]) {
old.set("read", info[1]);
}
break;
}
}
if (!old) {
break;
}
}
}
},
user.notification_channel_position
);
bus.subscribe(`/do-not-disturb/${user.get("id")}`, (data) => {
user.updateDoNotDisturbStatus(data.ends_at);
});
const site = container.lookup("site:main");
const siteSettings = container.lookup("site-settings:main");
const router = container.lookup("router:main");
bus.subscribe("/categories", (data) => {
(data.categories || []).forEach((c) => site.updateCategory(c));
(data.deleted_categories || []).forEach((id) =>
site.removeCategory(id)
);
});
bus.subscribe("/client_settings", (data) =>
set(siteSettings, data.name, data.value)
);
if (!isTesting()) {
bus.subscribe(alertChannel(user), (data) =>
onNotification(data, siteSettings, user)
);
initDesktopNotifications(bus, appEvents);
if (isPushNotificationsEnabled(user, site.mobileView)) {
disableDesktopNotifications();
registerPushNotifications(user, site.mobileView, router, appEvents);
} else {
unsubscribePushNotifications(user);
}
}
}
},
};