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/widgets/user-notifications.js.es6
Daniel Waterworth 04a75b1cb3 Change the way notification items are created
Look for the specialised version first, before falling back to the
default. This allows the behaviour to be customised based on the type of
notification.
2019-06-26 09:01:25 -04:00

133 lines
3.4 KiB
JavaScript

import { createWidget } from "discourse/widgets/widget";
import { headerHeight } from "discourse/components/site-header";
import { h } from "virtual-dom";
import DiscourseURL from "discourse/lib/url";
import { ajax } from "discourse/lib/ajax";
export default createWidget("user-notifications", {
tagName: "div.notifications",
buildKey: () => "user-notifications",
defaultState() {
return { notifications: [], loading: false, loaded: false };
},
markRead() {
ajax("/notifications/mark-read", { method: "PUT" }).then(() => {
this.refreshNotifications(this.state);
});
},
refreshNotifications(state) {
if (this.loading) {
return;
}
// estimate (poorly) the amount of notifications to return
let limit = Math.round(($(window).height() - headerHeight()) / 55);
// we REALLY don't want to be asking for negative counts of notifications
// less than 5 is also not that useful
if (limit < 5) {
limit = 5;
}
if (limit > 40) {
limit = 40;
}
const silent = this.currentUser.get("enforcedSecondFactor");
const stale = this.store.findStale(
"notification",
{ recent: true, silent, limit },
{ cacheKey: "recent-notifications" }
);
if (stale.hasResults) {
const results = stale.results;
let content = results.get("content");
// we have to truncate to limit, otherwise we will render too much
if (content && content.length > limit) {
content = content.splice(0, limit);
results.set("content", content);
results.set("totalRows", limit);
}
state.notifications = results;
} else {
state.loading = true;
}
stale
.refresh()
.then(notifications => {
if (!silent) {
this.currentUser.set("unread_notifications", 0);
}
state.notifications = notifications;
})
.catch(() => {
state.notifications = [];
})
.finally(() => {
state.loading = false;
state.loaded = true;
this.sendWidgetAction("notificationsLoaded", {
notifications: state.notifications,
markRead: () => this.markRead()
});
this.scheduleRerender();
});
},
html(attrs, state) {
if (!state.loaded) {
this.refreshNotifications(state);
}
const result = [];
if (state.loading) {
result.push(h("div.spinner-container", h("div.spinner")));
} else if (state.notifications.length) {
const notificationItems =
state.notifications.map(attrs => {
const notificationName =
this.site.notificationLookup[attrs.notification_type];
const widgetNames = [
`${notificationName.replace(/_/g, '-')}-notification-item`,
"default-notification-item"
];
return this.attach(widgetNames, attrs);
});
result.push(h("hr"));
const items = [notificationItems];
if (notificationItems.length > 5) {
items.push(
h(
"li.read.last.heading.show-all",
this.attach("button", {
title: "notifications.more",
icon: "chevron-down",
action: "showAllNotifications",
className: "btn"
})
)
);
}
result.push(h("ul", items));
}
return result;
},
showAllNotifications() {
DiscourseURL.routeTo(`${this.attrs.path}/notifications`);
}
});