Commit af7667d1 authored by Vladimir Baranov's avatar Vladimir Baranov

rref #5392. Add message editor

parent 58148155
...@@ -2480,6 +2480,7 @@ table.dataTable thead .sorting:after { ...@@ -2480,6 +2480,7 @@ table.dataTable thead .sorting:after {
.chat-app .conversation-section .user-message .message-content { .chat-app .conversation-section .user-message .message-content {
font-family: 'robotomedium'; font-family: 'robotomedium';
position: relative;
} }
.chat-app .conversation-section .message-content-url { .chat-app .conversation-section .message-content-url {
...@@ -2576,14 +2577,14 @@ table.dataTable thead .sorting:after { ...@@ -2576,14 +2577,14 @@ table.dataTable thead .sorting:after {
opacity:1; opacity:1;
} }
.chat-app .conversation-section .user-message .edit-text-message input {
.chat-app .conversation-section .user-message .edit-text-message .editor {
width: 100%; width: 100%;
margin-bottom: 7px; margin-bottom: 7px;
margin-top: 7px; margin-top: 7px;
height: 30px;
border-radius: 3px; border-radius: 3px;
border: 1px solid #ccc; border: 1px solid #ccc;
padding-left: 7px; padding: 5px 10px;
outline: none; outline: none;
} }
......
angular.module("ulakbus.messaging") angular.module("ulakbus.messaging")
.directive('messaging', function (Generator, MessagingService, $log, $rootScope, MessagingPopup, Utils, $q) { .directive('messaging', function (Generator, MessagingService, $log, $rootScope, MessagingPopup, Utils, $q, $timeout) {
// get channel key // get channel key
function getKey (channel) { function getKey (channel) {
...@@ -79,11 +79,21 @@ angular.module("ulakbus.messaging") ...@@ -79,11 +79,21 @@ angular.module("ulakbus.messaging")
if (channel.messages){ if (channel.messages){
channel.messages.push(message); channel.messages.push(message);
} }
}; }
updateLastMessage(message); updateLastMessage(message);
reportLastSeenMessage(); reportLastSeenMessage();
} }
function updateMessage(message){
// update current channel messages only
if (message.channel_key != getKey(iScope.selectedChannel)) return;
// update only visible messages
var storedMessage = Utils.findWhere(iScope.selectedChannel.messages, {key: message.key})
if (storedMessage){
angular.extend(storedMessage, message)
}
}
function updateAndSelect(channelKey){ function updateAndSelect(channelKey){
channelKey = getKey(channelKey); channelKey = getKey(channelKey);
return iScope.updateChannelsList().then(function(){ return iScope.updateChannelsList().then(function(){
...@@ -278,6 +288,7 @@ angular.module("ulakbus.messaging") ...@@ -278,6 +288,7 @@ angular.module("ulakbus.messaging")
iScope.applyMessageAction = function(message, action){ iScope.applyMessageAction = function(message, action){
var actionView = action[1]; var actionView = action[1];
switch (actionView) { switch (actionView) {
case "_zops_favorite_message": case "_zops_favorite_message":
MessagingService.add_to_favorites(message.key) MessagingService.add_to_favorites(message.key)
.then(function(){ .then(function(){
...@@ -285,6 +296,7 @@ angular.module("ulakbus.messaging") ...@@ -285,6 +296,7 @@ angular.module("ulakbus.messaging")
message.actions = null; message.actions = null;
}); });
break; break;
case "_zops_flag_message": case "_zops_flag_message":
MessagingService.flag_message(message.key, true) MessagingService.flag_message(message.key, true)
.then(function(){ .then(function(){
...@@ -292,6 +304,7 @@ angular.module("ulakbus.messaging") ...@@ -292,6 +304,7 @@ angular.module("ulakbus.messaging")
message.actions = null; message.actions = null;
}); });
break; break;
case "_zops_unflag_message": case "_zops_unflag_message":
MessagingService.flag_message(message.key, false) MessagingService.flag_message(message.key, false)
.then(function(){ .then(function(){
...@@ -299,6 +312,7 @@ angular.module("ulakbus.messaging") ...@@ -299,6 +312,7 @@ angular.module("ulakbus.messaging")
message.actions = null; message.actions = null;
}); });
break; break;
case "_zops_delete_message": case "_zops_delete_message":
iScope.deleteConfirmation("Mesajı silmek istediğinize emin misiniz?") iScope.deleteConfirmation("Mesajı silmek istediğinize emin misiniz?")
.then(function(){ .then(function(){
...@@ -307,7 +321,31 @@ angular.module("ulakbus.messaging") ...@@ -307,7 +321,31 @@ angular.module("ulakbus.messaging")
}) })
}); });
break; break;
case "_zops_edit_message": case "_zops_edit_message":
// find message content container
var messageContainer = $("#msg-"+message.key);
MessagingPopup.show({
templateUrl: "components/messaging/templates/edit_message.html",
rootElement: messageContainer,
// activate inplace editor logic
inplaceEditor: true,
link: function (scope) {
scope.internalContent = scope.content;
scope.save = function(){
// delete message if new content is empty
if (!scope.internalContent){
return iScope.applyMessageAction(message, ['_', '_zops_delete_message']);
}
MessagingService.edit_message(message.key, scope.internalContent)
.then(function(){
// apply changes to element
scope.content = scope.internalContent;
scope.done();
});
};
}
});
break; break;
} }
}; };
...@@ -321,7 +359,11 @@ angular.module("ulakbus.messaging") ...@@ -321,7 +359,11 @@ angular.module("ulakbus.messaging")
// listen to new messages and add them to selected channel if any // listen to new messages and add them to selected channel if any
$rootScope.$on("message", function(e, message){ $rootScope.$on("message", function(e, message){
if (message.is_update){
updateMessage(message);
} else {
appendMessage(iScope.selectedChannel, MessagingService.prepareMessage(message)); appendMessage(iScope.selectedChannel, MessagingService.prepareMessage(message));
}
}); });
// notifications in messaging window are processed as ordinary messages // notifications in messaging window are processed as ordinary messages
$rootScope.$on("notifications", function(e, notification){ $rootScope.$on("notifications", function(e, notification){
...@@ -373,3 +415,58 @@ angular.module("ulakbus.messaging") ...@@ -373,3 +415,58 @@ angular.module("ulakbus.messaging")
} }
} }
}) })
.directive("contenteditable", function(){
return {
require: "?ngModel",
scope: {},
link: function(iScope, iElem, iAttrs, ngModel) {
if(!ngModel) return;
ngModel.$render = function() {
iElem.text(ngModel.$viewValue || '');
};
// Listen for change events to enable binding
iElem.on('blur keyup change', function() {
iScope.$evalAsync(read);
});
function read() {
var html = iElem.text();
ngModel.$setViewValue(html);
}
iScope.$on('$destroy', function(){
iElem.off('blur keyup change');
})
}
}
})
.directive('autoFocus', function($timeout){
function placeCaretAtEnd(el) {
el.focus();
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}
return {
link: function(iScope, iElem){
$timeout(function(){
placeCaretAtEnd(iElem[0]);
}, 500);
}
}
});
...@@ -71,6 +71,10 @@ angular.module('ulakbus.messaging', ['ui.bootstrap']) ...@@ -71,6 +71,10 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
if (!messagingAppIsHidden && message.channel_key == currentChannelKey){ if (!messagingAppIsHidden && message.channel_key == currentChannelKey){
return; return;
} }
// skip message updates
if (message.is_update) return;
checkIfInitialized().then(function(){ checkIfInitialized().then(function(){
var channel = channelsMap[message.channel_key]; var channel = channelsMap[message.channel_key];
if (channel){ if (channel){
...@@ -534,11 +538,12 @@ angular.module('ulakbus.messaging', ['ui.bootstrap']) ...@@ -534,11 +538,12 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
var resultDeferred = $q.defer(); var resultDeferred = $q.defer();
var scope = config.scope || $rootScope.$new(true); var scope = config.scope || $rootScope.$new(true);
var rootElement = config.rootElement; var rootElement = config.rootElement;
var element = $compile(template)(scope); var originalContent, element;
if (config.link){
config.link(scope);
}
if (config.inplaceEditor){
originalContent = rootElement.text();
scope.content = originalContent;
}
scope.done = function(result){ scope.done = function(result){
resultDeferred.resolve.apply(this, arguments); resultDeferred.resolve.apply(this, arguments);
}; };
...@@ -546,13 +551,25 @@ angular.module('ulakbus.messaging', ['ui.bootstrap']) ...@@ -546,13 +551,25 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
resultDeferred.reject.apply(this, arguments); resultDeferred.reject.apply(this, arguments);
}; };
if (config.link){
config.link(scope);
}
element = $compile(template)(scope);
rootElement.empty(); rootElement.empty();
rootElement.append(element); rootElement.append(element);
resultDeferred.promise._done = scope.done; resultDeferred.promise._done = scope.done;
resultDeferred.promise._cancel = scope.cancel; resultDeferred.promise._cancel = scope.cancel;
return resultDeferred.promise.finally(function(){ return resultDeferred.promise
.finally(function(){
// inplace editor can change scope.content and it will be applied to original rootElement
if (config.inplaceEditor){
rootElement.text(scope.content);
} else {
rootElement.empty(); rootElement.empty();
}
scope.$destroy(); scope.$destroy();
}); });
} }
...@@ -566,4 +583,4 @@ angular.module('ulakbus.messaging', ['ui.bootstrap']) ...@@ -566,4 +583,4 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
return compile(config.template, config); return compile(config.template, config);
}; };
}); })
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
<div class="message-time">{{::msg.moment|fromNow}}</div> <div class="message-time">{{::msg.moment|fromNow}}</div>
</div> </div>
<div class="message-content"> <div class="message-content">
{{::msg.content}} <div class="editable-message-content" id="msg-{{msg.key}}">{{msg.content}}</div>
<a class="message-content-url" href="{{::msg.url}}" ng-click="hideApp()" ng-if="msg.url">{{msg.url}}</a> <a class="message-content-url" href="{{::msg.url}}" ng-click="hideApp()" ng-if="msg.url">{{msg.url}}</a>
</div> </div>
</div> </div>
......
<div class="edit-text-message">
<div class="editor" contenteditable="" auto-focus on-enter-pressed="save()" on-esc-pressed="cancel()" ng-model="internalContent"></div>
<button class="btn btn-default" ng-click="cancel()">Cancel</button>
<button class="btn btn-success" ng-click="save()">Save Changes</button>
</div>
...@@ -684,6 +684,35 @@ angular.module('ulakbus') ...@@ -684,6 +684,35 @@ angular.module('ulakbus')
}); });
event.preventDefault(); event.preventDefault();
} }
});
scope.$on('$destroy', function(){
element.unbind('keydown keypress');
})
}
}
})
/**
* @memberof ulakbus
* @ngdoc directive
* @name onEscPressed
* @description Fire action when ESC pressed on element
*/
.directive("onEscPressed", function () {
return {
link: function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if(event.which === 27 ) {
scope.$apply(function (){
scope.$eval(attrs.onEscPressed);
});
event.preventDefault();
}
});
scope.$on('$destroy', function(){
element.unbind('keydown keypress');
}) })
} }
} }
......
...@@ -102,6 +102,7 @@ angular.module('ulakbus') ...@@ -102,6 +102,7 @@ angular.module('ulakbus')
if ($location.path() === "/login") { if ($location.path() === "/login") {
$log.debug("show errors on login form"); $log.debug("show errors on login form");
} else { } else {
alert("Want relogin!");
return window.location.reload(); return window.location.reload();
} }
}, },
......
...@@ -14,7 +14,7 @@ angular.module("ulakbus") ...@@ -14,7 +14,7 @@ angular.module("ulakbus")
// check if obj1 has properties values equal to corresponding properties in obj2 // check if obj1 has properties values equal to corresponding properties in obj2
function hasEqualProperties(obj1, obj2){ function hasEqualProperties(obj1, obj2){
var result = true var result = true;
for (var prop in obj2){ for (var prop in obj2){
if(obj2.hasOwnProperty(prop)){ if(obj2.hasOwnProperty(prop)){
result = result && obj2[prop] == obj1[prop]; result = result && obj2[prop] == obj1[prop];
...@@ -50,5 +50,18 @@ angular.module("ulakbus") ...@@ -50,5 +50,18 @@ angular.module("ulakbus")
return list[i]; return list[i];
} }
} }
};
/**
* @param list {Array} Array of objects to group
* @param condition {Object} conditions object. If object in collection has same values as in conditions object found object will be returned
* @returns {Object}|undefined
*/
this.findWhere = function(list, condition){
for (var i = 0; i < list.length; i++){
if (hasEqualProperties(list[i], condition)){
return list[i];
}
}
} }
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment