UNPKG

linagora-rse

Version:
332 lines (288 loc) 10.4 kB
'use strict'; angular.module('esn.activitystreams-tracker', [ 'esn.session', 'esn.websocket', 'esn.activitystream', 'esn.user' ]) .factory('ASTrackerAPI', function($log, userAPI, activitystreamAPI) { function getActivityStreams(domainid, objectType) { return userAPI.getActivityStreams({domainid: domainid, member: true}).then(function(response) { response.data = response.data.filter(function(stream) { return stream.target && stream.target.objectType === objectType; }); return response; }); } function getUnreadCount(id) { $log.debug('Get unreads for stream ' + id); return activitystreamAPI.getUnreadCount(id); } return { getActivityStreams: getActivityStreams, getUnreadCount: getUnreadCount }; }) .factory('AStrackerHelpers', function(ASTrackerAPI, $q, session) { /** * Helper to get multiple activity streams * @param {array} ids an array of ids * @param {function} callback fn like callback(err, activityStreams) */ function getUnreadsCount(ids, callback) { var unreadsCount = []; var promises = ids.map(function(id) { var defer = $q.defer(); ASTrackerAPI.getUnreadCount(id).then( function(response) { unreadsCount.push(response.data); defer.resolve(); }, function(err) { defer.reject(err); }); return defer.promise; }); $q.all(promises).then(function() { callback(null, unreadsCount); }, callback); } /** * Helper to get the activity streams with unread count. * activityStreamsWithUnreadCount = [ * { * uuid: {string}, * display_name: {string}, * href: {string}, * img: {string}, * target: {object}, * unread_count: {number} * }, * { ... } * ] * @param {function} callback - fn like callback(err, activityStreamsWithUnreadCount) */ function getActivityStreamsWithUnreadCount(objectType, callback) { ASTrackerAPI.getActivityStreams(session.domain._id, objectType).then(function(response) { var activityStreams = response.data; var ids = activityStreams.map(function(element) { return element.uuid; }); getUnreadsCount(ids, function(err, unreadsCount) { if (err) { return callback(err); } var activityStreamsWithUnreadCount = activityStreams.map(function(elementMap) { var result = { uuid: elementMap.uuid, display_name: elementMap.target.displayName, href: '#', img: '', unread_count: 0 }; activityStreams.some(function(elementSome) { if (elementSome.uuid === elementMap.uuid && elementSome.target.objectType === objectType) { result.target = elementSome.target; return true; } }); unreadsCount.some(function(elementSome) { if (elementSome._id === elementMap.uuid) { result.unread_count = elementSome.unread_count; return true; } }); return result; }); return callback(null, activityStreamsWithUnreadCount); }); }, callback); } return { getActivityStreamsWithUnreadCount: getActivityStreamsWithUnreadCount }; }) .controller('ASTrackerController', function($rootScope, $scope, $timeout, $log, ASTrackerNotificationService, ASTrackerAPI, ASTrackerSubscriptionService) { $scope.$on('$destroy', function() { ASTrackerNotificationService.removeAllListeners(); }); var unregister = $rootScope.$on('activitystream:updated', function(evt, data) { if (data && data.activitystreamUuid) { // Usage of $timeout is to wait the tracker update in database $timeout(function() { ASTrackerAPI.getUnreadCount(data.activitystreamUuid).then( function(response) { ASTrackerNotificationService.updateUnread(data.activitystreamUuid, response.data.unread_count); } ); }, 1000); } }); $scope.$on('$destroy', function() { unregister(); }); var joinHandler = $rootScope.$on('collaboration:join', function(evt, data) { $log.debug('Got a join event', data); if (data && data.collaboration && data.collaboration.objectType) { var handlers = ASTrackerSubscriptionService.get(data.collaboration.objectType); if (!handlers || handlers.length === 0) { return; } handlers.forEach(function(handler) { try { handler.onJoin(data); } catch (e) { $log.error('Error while calling join handler', e); } }); } }); var leaveHandler = $rootScope.$on('collaboration:leave', function(evt, data) { $log.debug('Got a leave event', data); if (data && data.collaboration && data.collaboration.objectType) { var handlers = ASTrackerSubscriptionService.get(data.collaboration.objectType); if (!handlers || handlers.length === 0) { return; } handlers.forEach(function(handler) { try { handler.onLeave(data); } catch (e) { $log.error('Error while calling leave handler', e); } }); } }); $scope.$on('$destroy', function() { joinHandler(); leaveHandler(); }); }) .factory('ASTrackerNotificationService', function($rootScope, $log, $timeout, AStrackerHelpers, ASTrackerAPI, livenotification, session, _) { this.notifications = {}; this.activityStreams = []; var self = this; function updateUnread(activityStreamUuid, count) { if (!self.activityStreams) { return; } self.activityStreams.some(function(activityStream) { if (activityStream.uuid === activityStreamUuid) { activityStream.unread_count = count; return true; } }); } function liveNotificationHandler(data) { var activityStreamUuid = data.target[0]._id; if (data.verb === 'update') { $rootScope.$emit('activitystream:updateMessage', data); } if (data.actor._id !== session.user._id) { ASTrackerAPI.getUnreadCount(activityStreamUuid).then(function(response) { updateUnread(activityStreamUuid, response.data.unread_count); }); } } var getUnreadUpdate = function(activityStreamUuid) { updateUnread(activityStreamUuid, 0); $rootScope.$emit('activitystream:userUpdateRequest', { activitystreamUuid: activityStreamUuid }); }; function removeAllListeners() { self.notifications.forEach(function() { self.notification.removeListener('notification', liveNotificationHandler); }); } function subscribeToStreamNotification(streamId) { if (self.notifications[streamId]) { return false; } var socketIORoom = livenotification('/activitystreams', streamId).on('notification', liveNotificationHandler); self.notifications[streamId] = socketIORoom; return true; } function unsubscribeFromStreamNotification(streamId) { if (self.notifications[streamId]) { self.notifications[streamId].removeListener('notification', liveNotificationHandler); delete self.notifications[streamId]; } } function streamNotificationHasSubscribers(streamId) { return !!self.notifications[streamId]; } function addItem(stream) { self.activityStreams.push(stream); } function removeItem(streamId) { _.remove(self.activityStreams, { uuid: streamId }); } return { addItem: addItem, removeItem: removeItem, updateUnread: updateUnread, subscribeToStreamNotification: subscribeToStreamNotification, unsubscribeFromStreamNotification: unsubscribeFromStreamNotification, removeAllListeners: removeAllListeners, getUnreadUpdate: getUnreadUpdate, streams: self.activityStreams, streamNotificationHasSubscribers: streamNotificationHasSubscribers }; }) .factory('ASTrackerSubscriptionService', function($log, objectTypeAdapter, ASTrackerNotificationService) { var handlers = {}; function joinLeaveWrapper(objectType, handler) { return { onJoin: function(data) { if (data.collaboration.objectType !== objectType) { return; } handler.get(data.collaboration.id).then(function(success) { var uuid = success.data.activity_stream.uuid; var streamInfo = objectTypeAdapter.adapt(success.data); streamInfo.uuid = uuid; streamInfo.display_name = streamInfo.displayName; streamInfo.href = streamInfo.url; streamInfo.img = streamInfo.avatarUrl; var registered = ASTrackerNotificationService.subscribeToStreamNotification(uuid); if (registered) { ASTrackerNotificationService.addItem(streamInfo); } }, function(err) { $log.debug('Error while getting collaboration', err.data); }); }, onLeave: function(data) { if (data.collaboration.objectType !== objectType) { return; } handler.get(data.collaboration.id).then(function(success) { var uuid = success.data.activity_stream.uuid; ASTrackerNotificationService.unsubscribeFromStreamNotification(uuid); ASTrackerNotificationService.removeItem(uuid); }, function(err) { $log.debug('Error while getting the collaboration', err.data); }); } }; } function register(objectType, handler) { if (!objectType || !handler) { return; } if (!handlers[objectType]) { handlers[objectType] = []; } handlers[objectType].push(joinLeaveWrapper(objectType, handler)); } function get(objectType) { if (!objectType || !handlers[objectType]) { return []; } return handlers[objectType]; } return { register: register, get: get }; });