Commit 1d5f8f37 authored by Vladimir Baranov's avatar Vladimir Baranov

Merge branch 'feature/advanced-messaging' into develop

parents ce11ec8c f05f250a
......@@ -2087,7 +2087,7 @@ table.dataTable thead .sorting:after {
right: 15px;
-moz-box-shadow: 0px 0px 45px rgba(0,0,0,0.4);
box-shadow: 0px 0px 45px rgba(0,0,0,0.4);
z-index: 10;
z-index: 2100;
border-radius: 3px;
}
......@@ -2482,6 +2482,11 @@ table.dataTable thead .sorting:after {
font-family: 'robotomedium';
}
.chat-app .conversation-section .message-content-url {
display: block;
}
.chat-app .conversation-section .user-message .message-content .attachment-message {
color: #909090;
}
......@@ -2966,6 +2971,7 @@ table.dataTable thead .sorting:after {
.course-prg-scheduler .action-selector.readonly {
right: 0;
padding-right: 0;
cursor: default;
}
.course-prg-scheduler .action-selector.readonly:after {
......
......@@ -551,7 +551,8 @@ angular.module('ulakbus.crud', ['schemaForm', 'ui.bootstrap', 'ulakbus.formServi
key: data.oe_key,
name: data.name,
avatar_url: data.avatar_url,
totalHours: data.toplam_ders_saati
totalHours: data.toplam_ders_saati,
readonly: data.readonly
};
iScope.timetable = iScope.prepareTimetable(data.uygunluk_durumu);
};
......@@ -611,18 +612,19 @@ angular.module('ulakbus.crud', ['schemaForm', 'ui.bootstrap', 'ulakbus.formServi
iScope.currentTable = {
key: data.oe_key,
name: data.name,
avatar_url: data.avatar_url
avatar_url: data.avatar_url,
readonly: data.readonly
};
iScope.timetable = iScope.prepareTimetable(data.zaman_plani);
};
iScope.selectTable = function(lecturer){
iScope.selectTable = function(table){
iScope.loadingTable = true;
iScope.get_wf({
cmd: 'personel_sec',
secili_og_elemani: {key: lecturer.key}
cmd: 'derslik_degistir',
secili_derslik: {key: table.key}
}).then(function(response){
initLecturer(response);
initTable(response);
}).finally(function(){
iScope.loadingTable = false;
})
......
This diff is collapsed.
angular.module("ulakbus.messaging")
.directive('messaging', function (Generator, MessagingService, $log, $rootScope, MessagingPopup, Utils) {
.directive('messaging', function (Generator, MessagingService, $log, $rootScope, MessagingPopup, Utils, $q) {
// get channel key
function getKey (channel) {
......@@ -32,11 +32,24 @@ angular.module("ulakbus.messaging")
link: function(iScope, iElem, iAttrs){
iScope.chatAppIsHidden = true;
// reset state when user log in/log out
$rootScope.$watch('loggedInUser', function(v){
iScope.loggedIn = v;
reset();
});
// shared object to populate models through scopes
iScope.shared = {};
var popupRootElement = $(iElem).find('.popup-placeholder');
function reset(){
iScope.selectedChannel = null;
iScope.publicChannels = [];
iScope.notificationsChannel = [];
iScope.directChannels = [];
}
function editChannelPopup(channel){
return MessagingPopup.show({
templateUrl: "components/messaging/templates/create_channel.html",
......@@ -66,8 +79,9 @@ angular.module("ulakbus.messaging")
if (channel.messages){
channel.messages.push(message);
}
}
};
updateLastMessage(message);
reportLastSeenMessage();
}
function updateAndSelect(channelKey){
......@@ -103,10 +117,12 @@ angular.module("ulakbus.messaging")
};
iScope.updateChannelsList = function(){
return MessagingService.list_channels().then(function (groupedChannels) {
return MessagingService.list_channels().then(function (channels) {
var groupedChannels = channels.grouped;
iScope.publicChannels = groupedChannels[MessagingService.CHANNEL_TYPE.PUBLIC];
iScope.notificationsChannel = groupedChannels[MessagingService.CHANNEL_TYPE.NOTIFICATION][0];
iScope.directChannels = groupedChannels[MessagingService.CHANNEL_TYPE.DIRECT];
});
}
......@@ -123,11 +139,13 @@ angular.module("ulakbus.messaging")
iScope.hideApp = function(){
iScope.chatAppIsHidden = true;
MessagingService.toggle_messaging_window_visibility(false);
};
iScope.showApp = function(){
iScope.chatAppIsHidden = false;
iScope.updateChannelsList();
MessagingService.toggle_messaging_window_visibility(true);
return iScope.updateChannelsList();
}
iScope.searchUser = function(){
......@@ -221,9 +239,8 @@ angular.module("ulakbus.messaging")
function selectChannel(channelKey, silent){
if (!silent) iScope.loadingChannel = true;
return MessagingService.show_channel(channelKey).then(function(result){
return result;
}).finally(function(){
return MessagingService.show_channel(channelKey)
.finally(function(){
iScope.loadingChannel = false;
})
}
......@@ -308,12 +325,21 @@ angular.module("ulakbus.messaging")
$rootScope.$on("user_ready", function(){
// init service after user logged in
iScope.selectedChannel = null;
iScope.publicChannels = [];
iScope.notificationsChannel = [];
iScope.directChannels = []
reset();
iScope.hideApp();
});
$rootScope.$on(MessagingService.SHOW_MESSAGING_WINDOW_EVENT, function(e, channelKey){
var showApp = $q.when();
if (iScope.chatAppIsHidden){
showApp = iScope.showApp();
}
if (channelKey && channelKey != getKey(iScope.selectedChannel)){
showApp.then(function(){
iScope.selectChannel(channelKey);
})
}
})
}
};
})
......
......@@ -18,6 +18,9 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
.factory('MessagingService', function ($q, $timeout, $compile, $log, $rootScope, Moment, WSOps, Utils) {
var msg = {};
var notificationsChannelKey;
var channelsMap = {};
// channels loader promise
var channelsLoader;
msg.CHANNEL_TYPE = {
"PUBLIC": 15,
......@@ -25,6 +28,16 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
"NOTIFICATION": 5
};
msg.SHOW_MESSAGING_WINDOW_EVENT = "show_messaging_window";
var unread = {
messages: {count: 0},
notifications: {count: 0}
};
var currentChannelKey;
// track messaging app state for proper unread messages count
var messagingAppIsHidden = true;
function wsReady () {
/**
* wait until websocket will be open
......@@ -52,6 +65,44 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
}
}
function increaseUnread(message, messageType){
// skip current channel messages. Don't update counters
if (!messagingAppIsHidden && message.channel_key == currentChannelKey){
return;
}
checkIfInitialized().then(function(){
var channel = channelsMap[message.channel_key];
if (channel){
channel.unread += 1;
}
unread[messageType].count += 1;
})
}
function decreaseUnread(channel){
// get channel from channelsMap. Channels in channelMap has unread property
// which is updated when messages arrive
channel = channelsMap[channel.key];
if (channel && channel.unread){
var counter;
if (channel.type == msg.CHANNEL_TYPE.NOTIFICATION){
counter = unread.notifications
} else {
counter = unread.messages;
}
counter.count -= channel.unread;
if (counter.count < 0) counter.count = 0;
channel.unread = 0;
}
}
function checkIfInitialized(){
if (!channelsLoader){
return msg.list_channels()
}
return channelsLoader;
}
// prepare message to show in UI
msg.prepareMessage = function(message){
if (!message.timestamp){
......@@ -64,9 +115,35 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
};
msg.get_notifications_channel_key = function(){
return checkIfInitialized().then(function(){
return notificationsChannelKey;
});
};
msg.get_unread_counters = function(){
return unread;
};
msg.reset_state = function(){
currentChannelKey = null;
notificationsChannelKey = null;
channelsMap = {};
unread.messages.count = 0;
unread.notifications.count = 0;
channelsLoader = false;
}
msg.toggle_messaging_window_visibility = function(visibility, resetState){
messagingAppIsHidden = !visibility;
if (resetState){
msg.reset_state();
}
};
msg.show_messaging_window = function(channelKey){
$rootScope.$broadcast(msg.SHOW_MESSAGING_WINDOW_EVENT, channelKey);
}
/**
* API
*
......@@ -100,13 +177,21 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
var outgoing = {
view: '_zops_list_channels'
};
return wsRequest(outgoing).then(function (data) {
console.error("channels: ", data.channels);
channelsLoader = wsRequest(outgoing).then(function (data) {
var grouped = Utils.groupBy(data.channels||[], "type");
// 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;
return grouped;
return {grouped: grouped, channelsMap: channelsMap};
});
return channelsLoader;
};
msg.search_user = function (query) {
......@@ -226,6 +311,10 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
};
return wsRequest(outgoing).then(function(result){
$log.info("Show channel ", channelKey, ": ", result);
// decrease unread messages for current channel
decreaseUnread(result);
// save current channel key
currentChannelKey = result.key;
prepareMessages(result.last_messages);
return result;
})
......@@ -249,6 +338,9 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
};
return wsRequest(outgoing).then(function(result){
$log.info("Get unread messages count: ", result);
// update internal unread messages counters
unread.messages.count = result.messages;
unread.notifications.count = result.notifications;
return result;
})
};
......@@ -379,6 +471,25 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
});
};
/**
* Event listeners
*/
$rootScope.$on("message", function(e, message){
increaseUnread(message, 'messages');
});
$rootScope.$on("notifications", function(e, message){
increaseUnread(message, 'notifications');
});
// reset state on logout
$rootScope.$watch("loggedInUser", function(value){
if (!value){
msg.reset_state();
};
});
return msg;
})
......
......@@ -40,7 +40,6 @@
<div class="conversation-block clearfix" ng-repeat="msg in selectedChannel.messages">
<div class="conversation-actions">
<div class="action"><span class="glyphicon glyphicon-star-empty"></span></div>
<div class="action dropdown-toggle" data-toggle="dropdown" ng-click="getMessageActions(msg)">
<span class="glyphicon glyphicon-option-horizontal"></span>
</div>
......@@ -59,6 +58,7 @@
</div>
<div class="message-content">
{{::msg.content}}
<a class="message-content-url" href="{{::msg.url}}" ng-if="msg.url">{{msg.url}}</a>
</div>
</div>
</div>
......
<div>
<div ng-show="loggedIn">
<a class="chat-app-button" ng-show="chatAppIsHidden" ng-click="showApp()"><i class="glyphicon glyphicon-comment"></i></a>
<div class="chat-app" ng-hide="chatAppIsHidden">
......@@ -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="{'notification': ch.unread, 'active': isChannelSelected(ch)}" title="{{ch.description}}" ng-repeat="ch in publicChannels" ng-click="selectChannel(ch)">{{ch.name}}</li>
<li ng-class="{'unread': ch.unread, 'active': isChannelSelected(ch)}" title="{{ch.description}}" ng-repeat="ch in publicChannels" ng-click="selectChannel(ch)">{{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="{'notification': 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)">{{userChannel.name}}</li>
</ul>
</div>
......
......@@ -42,18 +42,19 @@ angular.module('ulakbus')
replace: true,
scope: {},
controller: function ($scope, $log) {
$scope.count = {
messages: 0,
notifications: 0
};
function initCounters(){
MessagingService.get_unread_messages_count()
.then(function(result){
$scope.count.messages = result.messages;
$scope.count.notifiations = result.notifications;
$scope.count = MessagingService.get_unread_counters();
// initialize counters
MessagingService.get_unread_messages_count();
$scope.showMessagesWindow = function(type){
if (type == 'notifications'){
return MessagingService.get_notifications_channel_key()
.then(function(channelKey){
return MessagingService.show_messaging_window(channelKey);
})
}
initCounters();
MessagingService.show_messaging_window();
}
}
};
})
......
......@@ -31,8 +31,8 @@
&lt;!&ndash; /.dropdown-messages &ndash;&gt;
</li>-->
<li uib-dropdown auto-close="outsideClick">
<a uib-dropdown-toggle>
<div class="badge" ng-show="count.messages > 0">{{count.messages}}</div>
<a uib-dropdown-toggle ng-click="showMessagesWindow('messages')">
<div class="badge" ng-show="count.messages.count > 0">{{count.messages.count}}</div>
<i class="fa fa-envelope fa-fw" tooltip-placement="bottom" uib-tooltip="Mesajlar"></i>
<!--<i class="fa fa-caret-down"></i>-->
</a>
......@@ -99,8 +99,8 @@
</li>
<!-- /.dropdown -->
<li uib-dropdown auto-close="outsideClick">
<a uib-dropdown-toggle>
<div class="badge" ng-if="count.notifications > 0">{{count.notifications}}</div>
<a uib-dropdown-toggle ng-click="showMessagesWindow('notifications')">
<div class="badge" ng-if="count.notifications.count > 0">{{count.notifications.count}}</div>
<i class="fa fa-bell fa-fw" tooltip-placement="bottom" uib-tooltip="Duyurular"></i>
<!--<i class="fa fa-caret-down"></i>-->
</a>
......
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