import debugLib from 'debug';
import createAction from 'redux-actions/lib/createAction';
import { createSelector } from 'reselect';
import { apiPatch } from './apiActions/apiRequest';
import { getEntitiesFromCollection } from '../../selectors/collectionSelector';
import apiGetCollection from './apiActions/apiGetCollection';
import { NOTIFICATIONS } from '../../data/collectionIds';
import { setEntity, updateEntities } from '../entities/entityActions';
import { GATEWAY_MESSAGE_AUTH } from '../../data/Injectables';
import { NOTIFICATION } from '../../data/entityTypes';
const debug = debugLib('SlimmingWorld:notificationActions');
export const UPDATE_NOTIFICATION_COUNT = 'notificationActions/UPDATE_NOTIFICATION_COUNT';
const updateNotificationCount = createAction(UPDATE_NOTIFICATION_COUNT);
export const GET_NOTIFICATIONS = 'notificationActions/GET_NOTIFICATIONS';
/**
* Retrieves notifications
* @param loadMore
* @param limit
*/
export const getNotifications = (loadMore = false, limit = 10) =>
apiGetCollection(
GET_NOTIFICATIONS,
GATEWAY_MESSAGE_AUTH,
'/notifications',
NOTIFICATIONS,
{
limit,
...(loadMore
? {
from: {
param: 'sinceId',
key: 'id',
},
}
: {}),
},
{
requestData: {
userId: 'me',
},
transformResponse: response => ({
pagination: response.pagination,
data: response.data.notifications,
}),
entityType: NOTIFICATION,
},
);
export const MARK_NOTIFICATION_READ = 'notificationActions/MARK_NOTIFICATION_READ';
/**
*
* Mark notifcation(s) as read
* @param ids
*/
export const markNotificationsRead = ids => (dispatch, getState) => {
const state = getState();
const idsArray = Array.isArray(ids) ? ids.find() : [ids];
const { totalRead, totalUnread } = state.notifications;
const { entities } = getEntitiesFromCollection(state, { collectionId: NOTIFICATIONS });
const entitiesToUpdate = entities.filter(entity => idsArray.indexOf(entity.id) > -1);
entitiesToUpdate.forEach(entity =>
dispatch(setEntity(NOTIFICATION, entity.id, { ...entity, isRead: true }, true)),
);
dispatch(
updateNotificationCount({
totalUnread: totalUnread - idsArray.length,
totalRead: totalRead + idsArray.length,
}),
);
dispatch(
apiPatch(MARK_NOTIFICATION_READ, GATEWAY_MESSAGE_AUTH, `/notifications/${idsArray.join(',')}`, {
isRead: true,
userId: 'me',
}),
).catch(error => {
debug(error);
dispatch(
updateNotificationCount({
totalUnread,
totalRead,
}),
);
entitiesToUpdate.forEach(entity =>
dispatch(setEntity(NOTIFICATION, entity.id, { ...entity, isRead: false }, true)),
);
});
};
export const MARK_ALL_NOTIFICATIONS_READ = 'notificationActions/MARK_ALL_NOTIFICATIONS_READ';
export const markAllNotificationsRead = () => (dispatch, getState) => {
const { totalRead, totalUnread } = getState().notifications;
return dispatch(
apiPatch(
MARK_ALL_NOTIFICATIONS_READ,
GATEWAY_MESSAGE_AUTH,
/**
* The userId is added directly as a query-parameter in the request URL, because this is the
* only PATCH-call where we have to do this. Normally, the userId would be passed in the body.
* However, this one is created in a different way because backend needs to support the old
* API-call (for the App) and proxy it to this one, resulting in adding the userId as a
* query-parameter.
*/
'/notifications/mark-all-as-read?userId=me',
),
).then(() => {
dispatch(updateEntities(NOTIFICATION, { isRead: true }, { isRead: false }));
dispatch(
updateNotificationCount({
totalRead: totalRead + totalUnread,
totalUnread: 0,
}),
);
});
};
const EMPTY_ARRAY = [];
export const createNotificationAwardFullSelector = createSelector(
state => state.entities.notification,
state => state.entities.award,
(notification, award) => {
const notifications = notification ? [...Object.values(notification)] : EMPTY_ARRAY;
const awards = award ? [...Object.values(award)] : EMPTY_ARRAY;
if (notifications.length > 0 && awards.length > 0) {
notifications.forEach((itemNoti, i) => {
awards.forEach(itemAward => {
if (itemNoti.award && itemNoti.award.id === itemAward.id) {
notifications[i] = {
...itemNoti,
award: {
...itemAward,
},
};
}
});
});
}
return notifications;
},
);