mirror of
https://github.com/discourse/discourse.git
synced 2025-02-05 06:23:59 +08:00
87 lines
2.4 KiB
JavaScript
87 lines
2.4 KiB
JavaScript
import { createWidget } from 'discourse/widgets/widget';
|
|
import { headerHeight } from 'discourse/components/site-header';
|
|
import { h } from 'virtual-dom';
|
|
|
|
export default createWidget('user-notifications', {
|
|
tagName: 'div.notifications',
|
|
buildKey: () => 'user-notifications',
|
|
|
|
defaultState() {
|
|
return { notifications: [], loading: false };
|
|
},
|
|
|
|
notificationsChanged() {
|
|
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 stale = this.store.findStale('notification', {recent: true, 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 => {
|
|
this.currentUser.set('unread_notifications', 0);
|
|
state.notifications = notifications;
|
|
}).catch(() => {
|
|
state.notifications = [];
|
|
}).finally(() => {
|
|
state.loading = false;
|
|
this.scheduleRerender();
|
|
});
|
|
},
|
|
|
|
html(attrs, state) {
|
|
if (!state.notifications.length) {
|
|
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(n => this.attach('notification-item', n));
|
|
|
|
result.push(h('hr'));
|
|
|
|
const items = [notificationItems];
|
|
|
|
if (notificationItems.length > 5) {
|
|
const href = `${attrs.path}/notifications`;
|
|
|
|
items.push(
|
|
h('li.read.last.heading', h('a', { attributes: { href } }, [I18n.t('notifications.more'), '...'])),
|
|
h('hr')
|
|
);
|
|
}
|
|
|
|
result.push(h('ul', items));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
});
|