From a4975cab339711a4436cd539b501d59928a656b9 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 19 Jul 2014 10:33:27 -0400 Subject: [PATCH] closes #1825, closes #1674 --- public/src/forum/chats.js | 19 +++++++++++++- public/src/forum/footer.js | 23 ++++++++++++----- public/src/modules/chat.js | 51 ++++++++++++++++++++++---------------- src/messaging.js | 36 +++++++++++++++++++++------ src/socket.io/modules.js | 21 ++++++++++++++++ src/socket.io/user.js | 5 ++++ 6 files changed, 120 insertions(+), 35 deletions(-) diff --git a/public/src/forum/chats.js b/public/src/forum/chats.js index d4374d4fb3..92086a8b6d 100644 --- a/public/src/forum/chats.js +++ b/public/src/forum/chats.js @@ -7,6 +7,8 @@ define('forum/chats', ['string', 'sounds'], function(S, sounds) { initialised: false }; + var newMessage = false; + Chats.init = function() { var containerEl = $('.expanded-chat ul'); @@ -75,6 +77,15 @@ define('forum/chats', ['string', 'sounds'], function(S, sounds) { Chats.addGlobalEventListeners = function() { $(window).on('resize', Chats.resizeMainWindow); + $(window).on('mousemove keypress click', function() { + if (newMessage) { + var recipientUid = Chats.getRecipientUid(); + if (recipientUid) { + socket.emit('modules.chats.markRead', recipientUid); + newMessage = false; + } + } + }); }; Chats.addSocketListeners = function() { @@ -83,6 +94,8 @@ define('forum/chats', ['string', 'sounds'], function(S, sounds) { containerEl = $('.expanded-chat ul'); if (Chats.isCurrentChat(data.withUid)) { + newMessage = data.message.self === 0; + Chats.parseMessage(data.message, function(html) { var newMessage = $(html); newMessage.insertBefore(typingNotifEl); @@ -163,8 +176,12 @@ define('forum/chats', ['string', 'sounds'], function(S, sounds) { }; Chats.setActive = function() { + var recipientUid = Chats.getRecipientUid(); + if (recipientUid) { + socket.emit('modules.chats.markRead', recipientUid); + } $('.chats-list li').removeClass('bg-primary'); - $('.chats-list li[data-uid="' + Chats.getRecipientUid() + '"]').addClass('bg-primary'); + $('.chats-list li[data-uid="' + recipientUid + '"]').addClass('bg-primary'); }; Chats.parseMessage = function(data, callback) { diff --git a/public/src/forum/footer.js b/public/src/forum/footer.js index c8582a1b8c..e7e8209a1b 100644 --- a/public/src/forum/footer.js +++ b/public/src/forum/footer.js @@ -4,19 +4,30 @@ define('forum/footer', ['notifications', 'chat'], function(Notifications, Chat) Chat.prepareDOM(); translator.prepareDOM(); - function updateUnreadCount(err, count) { - var unreadEl = $('#unread-count'); + function updateUnreadTopicCount(err, count) { + if (err) { + return console.warn('Error updating unread count', err); + } + $('#unread-count') + .toggleClass('unread-count', count > 0) + .attr('data-content', count > 20 ? '20+' : count); + } + + function updateUnreadChatCount(err, count) { if (err) { - console.warn('Error updating unread count', err); + return console.warn('Error updating unread count', err); } - unreadEl + $('#chat-count') .toggleClass('unread-count', count > 0) .attr('data-content', count > 20 ? '20+' : count); } - socket.on('event:unread.updateCount', updateUnreadCount); - socket.emit('user.getUnreadCount', updateUnreadCount); + socket.on('event:unread.updateCount', updateUnreadTopicCount); + socket.emit('user.getUnreadCount', updateUnreadTopicCount); + + socket.on('event:unread.updateChatCount', updateUnreadChatCount); + socket.emit('user.getUnreadChatCount', updateUnreadChatCount); }); diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js index 9895b5fb5f..cce8a14c0d 100644 --- a/public/src/modules/chat.js +++ b/public/src/modules/chat.js @@ -4,6 +4,7 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, S, sounds, Chats) { var module = {}; + var newMessage = false; module.prepareDOM = function() { // Chats Dropdown @@ -66,7 +67,7 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, if (isSelf) { username = data.message.toUser.username; } - + newMessage = data.message.self === 0; if (module.modalExists(data.withUid)) { var modal = module.getModal(data.withUid); module.appendChatMessage(modal, data.message); @@ -135,7 +136,7 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, }; function checkStatus(chatModal) { - socket.emit('user.isOnline', chatModal.touid, function(err, data) { + socket.emit('user.isOnline', chatModal.attr('touid'), function(err, data) { translator.translate('[[global:' + data.status + ']]', function(translated) { $('#chat-user-status').attr('class', 'fa fa-circle status ' + data.status) .attr('title', translated) @@ -145,10 +146,10 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, } function checkOnlineStatus(chatModal) { - if(chatModal.intervalId === 0) { - chatModal.intervalId = setInterval(function() { + if(parseInt(chatModal.attr('intervalId'), 10) === 0) { + chatModal.attr('intervalId', setInterval(function() { checkStatus(chatModal); - }, 1000); + }, 1000)); } } @@ -160,11 +161,9 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, var chatModal = $(chatTpl), uuid = utils.generateUUID(); - chatModal.intervalId = 0; - chatModal.touid = touid; - chatModal.username = username; - chatModal.attr('id', 'chat-modal-' + touid); + chatModal.attr('touid', touid); + chatModal.attr('intervalId', 0); chatModal.attr('UUID', uuid); chatModal.css("position", "fixed"); chatModal.appendTo($('body')); @@ -211,6 +210,13 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, module.bringModalToTop(chatModal); }); + chatModal.on('mousemove keypress click', function() { + if (newMessage) { + socket.emit('modules.chats.markRead', touid); + console.log('sent') + newMessage = false; + } + }); addSendHandler(chatModal); @@ -234,12 +240,12 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, }; module.close = function(chatModal) { - clearInterval(chatModal.intervalId); - chatModal.intervalId = 0; + clearInterval(chatModal.attr('intervalId')); + chatModal.attr('intervalId', 0); chatModal.remove(); chatModal.data('modal', null); taskbar.discard('chat', chatModal.attr('UUID')); - Chats.notifyTyping(chatModal.touid, false); + Chats.notifyTyping(chatModal.attr('touid'), false); }; module.center = function(chatModal) { @@ -258,19 +264,20 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, Chats.scrollToBottom(chatModal.find('#chat-content')); module.center(chatModal); module.bringModalToTop(chatModal); + socket.emit('modules.chats.markRead', chatModal.attr('touid')); }; module.minimize = function(uuid) { var chatModal = $('div[UUID="' + uuid + '"]'); chatModal.addClass('hide'); taskbar.minimize('chat', uuid); - clearInterval(chatModal.intervalId); - chatModal.intervalId = 0; - Chats.notifyTyping(chatModal.touid, false); + clearInterval(chatModal.attr('intervalId')); + chatModal.attr('intervalId', 0); + Chats.notifyTyping(chatModal.attr('touid'), false); }; function getChatMessages(chatModal, callback) { - socket.emit('modules.chats.get', {touid:chatModal.touid}, function(err, messages) { + socket.emit('modules.chats.get', {touid: chatModal.attr('touid')}, function(err, messages) { module.appendChatMessage(chatModal, messages, callback); }); } @@ -279,20 +286,20 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, var input = chatModal.find('#chat-message-input'); input.off('keypress').on('keypress', function(e) { if(e.which === 13) { - Chats.sendMessage(chatModal.touid, chatModal.find('#chat-message-input')); + Chats.sendMessage(chatModal.attr('touid'), chatModal.find('#chat-message-input')); } }); input.off('keyup').on('keyup', function() { if ($(this).val()) { - socket.emit('modules.chats.userStartTyping', {touid:chatModal.touid, fromUid: app.uid}); + socket.emit('modules.chats.userStartTyping', {touid:chatModal.attr('touid'), fromUid: app.uid}); } else { - Chats.notifyTyping(chatModal.touid, false); + Chats.notifyTyping(chatModal.attr('touid'), false); } }); chatModal.find('#chat-message-send-btn').off('click').on('click', function(e){ - Chats.sendMessage(chatModal.touid, chatModal.find('#chat-message-input')); + Chats.sendMessage(chatModal.attr('touid'), chatModal.find('#chat-message-input')); return false; }); } @@ -308,7 +315,9 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, message.insertBefore(typingNotif); Chats.scrollToBottom(chatContent); - if (typeof done === 'function') done(); + if (typeof done === 'function') { + done(); + } }); }; diff --git a/src/messaging.js b/src/messaging.js index a8e2447eac..c7577b1a43 100644 --- a/src/messaging.js +++ b/src/messaging.js @@ -43,8 +43,21 @@ var db = require('./database'), Messaging.updateChatTime(fromuid, touid); Messaging.updateChatTime(touid, fromuid); - getMessages([mid], fromuid, touid, true, function(err, messages) { - callback(err, messages ? messages[0] : null); + async.parallel([ + function(next) { + Messaging.markRead(fromuid, touid, next); + }, + function(next) { + Messaging.markUnread(touid, fromuid, next); + } + ], function(err, results) { + if (err) { + return callback(err); + } + + getMessages([mid], fromuid, touid, true, function(err, messages) { + callback(err, messages ? messages[0] : null); + }); }); }); }); @@ -122,11 +135,8 @@ var db = require('./database'), }; Messaging.updateChatTime = function(uid, toUid, callback) { - db.sortedSetAdd('uid:' + uid + ':chats', Date.now(), toUid, function(err) { - if (callback) { - callback(err); - } - }); + callback = callback || function() {}; + db.sortedSetAdd('uid:' + uid + ':chats', Date.now(), toUid, callback); }; Messaging.getRecentChats = function(uid, start, end, callback) { @@ -157,6 +167,18 @@ var db = require('./database'), }); }; + Messaging.getUnreadCount = function(uid, callback) { + db.sortedSetCard('uid:' + uid + ':chats:unread', callback); + }; + + Messaging.markRead = function(uid, toUid, callback) { + db.sortedSetRemove('uid:' + uid + ':chats:unread', toUid, callback); + }; + + Messaging.markUnread = function(uid, toUid, callback) { + db.sortedSetAdd('uid:' + uid + ':chats:unread', Date.now(), toUid, callback); + }; + // todo #1798 -- this utility method creates a room name given an array of uids. Messaging.uidsToRoom = function(uids, callback) { uid = parseInt(uid, 10); diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js index 31b0926b73..14c05f796e 100644 --- a/src/socket.io/modules.js +++ b/src/socket.io/modules.js @@ -189,6 +189,7 @@ SocketModules.chats.send = function(socket, data, callback) { recipMessage.self = 0; // Recipient + SocketModules.chats.pushUnreadCount(touid); server.getUserSockets(touid).forEach(function(s) { s.emit('event:chats.receive', { withUid: socket.uid, @@ -197,6 +198,7 @@ SocketModules.chats.send = function(socket, data, callback) { }); // Sender + SocketModules.chats.pushUnreadCount(socket.uid); server.getUserSockets(socket.uid).forEach(function(s) { s.emit('event:chats.receive', { withUid: touid, @@ -221,6 +223,25 @@ function sendChatNotification(fromuid, touid, messageObj) { } } +SocketModules.chats.pushUnreadCount = function(uid) { + Messaging.getUnreadCount(uid, function(err, unreadCount) { + if (err) { + return; + } + server.getUserSockets(uid).forEach(function(s) { + s.emit('event:unread.updateChatCount', null, unreadCount); + }); + }); +}; + +SocketModules.chats.markRead = function(socket, touid, callback) { + Messaging.markRead(socket.uid, touid, function(err) { + if (!err) { + SocketModules.chats.pushUnreadCount(socket.uid); + } + }); +}; + SocketModules.chats.userStartTyping = function(socket, data, callback) { sendTypingNotification('event:chats.userStartTyping', socket, data, callback); }; diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 58ebcc0ca7..55236a22b7 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -4,6 +4,7 @@ var async = require('async'), user = require('../user'), groups = require('../groups'), topics = require('../topics'), + messaging = require('../messaging'), utils = require('./../../public/src/utils'), meta = require('../meta'), SocketUser = {}; @@ -216,6 +217,10 @@ SocketUser.getUnreadCount = function(socket, data, callback) { topics.getTotalUnread(socket.uid, callback); }; +SocketUser.getUnreadChatCount = function(socket, data, callback) { + messaging.getUnreadCount(socket.uid, callback); +}; + SocketUser.getActiveUsers = function(socket, data, callback) { module.parent.exports.emitOnlineUserCount(callback); };