frontend/js/modules/message.js
'use strict';
angular.module('esn.message')
.constant('ESN_MESSAGE_TYPES', ['whatsup', 'event', 'poll'])
.constant('ESN_MESSAGE_DEFAULT_POLL_CHOICES', [{ label: '' }, { label: '' }])
.run(function(esnTimelineEntryProviders, $q, ESN_MESSAGE_TYPES) {
esnTimelineEntryProviders.register({
verb: 'post',
templateUrl: '/views/modules/message/timeline/post.html',
canHandle: function() {
return true;
}
});
esnTimelineEntryProviders.register({
verb: 'like',
templateUrl: '/views/modules/message/timeline/like.html',
canHandle: function(entry) {
return ESN_MESSAGE_TYPES.indexOf(entry.object.objectType) >= 0;
}
});
esnTimelineEntryProviders.register({
verb: 'update',
templateUrl: '/views/modules/message/timeline/poll-reply.html',
canHandle: function(entry) {
return entry.object.objectType === 'poll';
}
});
})
.controller('messageEditionController', function($scope, ESN_MESSAGE_TYPES) {
var types = ESN_MESSAGE_TYPES;
$scope.type = types[0];
$scope.show = function(type) {
if (types.indexOf(type) >= 0) {
$scope.type = type;
} else {
$scope.type = types[0];
}
};
})
.directive('messageEdition', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/messageEdition.html'
};
})
.controller('messageController', function($scope, $q, messageAPI, $alert, $rootScope, geoAPI, messageAttachmentHelper,
backgroundProcessorService, notificationFactory, fileUploadService,
DEFAULT_FILE_TYPE, ESN_MESSAGE_DEFAULT_POLL_CHOICES) {
$scope.rows = 1;
$scope.position = {};
$scope.attachments = [];
$scope.uploadService = null;
$scope.validators = [];
$scope.validationError = {};
$scope.expand = function() {
if ($scope.rows === 1) {
$scope.rows = 5;
}
};
$scope.shrink = function() {
return;
};
$scope.onFileSelect = function($files) {
$scope.expand();
if (!$scope.uploadService) {
$scope.uploadService = fileUploadService.get();
}
for (var i = 0; i < $files.length; i++) {
$scope.attachments.push($scope.uploadService.addFile($files[i], true));
}
};
$scope.removeFile = function(file) {
$scope.attachments = $scope.attachments.filter(function(attachment) {
return attachment.file !== file;
});
};
$scope.sendMessage = function() {
if (!$scope.messageContent || $scope.messageContent.trim().length === 0) {
$scope.displayError('You can not say nothing!');
return;
}
$scope.validators.forEach(function(validator) {
validator();
});
if ($scope.validationError && Object.keys($scope.validationError).length > 0) {
$scope.displayValidationError();
return;
}
if (!$scope.activitystream || !$scope.activitystream.activity_stream || !$scope.activitystream.activity_stream.uuid) {
$scope.displayError('You can not post to an unknown activitystream');
return;
}
var objectType = $scope.type;
var data = { description: $scope.messageContent };
if ($scope.position.coords) {
data.position = {
coords: {
latitude: $scope.position.coords.latitude,
longitude: $scope.position.coords.longitude
}
};
}
if ($scope.position.display_name) {
data.position.display_name = $scope.position.display_name;
}
var target = {
objectType: 'activitystream',
id: $scope.activitystream.activity_stream.uuid
};
function send(objectType, data, targets, attachments) {
var defer = $q.defer();
var attachmentsModel = attachments.map(function(attachment) {
var type = attachment.file.type;
if (!type || type.length === 0) {
type = DEFAULT_FILE_TYPE;
}
return {_id: attachment.response.data._id, name: attachment.file.name, contentType: type, length: attachment.file.size};
});
if ($scope.additionalData) {
data.data = angular.copy($scope.additionalData);
}
messageAPI.post(objectType, data, targets, attachmentsModel).then(
function(response) {
$rootScope.$emit('message:posted', {
activitystreamUuid: $scope.activitystream.activity_stream.uuid,
id: response.data._id
});
return defer.resolve();
},
function(err) {
return defer.reject(err);
}
);
return defer.promise;
}
function clean() {
$scope.messageContent = '';
$scope.rows = 1;
$scope.attachments = [];
$scope.uploadService = null;
$scope.additionalData = {};
$scope.data = {};
if ($scope.position.coords) {
$scope.position = {};
}
}
if ((!$scope.uploadService) || ($scope.uploadService && $scope.uploadService.isComplete())) {
return send(objectType, data, [target], $scope.attachments).then(function() {
clean();
$scope.show('whatsup');
}, function(err) {
if (err.data.status === 403) {
$scope.displayError('You do not have enough rights to write a new message here');
} else {
$scope.displayError('Error while sharing your whatsup message');
}
});
} else {
notificationFactory.weakInfo('Publishing message...', 'Your message is being sent and will be published as soon as possible');
var done = function(attachments) {
return send(objectType, data, [target], attachments).then(function() {
notificationFactory.weakInfo('Message published', 'Your message has been published');
}, function() {
notificationFactory.weakInfo('Message error', 'Your message has not been published');
});
};
backgroundProcessorService.add($scope.uploadService.await(done));
clean();
$scope.show('whatsup');
}
};
$scope.resetMessage = function() {
$scope.rows = 1;
$scope.messageContent = '';
$scope.removePosition();
$scope.uploadService = null;
$scope.additionalData = {
pollChoices: angular.copy(ESN_MESSAGE_DEFAULT_POLL_CHOICES)
};
$q.all(messageAttachmentHelper.deleteAttachments($scope.attachments)).then(function() {
$scope.attachments = [];
$scope.uploads = [];
$scope.complete = 0;
});
};
$scope.displayValidationError = function() {
var errorMsg = '';
angular.forEach($scope.validationError, function(error) {
errorMsg = errorMsg + error + ' ';
});
$scope.displayError(errorMsg);
};
$scope.displayError = function(err) {
$alert({
content: err,
type: 'danger',
show: true,
position: 'bottom',
container: '.message-panel > .error',
duration: '3',
animation: 'am-fade'
});
};
})
.controller('messageCommentController', function($scope, $q, messageAPI, $alert, $rootScope, geoAPI, messageAttachmentHelper,
backgroundProcessorService, notificationFactory, fileUploadService, DEFAULT_FILE_TYPE) {
$scope.attachments = [];
$scope.uploadService = null;
$scope.commentContent = '';
$scope.sending = false;
$scope.rows = 1;
$scope.position = {};
$scope.expand = function() {
if ($scope.rows === 1) {
$scope.rows = 4;
}
};
$scope.shrink = function() {};
$scope.onFileSelect = function($files) {
$scope.expand();
if (!$scope.uploadService) {
$scope.uploadService = fileUploadService.get();
}
for (var i = 0; i < $files.length; i++) {
$scope.attachments.push($scope.uploadService.addFile($files[i], true));
}
};
$scope.removeFile = function(file) {
$scope.attachments = $scope.attachments.filter(function(attachment) {
return attachment.file !== file;
});
};
$scope.addComment = function(objectType) {
if ($scope.sending) {
$scope.displayError('Client problem, unexpected action!');
return;
}
if (!$scope.message) {
$scope.displayError('Client problem, message is missing!');
return;
}
if (!$scope.commentContent || $scope.commentContent.trim().length === 0) {
$scope.displayError('You can not say nothing!');
return;
}
objectType = objectType || $scope.message.objectType;
var data = {
description: $scope.commentContent
};
var inReplyTo = {
objectType: $scope.message.objectType,
_id: $scope.message._id
};
if ($scope.position.coords) {
data.position = {
coords: {
latitude: $scope.position.coords.latitude,
longitude: $scope.position.coords.longitude
}
};
}
if ($scope.position.display_name) {
data.position.display_name = $scope.position.display_name;
}
if ($scope.additionalData) {
data.data = $scope.additionalData;
}
function comment(objectType, data, inReplyTo, attachments) {
var defer = $q.defer();
var attachmentsModel = attachments.map(function(attachment) {
var type = attachment.file.type;
if (!type || type.length === 0) {
type = DEFAULT_FILE_TYPE;
}
return {_id: attachment.response.data._id, name: attachment.file.name, contentType: type, length: attachment.file.size};
});
if ($scope.additionalData) {
data.data = angular.copy($scope.additionalData);
}
messageAPI.addComment(objectType, data, inReplyTo, attachmentsModel).then(
function(response) {
$rootScope.$emit('message:comment', {
id: response.data._id,
parent: $scope.message
});
return defer.resolve();
},
function(err) {
return defer.reject(err);
}
);
return defer.promise;
}
function clean() {
$scope.commentContent = '';
$scope.shrink();
$scope.attachments = [];
$scope.uploadService = null;
$scope.sending = false;
}
if ((!$scope.uploadService) || ($scope.uploadService && $scope.uploadService.isComplete())) {
$scope.sending = true;
return comment(objectType, data, inReplyTo, $scope.attachments).then(clean, function(err) {
$scope.sending = false;
if (err.data.status === 403) {
$scope.displayError('You do not have enough rights to write a response here');
} else {
$scope.displayError('Error while adding comment');
}
});
} else {
notificationFactory.weakInfo('Publishing comment...', 'Your comment is being sent and will be published as soon as possible');
var done = function(attachments) {
return comment(objectType, data, inReplyTo, attachments).then(function() {
notificationFactory.weakInfo('Comment published', 'Your comment has been published');
}, function() {
notificationFactory.weakInfo('Comment error', 'Your comment has not been published');
});
};
backgroundProcessorService.add($scope.uploadService.await(done));
clean();
}
};
$scope.resetComment = function() {
$scope.commentContent = '';
$scope.rows = 1;
$scope.removePosition();
$q.all(messageAttachmentHelper.deleteAttachments($scope.attachments)).then(function() {
$scope.attachments = [];
$scope.uploads = [];
$scope.complete = 0;
});
};
$scope.displayError = function(err) {
$alert({
content: err,
type: 'danger',
show: true,
position: 'bottom',
container: '[error-message-id="' + $scope.message._id + '"]',
duration: '3',
animation: 'am-fade'
});
};
})
.controller('singleMessageDisplayController', function($rootScope, $scope, messageAPI, message, activitystream) {
$scope.message = message;
$scope.parentMessage = true;
$scope.streams = [];
$scope.activitystream = activitystream;
function onCommentPosted(evt, msgMeta) {
if (msgMeta.parent._id !== $scope.message._id) {
return;
}
messageAPI.get(message._id).then(function(response) {
$scope.message.responses = response.data.responses || $scope.message.responses;
});
}
var unregCmtPostedListener = $rootScope.$on('message:comment', onCommentPosted);
$scope.$on('$destroy', function() {
unregCmtPostedListener();
});
})
.directive('whatsupMessage', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/templates/whatsupMessage.html',
controller: 'attachmentAlternativeUploaderModalNoUploaderController',
controllerAs: '$ctrl'
};
})
.directive('pollMessage', function($log, session, pollAPI) {
function link(scope, element) {
var results, choices;
scope.showMeChart = false;
scope.toggleChartDisplay = function() {
scope.showMeChart = !scope.showMeChart;
};
function refreshScopeData() {
results = scope.message.pollResults;
choices = scope.message.pollChoices;
scope.pollContext = {
vote: null,
isCreator: session.user._id === scope.message.author._id,
hasVoted: results.filter(function(result) {
return result.actor.objectType === 'user' && result.actor.id === session.user._id;
}).length > 0
};
computeResults();
}
function computeResults() {
scope.pollContext.results = [];
var cache = {};
choices.forEach(function(choice) {
cache[choice.label] = 0;
});
results.forEach(function(result) {
var label = choices[result.vote].label;
cache[label]++;
});
scope.pollContext.results = choices.map(function(choice) {
return {label: choice.label, votes: cache[choice.label], ratio: cache[choice.label] > 0 ? Math.round((cache[choice.label] * 100) / results.length) : 0};
});
scope.pollContext.chart = scope.pollContext.results.map(function(result) {
return result.votes;
});
scope.pollContext.labels = scope.pollContext.results.map(function(result) {
return result.label;
});
}
function onVoteSuccess(response) {
$log.debug('Vote succedded');
scope.pollContext.hasVoted = true;
scope.message = response.data;
refreshScopeData();
}
function onVoteFailure() {
$log.debug('Vote failed');
}
scope.recordVote = function() {
var button = element.find('.vote-button');
var vote = scope.pollContext.vote;
if (vote === null || !choices[vote]) {
return $log.warn('Cannot vote: vote is invalid ' + vote);
}
button.attr('disabled', 'true');
pollAPI.vote(scope.message._id, vote)
.then(onVoteSuccess, onVoteFailure)
.finally(function() {
button.removeAttr('disabled');
});
};
refreshScopeData();
}
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/templates/pollMessage.html',
link: link
};
})
.directive('emailMessage', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/templates/emailMessage.html'
};
})
.directive('whatsupEdition', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/whatsup/whatsupEdition.html',
controller: 'attachmentAlternativeUploaderModalNoUploaderController',
controllerAs: '$ctrl'
};
})
.directive('whatsupAddComment', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/whatsup/whatsupAddComment.html',
controller: 'attachmentAlternativeUploaderModalNoUploaderController',
controllerAs: '$ctrl'
};
})
.directive('pollEdition', function(ESN_MESSAGE_DEFAULT_POLL_CHOICES) {
function link(scope) {
scope.additionalData = {
pollChoices: angular.copy(ESN_MESSAGE_DEFAULT_POLL_CHOICES)
};
scope.validators.push(function() {
var choices = scope.additionalData.pollChoices.filter(function(choice) {
return choice.label && choice.label.length;
});
var choicesMap = {};
var hasDuplicates = false;
choices.forEach(function(element) {
if (element.label.toLowerCase() in choicesMap) {
hasDuplicates = true;
}
choicesMap[element.label.toLowerCase()] = true;
});
if (!choices || choices.length < 2) {
scope.validationError.title = 'Your poll should contain at least two choices.';
} else if (!scope.messageContent || !scope.messageContent.length) {
scope.validationError.title = 'Your poll should have a description.';
} else if (hasDuplicates) {
scope.validationError.title = 'Your poll has duplicated choices.';
} else {
delete scope.validationError.title;
}
});
scope.appendChoice = function() {
scope.additionalData.pollChoices.push({label: ''});
};
}
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/poll/pollEdition.html',
link: link,
controller: 'attachmentAlternativeUploaderModalNoUploaderController',
controllerAs: '$ctrl'
};
})
.directive('messagesDisplay', function() {
return {
restrict: 'E',
replace: true,
scope: {
message: '='
},
templateUrl: '/views/modules/message/messagesDisplay.html'
};
})
.directive('messageTemplateDisplayer', function(RecursionHelper) {
return {
restrict: 'E',
replace: true,
scope: {
message: '=',
activitystream: '=?',
lastPost: '=',
parent: '=?',
// TODO: Rename to isParent
parentMessage: '=?'
},
templateUrl: '/views/modules/message/messagesTemplateDisplayer.html',
controller: function($scope) {
$scope.parentMessage = !!$scope.parentMessage;
$scope.onMessageLiked = function() {
$scope.message.likes.total_count++;
};
$scope.onMessageUnliked = function() {
if ($scope.message.likes.total_count <= 0) {
$scope.message.likes.total_count = 0;
} else {
$scope.message.likes.total_count--;
}
};
if (!$scope.activitystream) {
var origins = $scope.message.streamOrigins;
if (origins && origins.length > 0) {
$scope.activitystream = origins[0];
}
}
if ($scope.activitystream) {
$scope.writable = $scope.activitystream.writable;
} else {
$scope.writable = false;
}
},
compile: function(element) {
return RecursionHelper.compile(element, function() {});
}
};
})
.directive('messagePreviewDisplayer', function(RecursionHelper) {
return {
restrict: 'E',
replace: true,
scope: {
message: '='
},
templateUrl: '/views/modules/message/messagesPreviewDisplayer.html',
compile: function(element) {
return RecursionHelper.compile(element, function() {});
}
};
})
.directive('whatsupMessagePreview', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/previews/whatsupMessage.html'
};
})
.directive('emailMessagePreview', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/previews/emailMessage.html'
};
})
.directive('pollMessagePreview', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/previews/pollMessage.html'
};
})
.directive('messagePreview', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/previews/defaultMessage.html'
};
})
.directive('messagesThread', function() {
return {
restrict: 'E',
replace: true,
scope: {
message: '=',
activitystreamUuid: '=',
lastPost: '=',
writable: '='
},
templateUrl: '/views/modules/message/messagesThread.html'
};
})
.directive('messageAttachments', function() {
return {
restrict: 'E',
scope: {
message: '='
},
templateUrl: '/views/modules/message/attachments/messageAttachments.html'
};
})
.directive('messageEditionAttachment', function($timeout, fileAPIService) {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/attachments/messageEditionAttachment.html',
link: function($scope) {
$scope.cancel = function() {
if ($scope.attachment.uploaded) {
$scope.$parent.removeFile($scope.attachment.file);
fileAPIService.remove('files', $scope.attachment.response._id).then(function() {
$scope.attachment.defer.resolve({status: 'canceled'});
}, function() {
$scope.attachment.defer.resolve({status: 'can not delete file'});
});
} else if ($scope.attachment.uploading) {
$scope.attachment.cancel();
$scope.$parent.removeFile($scope.attachment.file);
$scope.attachment.defer.resolve({status: 'canceled'});
}
};
$scope.$on('$destroy', function() {
$scope.cancel();
});
}
};
})
.directive('messageEditionAttachments', function() {
return {
restrict: 'E',
templateUrl: '/views/modules/message/attachments/messageEditionAttachments.html'
};
})
.directive('shareMessageButton', function($modal) {
return {
restrict: 'E',
replace: true,
templateUrl: '/views/modules/message/share/share-message-button.html',
scope: true,
link: function($scope) {
$scope.$on('modal.hide', function(evt, modal) {
$scope.shareModal = null;
modal.destroy();
});
$scope.showShareModal = function() {
$scope.shareModal = $modal({scope: $scope, templateUrl: '/views/modules/message/share/share-message-modal.html'});
};
}
};
})
.directive('shareList', function() {
return {
restrict: 'E',
templateUrl: '/views/modules/message/share/share-list.html'
};
})
.directive('shareTag', function() {
return {
restrict: 'E',
templateUrl: '/views/modules/message/share/share-tag.html'
};
})
.controller('messageShareController', function($scope, $q, $log, $alert, notificationFactory, messageAPI, userAPI) {
$scope.sending = false;
$scope.share = function() {
if (!$scope.activitystream) {
$log.debug('activitystream is required');
return;
}
if ($scope.shares.length === 0) {
$log.debug('At least one share is required');
return;
}
var targets = $scope.shares.map(function(share) {
return {
objectType: 'activitystream',
id: share.uuid
};
});
var resource = {
objectType: 'activitystream',
id: $scope.activitystream.activity_stream.uuid
};
$scope.sending = true;
messageAPI.share($scope.message._id, resource, targets).then(function(result) {
$log.debug('Message has been shared', result.data._id);
if ($scope.shareModal) {
$scope.shareModal.hide();
}
$scope.messageShared();
}, function(err) {
$log.error('Can not share message', err.data);
$scope.displayError('Error while sharing message');
}).finally(function() {
$scope.sending = false;
});
};
$scope.selected = '';
$scope.shares = [];
$scope.$on('$typeahead.select', function(value, index) {
$scope.addTarget(index);
$scope.selected = null;
});
function isAlreadyInShares(target) {
return $scope.shares.some(function(share) {
return share.uuid === target.uuid;
});
}
function isCurrentActivityStream(target) {
return target.uuid === $scope.activitystream.activity_stream.uuid;
}
function isAlreadyShared(target) {
return $scope.message.copyOf &&
$scope.message.copyOf.target &&
$scope.message.copyOf.target.some(function(shared) {
return shared.id === target.uuid;
});
}
$scope.getTargets = function(str) {
return userAPI.getActivityStreams({name: str, writable: true}).then(function(response) {
return response.data.filter(function(target) {
return !isAlreadyInShares(target) && !isCurrentActivityStream(target);
});
});
};
$scope.addTarget = function(selected) {
if (isAlreadyInShares(selected) || isCurrentActivityStream(selected)) {
return;
}
if (isAlreadyShared(selected)) {
selected.already = true;
}
$scope.shares.push(selected);
};
$scope.removeShare = function(target) {
$scope.shares = $scope.shares.filter(function(share) {
return share.uuid !== target.uuid;
});
};
$scope.messageShared = function() {
notificationFactory.weakInfo('Message Sharing', 'Message has been shared!');
$scope.$emit('message:shared', {
message: $scope.message,
shares: $scope.shares
});
};
$scope.displayError = function(err) {
$alert({
content: err,
type: 'danger',
show: true,
position: 'bottom',
container: '#shareerror',
duration: '3',
animation: 'am-fade'
});
};
})
.factory('messageAttachmentHelper', function($q, fileAPIService) {
function deleteAttachments(attachments) {
var calls = [];
if (!attachments || attachments.length === 0) {
return;
}
angular.forEach(attachments, function(attachment) {
if (attachment.response && attachment.response._id) {
var defer = $q.defer();
fileAPIService.remove('files', attachment.response._id).then(function() {
defer.resolve({status: 'success', _id: attachment.response._id});
}, function() {
defer.resolve({status: 'error', _id: attachment.response._id});
});
calls.push(defer.promise);
} else if (attachment.uploading) {
attachment.cancel();
}
});
return calls;
}
return {
deleteAttachments: deleteAttachments
};
})
.factory('messageAPI', function(esnRestangular) {
function get(options) {
if (angular.isString(options)) {
return esnRestangular.one('messages', options).get();
}
return esnRestangular.all('messages').getList(options);
}
function post(objectType, data, targets, attachments) {
var payload = {};
payload.object = angular.copy(data);
payload.object.objectType = objectType;
payload.targets = targets;
if (attachments && angular.isArray(attachments)) {
payload.object.attachments = attachments;
}
return esnRestangular.all('messages').post(payload);
}
function addComment(objectType, data, inReplyTo, attachments) {
var payload = {};
payload.object = angular.copy(data);
payload.object.objectType = objectType;
payload.inReplyTo = inReplyTo;
if (attachments && angular.isArray(attachments)) {
payload.object.attachments = attachments;
}
return esnRestangular.all('messages').post(payload);
}
function share(id, resource, targets) {
var payload = {
resource: resource,
target: targets
};
return esnRestangular.one('messages', id).all('shares').post(payload);
}
return {
get: get,
post: post,
addComment: addComment,
share: share
};
})
.directive('sharedFrom', function(activitystreamAPI, objectTypeAdapter) {
return {
restrict: 'E',
templateUrl: '/views/modules/message/share/shared-from.html',
link: function(scope) {
if (scope.message && scope.message.copyOf && scope.message.copyOf.origin) {
activitystreamAPI.getResource(scope.message.copyOf.origin.resource.id).then(
function(response) {
var collaboration = response.data;
collaboration.object.objectType = collaboration.objectType;
scope.sharedFrom = objectTypeAdapter.adapt(collaboration.object);
},
function(error) {
scope.sharedFromError = error.details || error;
});
}
}
};
})
.directive('sharedTo', function(activitystreamAPI, messageAPI, objectTypeAdapter, $q) {
return {
restrict: 'E',
templateUrl: '/views/modules/message/share/shared-to.html',
link: function(scope) {
function updateShareTargets(target) {
if (!target) {
return;
}
var cache = [];
var targets = [];
target.forEach(function(target) {
if (cache.indexOf(target.id) === -1) {
cache.push(target.id);
targets.push(target);
}
});
var collaborations = [];
var restCalls = targets.map(function(target) {
return activitystreamAPI.getResource(target.id).then(
function(response) {
collaborations.push(response.data);
},
function(error) {
scope.sharedToError = error.details || error;
});
});
$q.all(restCalls).then(function() {
scope.shareTargets = collaborations.map(function(collaboration) {
collaboration.object.objectType = collaboration.objectType;
return objectTypeAdapter.adapt(collaboration.object);
});
},
function(error) {
scope.sharedToError = error.details || error;
});
}
if (scope.message && scope.message.copyOf && scope.message.copyOf.target) {
updateShareTargets(scope.message.copyOf.target);
} else {
scope.shareTargets = [];
}
scope.$on('message:shared', function(evt, data) {
if (data.message._id === scope.message._id) {
messageAPI.get(data.message._id).then(function(response) {
if (response.data.copyOf) {
scope.message.copyOf = response.data.copyOf;
updateShareTargets(scope.message.copyOf.target);
}
});
}
});
}
};
})
.directive('messageShared', function() {
return {
restrict: 'E',
scope: {
message: '='
},
templateUrl: '/views/modules/message/templates/includes/messageShared.html'
};
})
.directive('messageOembeds', function() {
return {
restrict: 'E',
scope: {
message: '='
},
templateUrl: '/views/modules/message/templates/includes/messageOembeds.html'
};
})
.directive('messageDateLink', function() {
return {
restrict: 'E',
scope: {
message: '=',
activitystream: '='
},
templateUrl: '/views/modules/message/templates/includes/messageDateLink.html'
};
})
.directive('messageBottomLinks', function() {
return {
restrict: 'E',
scope: true,
templateUrl: '/views/modules/message/templates/includes/messageBottomLinks.html'
};
})
.directive('messageComments', function() {
return {
restrict: 'E',
scope: true,
templateUrl: '/views/modules/message/templates/includes/messageComments.html'
};
})
.directive('setFocus', function() {
return {
link: function(scope, element, attrs) {
element.bind('click', function() {
angular.element(document.querySelector('.' + attrs.setFocus)).focus();
});
}
};
});