Commit 2d8da571 authored by Vladimir Baranov's avatar Vladimir Baranov

Merge branch 'feature/messaging-improvements' into develop

parents 45019b81 03773d10
......@@ -2480,6 +2480,7 @@ table.dataTable thead .sorting:after {
.chat-app .conversation-section .user-message .message-content {
font-family: 'robotomedium';
position: relative;
}
.chat-app .conversation-section .message-content-url {
......@@ -2576,14 +2577,14 @@ table.dataTable thead .sorting:after {
opacity:1;
}
.chat-app .conversation-section .user-message .edit-text-message input {
.chat-app .conversation-section .user-message .edit-text-message .editor {
width: 100%;
margin-bottom: 7px;
margin-top: 7px;
height: 30px;
border-radius: 3px;
border: 1px solid #ccc;
padding-left: 7px;
padding: 5px 10px;
outline: none;
}
......
This diff is collapsed.
......@@ -19,6 +19,7 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
var msg = {};
var notificationsChannelKey;
var channelsMap = {};
var groupedChannels = {};
// channels loader promise
var channelsLoader;
......@@ -70,6 +71,10 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
if (!messagingAppIsHidden && message.channel_key == currentChannelKey){
return;
}
// skip message updates
if (message.is_update) return;
checkIfInitialized().then(function(){
var channel = channelsMap[message.channel_key];
if (channel){
......@@ -128,6 +133,7 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
currentChannelKey = null;
notificationsChannelKey = null;
channelsMap = {};
groupedChannels = {};
unread.messages.count = 0;
unread.notifications.count = 0;
channelsLoader = false;
......@@ -179,16 +185,22 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
};
channelsLoader = wsRequest(outgoing).then(function (data) {
var grouped = Utils.groupBy(data.channels||[], "type");
var initialGroups = {};
initialGroups[msg.CHANNEL_TYPE.PUBLIC] = [];
initialGroups[msg.CHANNEL_TYPE.DIRECT] = [];
initialGroups[msg.CHANNEL_TYPE.NOTIFICATION] = [];
groupedChannels = Utils.groupBy(data.channels||[], "type", initialGroups);
// add all channels to channels map
for (var i = 0; i < data.channels.length; i++){
var channel = data.channels[i];
channelsMap[channel.key] = channel;
}
// save notifications channel key
notificationsChannelKey = grouped[msg.CHANNEL_TYPE.NOTIFICATION][0].key;
notificationsChannelKey = groupedChannels[msg.CHANNEL_TYPE.NOTIFICATION][0].key;
return {grouped: grouped, channelsMap: channelsMap};
return {grouped: groupedChannels, channelsMap: channelsMap};
});
return channelsLoader;
......@@ -275,6 +287,9 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
};
return wsRequest(outgoing).then(function(result){
$log.info("Channel ", channelKey, " deleted: ", result);
if (channelsMap[channelKey]){
channelsMap[channelKey].deleted = true;
}
return result;
})
};
......@@ -328,6 +343,7 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
};
return wsRequest(outgoing).then(function(result){
$log.info("Load channel ", channelKey, "history: ", result);
prepareMessages(result.messages);
return result;
})
};
......@@ -483,6 +499,25 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
increaseUnread(message, 'notifications');
});
$rootScope.$on("channel_change", function(e, action, channel){
checkIfInitialized().then(function(){
if (action == 'add'){
var group = groupedChannels[channel.type];
if (!channelsMap[channel.key]){
channelsMap[channel.key] = channel;
}
return group.push(channel);
}
if (action == 'status'){
var localChannel = channelsMap[channel.channel_key];
if (localChannel){
localChannel.is_online = channel.is_online;
}
}
})
});
// reset state on logout
$rootScope.$watch("loggedInUser", function(value){
if (!value){
......@@ -490,6 +525,11 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
};
});
// initialize unread messages counter when user logged in
$rootScope.$on("user_ready", function(){
msg.get_unread_messages_count();
});
return msg;
})
......@@ -499,11 +539,12 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
var resultDeferred = $q.defer();
var scope = config.scope || $rootScope.$new(true);
var rootElement = config.rootElement;
var element = $compile(template)(scope);
if (config.link){
config.link(scope);
}
var originalContent, element;
if (config.inplaceEditor){
originalContent = rootElement.text();
scope.content = originalContent;
}
scope.done = function(result){
resultDeferred.resolve.apply(this, arguments);
};
......@@ -511,14 +552,26 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
resultDeferred.reject.apply(this, arguments);
};
if (config.link){
config.link(scope);
}
element = $compile(template)(scope);
rootElement.empty();
rootElement.append(element);
resultDeferred.promise._done = scope.done;
resultDeferred.promise._cancel = scope.cancel;
return resultDeferred.promise.finally(function(){
rootElement.empty();
scope.$destroy();
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();
}
scope.$destroy();
});
}
......@@ -531,4 +584,4 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
return compile(config.template, config);
};
});
})
......@@ -31,10 +31,10 @@
</div>
</div>
<div class="conversation-body" ng-class="{readonly: selectedChannel.read_only}" scroll-down-when-update="lastMessage">
<div class="conversation-body" ng-class="{readonly: selectedChannel.read_only}" scroll-down-when-update="{{lastMessage}}" load-more-top="loadMore()">
<div class="conversation-body-inner">
<div class="beginning-of-conversation">
<div class="beginning-of-conversation" ng-show="allMessagesLoaded">
Burası yazışmanın başı!
</div>
......@@ -49,7 +49,7 @@
</div>
<div class="user-photo">
<img ng-src="{{msg.avatar_url}}" ng-show="msg.avatar_url">
<img ng-src="{{::msg.avatar_url}}" ng-if="msg.avatar_url">
</div>
<div class="user-message">
<div class="message-header clearfix">
......@@ -57,8 +57,8 @@
<div class="message-time">{{::msg.moment|fromNow}}</div>
</div>
<div class="message-content">
{{::msg.content}}
<a class="message-content-url" href="{{::msg.url}}" ng-if="msg.url">{{msg.url}}</a>
<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>
</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>
......@@ -11,12 +11,12 @@
<ul class="channels">
<li class="title">KANALLAR <span class="add-action glyphicon glyphicon-plus-sign" ng-click="createChannel()"></span></li>
<li ng-class="{'unread': ch.unread, 'public-ro-channel': ch.read_only, 'active': isChannelSelected(ch)}" title="{{ch.description}}" ng-repeat="ch in publicChannels" ng-click="selectChannel(ch)">{{ch.name}}</li>
<li ng-class="{'unread': ch.unread, 'public-ro-channel': ch.read_only, 'active': isChannelSelected(ch)}" title="{{ch.description}}" ng-repeat="ch in publicChannels" ng-click="selectChannel(ch)" ng-hide="ch.deleted">{{ch.name}}</li>
</ul>
<ul class="direct-messages">
<li class="title">MESAJLAR <span class="add-action glyphicon glyphicon-plus-sign" ng-click="searchUser()"></span></li>
<li ng-class="{'unread': userChannel.unread, 'active': isChannelSelected(userChannel), 'online': userChannel.is_online}" ng-repeat="userChannel in directChannels" ng-click="selectChannel(userChannel)">{{userChannel.name}}</li>
<li ng-class="{'unread': userChannel.unread, 'active': isChannelSelected(userChannel), 'online': userChannel.is_online}" ng-repeat="userChannel in directChannels" ng-click="selectChannel(userChannel)" ng-hide="userChannel.deleted">{{userChannel.name}}</li>
</ul>
</div>
......
......@@ -43,8 +43,6 @@ angular.module('ulakbus')
scope: {},
controller: function ($scope, $log) {
$scope.count = MessagingService.get_unread_counters();
// initialize counters
MessagingService.get_unread_messages_count();
$scope.showMessagesWindow = function(type){
if (type == 'notifications'){
......@@ -686,6 +684,35 @@ angular.module('ulakbus')
});
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')
if ($location.path() === "/login") {
$log.debug("show errors on login form");
} else {
alert("Want relogin!");
return window.location.reload();
}
},
......@@ -129,4 +130,4 @@ angular.module('ulakbus')
};
return error_service;
});
\ No newline at end of file
});
......@@ -162,6 +162,16 @@ angular.module('ulakbus')
task_list: function () {
// broadcast task list to task_list directive in dashboard_widget_directives.js
$rootScope.$broadcast('task_list', msg_data["task_list"]);
},
channel_subscription: function(){
$timeout(function(){
$rootScope.$broadcast('channel_change', 'add', msg_data);
})
},
user_status: function(){
$timeout(function(){
$rootScope.$broadcast('channel_change', 'status', msg_data);
})
}
};
// do_action is the dispatcher function for incoming events
......
......@@ -14,7 +14,7 @@ angular.module("ulakbus")
// check if obj1 has properties values equal to corresponding properties in obj2
function hasEqualProperties(obj1, obj2){
var result = true
var result = true;
for (var prop in obj2){
if(obj2.hasOwnProperty(prop)){
result = result && obj2[prop] == obj1[prop];
......@@ -26,14 +26,16 @@ angular.module("ulakbus")
/**
* @param list {Array} Array of objects to group
* @param propName {String} property name to group array by
* @param initialObject {Object} initial object for groups setup
* @returns {Object}
*/
this.groupBy = function (list, propName) {
this.groupBy = function (list, propName, initialObject) {
if (!initialObject) initialObject = {};
return list.reduce(function(acc, item) {
(acc[item[propName]] = acc[item[propName]] || []).push(item);
return acc;
}, {});
}, initialObject);
};
/**
......@@ -48,5 +50,18 @@ angular.module("ulakbus")
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