Skip to content
This repository has been archived by the owner on Jul 2, 2021. It is now read-only.

Commit

Permalink
Merge pull request #73 from Wikia/IRIS-4163
Browse files Browse the repository at this point in the history
IRIS-4163 | Load on site notifications when user goes to user profile
  • Loading branch information
tortila authored Apr 14, 2017
2 parents 20f74e2 + 941fc14 commit 6e07a00
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 114 deletions.
6 changes: 6 additions & 0 deletions app/components/wikia-user-profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export default Component.extend(

username: computed.oneWay('currentUser.name'),

init() {
this._super(...arguments);
this.errors = [];
this.get('notifications').loadFirstPage();
},

didRender() {
this._super(...arguments);
this.element.scrollTop = 0;
Expand Down
9 changes: 0 additions & 9 deletions app/mixins/mark-all-notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,11 @@ import {trackMarkAllAsRead} from '../utils/notifications-tracker';

const {Mixin} = Ember;

/**
* @typedef {Object} ImageCropData
* @property {number} x
* @property {number} y
* @property {number} width
* @property {number} height
*/

export default Mixin.create(
{
actions: {
markAllAsRead() {
trackMarkAllAsRead();

this.get('notifications').markAllAsRead();
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/mixins/notifications-scroll-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default Mixin.create({
const target = $(event.target);

if (this.hasAlmostScrolledToTheBottom(target)) {
this.get('notifications').loadMoreResults();
this.get('notifications').loadNextPage();
}
},

Expand Down
113 changes: 38 additions & 75 deletions app/models/notifications/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,63 @@ import Ember from 'ember';
import Notification from './notification';
import fetch from 'ember-network/fetch';
import {convertToIsoString} from '../../utils/iso-date-time';
import {getOnSiteNotificationsServiceUrl, getQueryString} from '../../utils/url';
import {getOnSiteNotificationsServiceUrl} from '../../utils/url';

const {Object: EmberObject, A, RSVP, Logger} = Ember;
const {Object: EmberObject, A, RSVP, Logger, get} = Ember;

const NotificationsModel = EmberObject.extend({
unreadCount: 0,
data: null,
data: new A(),

getNewestNotificationISODate() {
return convertToIsoString(this.get('data.0.timestamp'));
},

getOldestNotificationISODate() {
return convertToIsoString(this.get('data.lastObject.timestamp'));
/**
* @return {Promise}
*/
loadUnreadNotificationCount() {
return fetch(getOnSiteNotificationsServiceUrl('/notifications/unread-count'), {credentials: 'include'})
.then((response) => response.json())
.then((result) => {
this.set('unreadCount', result.unreadCount);
}).catch((error) => {
this.set('unreadCount', 0);
Logger.error('Setting notifications unread count to 0 because of the API fetch error');
});
},

setNormalizedData(apiData) {
this.setProperties({
data: new A()
});

const notifications = apiData.notifications;

if (notifications && notifications.length) {
this.addNotifications(notifications);
}
/**
* @return {Promise.<string>}
*/
loadFirstPageReturningNextPageLink() {
return fetch(getOnSiteNotificationsServiceUrl('/notifications'), {credentials: 'include'})
.then((response) => response.json())
.then((data) => {
this.addNotifications(data.notifications);
return this.getNext(data);
});
},

loadMoreResults() {
const queryString = getQueryString({
startingTimestamp: this.getOldestNotificationISODate()
});

return fetch(getOnSiteNotificationsServiceUrl(`/notifications${queryString}`), {
/**
* @param page link to the page to load
* @return {Promise.<string>}
*/
loadPageReturningNextPageLink(page) {
return fetch(getOnSiteNotificationsServiceUrl(page), {
method: 'GET',
credentials: 'include'
})
.then((response) => response.json())
}).then((response) => response.json())
.then((data) => {
this.addNotifications(data.notifications);
return data.notifications.length;
return this.getNext(data);
});
},

getNext(data) {
return get(data, '_links.next') || null;
},

markAsRead(notification) {
if (!notification.isUnread) {
return RSVP.reject();
Expand Down Expand Up @@ -81,55 +95,4 @@ const NotificationsModel = EmberObject.extend({

});

NotificationsModel.reopenClass({
/**
* @returns {Ember.RSVP.Promise}
*/
getNotifications() {
const model = NotificationsModel.create();

return RSVP.all([
this.getNotificationsList(model),
this.getUnreadNotificationsCount(model)
]).then(() => {
return model;
});
},

getUnreadNotificationsCount(model) {
return fetch(getOnSiteNotificationsServiceUrl('/notifications/unread-count'), {
credentials: 'include'
})
.then((response) => {
if (response.ok) {
response.json().then((result) => {
model.set('unreadCount', result.unreadCount);
});
} else {
model.set('unreadCount', 0);
Logger.error('Notifications unread-count error:', response);
}
}).catch((error) => {
model.set('unreadCount', 0);
Logger.error('Setting notifications unread count to 0 because of the API fetch error');
});
},

getNotificationsList(model) {
return this.requestNotifications().then((data) => {
model.setNormalizedData(data);
});
},

/**
* @private
*/
requestNotifications() {
return fetch(getOnSiteNotificationsServiceUrl('/notifications'), {
credentials: 'include'
}).then((response) => response.json());
}

});

export default NotificationsModel;
65 changes: 37 additions & 28 deletions app/services/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import NotificationsModel from '../models/notifications/notifications';
const {Service, Logger, computed, inject, RSVP} = Ember;

export default Service.extend({
model: NotificationsModel.create(),
isLoading: false,
allLoaded: false,
model: null,
notificationsPerPage: 10,
nextPage: null,

currentUser: inject.service(),
wikiVariables: inject.service(),
Expand All @@ -16,29 +15,18 @@ export default Service.extend({
/**
* @private
*/
isUserAuthenticated: Ember.computed.bool('currentUser.isAuthenticated'),
isUserAnonymous: Ember.computed.not('currentUser.isAuthenticated'),

modelLoader: computed('isUserAuthenticated', function () {
modelLoader: computed('isUserAnonymous', function () {
if (this.get('fastboot.isFastBoot')) {
return;
}
this.set('isLoading', true);
if (!this.get('isUserAuthenticated')) {
this.set('isLoading', false);
if (this.get('isUserAnonymous') === true) {
return RSVP.reject();
}

return NotificationsModel.getNotifications()
.then((model) => {
this.setProperties({
model,
isLoading: false,
allLoaded: model.data.length < this.get('notificationsPerPage')
});
})
return this.get('model').loadUnreadNotificationCount()
.catch((err) => {
Logger.warn('Couldn\'t load notifications', err);
this.set('isLoading', false);
Logger.warn('Couldn\'t load notification count', err);
});
}),

Expand All @@ -52,22 +40,42 @@ export default Service.extend({
this.get('modelLoader');
},

loadMoreResults() {
if (this.get('isLoading') === true || !this.get('isUserAuthenticated') || this.get('allLoaded') === true) {
loadFirstPage() {
if (this.get('isUserAnonymous') === true
|| this.get('isLoading') === true
|| this.get('nextPage') !== null) {
return;
}
this.set('isLoading', true);
this.get('model')
.loadFirstPageReturningNextPageLink()
.then((nextPage) => {
this.set('nextPage', nextPage);
})
.catch((err) => {
Logger.warn('Couldn\'t load first page', err);
})
.finally(() => {
this.set('isLoading', false);
});
},

loadNextPage() {
if (this.get('isUserAnonymous') === true
|| this.get('isLoading') === true
|| this.get('nextPage') === null) {
return;
}
this.set('isLoading', true);
this.get('model')
.loadMoreResults(this.get('notificationsPerPage'))
.then((resultCount) => {
this.setProperties({
isLoading: false,
allLoaded: resultCount < this.get('notificationsPerPage')
});
.loadPageReturningNextPageLink(this.get('nextPage'))
.then((nextPage) => {
this.set('nextPage', nextPage);
})
.catch((err) => {
Logger.warn('Couldn\'t load more notifications', err);
})
.finally(() => {
this.set('isLoading', false);
});
},
Expand All @@ -78,6 +86,7 @@ export default Service.extend({

markAsRead(notification) {
this.get('model').markAsRead(notification);
}
},


});
13 changes: 12 additions & 1 deletion app/templates/components/wikia-user-profile.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,18 @@
</ul>
{{else}}
<p class="wds-notifications__zero-state">
{{i18n 'notifications-no-notifications-message' ns='design-system'}}
{{#if isLoadingNewResults}}
{{wds-spinner
active=true
isBlock=true
isThemed=false
overlay=false
radius=15
strokeWidth=2
}}
{{else}}
{{i18n 'notifications-no-notifications-message' ns='design-system'}}
{{/if}}
</p>
{{/if}}
</div>

0 comments on commit 6e07a00

Please sign in to comment.