You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
4.8 KiB
JavaScript

'use strict';
/* globals define, app, ajaxify, utils, socket, templates */
define('forum/chats', ['string', 'sounds'], function(S, sounds) {
var Chats = {
initialised: false
};
var newMessage = false;
Chats.init = function() {
var containerEl = $('.expanded-chat ul');
if (!Chats.initialised) {
Chats.addSocketListeners();
Chats.addGlobalEventListeners();
}
Chats.addEventListeners();
Chats.resizeMainWindow();
Chats.scrollToBottom(containerEl);
Chats.setActive();
Chats.initialised = true;
};
Chats.getRecipientUid = function() {
return parseInt($('.expanded-chat').attr('data-uid'), 10);
};
Chats.isCurrentChat = function(uid) {
return Chats.getRecipientUid() === parseInt(uid, 10);
};
Chats.addEventListeners = function() {
var inputEl = $('.chat-input'),
sendEl = $('.expanded-chat button[data-action="send"]'),
popoutEl = $('[data-action="pop-out"]');
$('.chats-list').on('click', 'li', function(e) {
ajaxify.go('chats/' + utils.slugify($(this).attr('data-username')));
});
inputEl.on('keypress', function(e) {
if(e.which === 13) {
Chats.sendMessage(Chats.getRecipientUid(), inputEl);
}
});
inputEl.on('keyup', function() {
if ($(this).val()) {
Chats.notifyTyping(Chats.getRecipientUid(), true);
} else {
Chats.notifyTyping(Chats.getRecipientUid(), false);
}
});
sendEl.on('click', function(e) {
Chats.sendMessage(Chats.getRecipientUid(), inputEl);
return false;
});
popoutEl.on('click', function() {
var username = $('.expanded-chat').attr('data-username'),
uid = Chats.getRecipientUid();
ajaxify.go('chats', function() {
app.openChat(username, uid);
}, true);
});
};
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() {
socket.on('event:chats.receive', function(data) {
var typingNotifEl = $('.user-typing'),
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);
newMessage.find('span.timeago').timeago();
newMessage.find('img:not(".chat-user-image")').addClass('img-responsive');
Chats.scrollToBottom(containerEl);
});
} else {
$('.chats-list li[data-uid="' + data.withUid + '"]').addClass('unread');
app.alternatingTitle('[[modules:chat.user_has_messaged_you, ' + data.message.fromUser.username + ']]');
}
});
socket.on('event:chats.userStartTyping', function(withUid) {
var typingNotifEl = $('.user-typing');
if (Chats.isCurrentChat(withUid)) {
typingNotifEl.removeClass('hide');
}
$('.chats-list li[data-uid="' + withUid + '"]').addClass('typing');
});
socket.on('event:chats.userStopTyping', function(withUid) {
var typingNotifEl = $('.user-typing');
if (Chats.isCurrentChat(withUid)) {
typingNotifEl.addClass('hide');
}
$('.chats-list li[data-uid="' + withUid + '"]').removeClass('typing');
});
};
Chats.resizeMainWindow = function() {
var messagesList = $('.expanded-chat ul');
if (messagesList.length) {
var margin = $('.expanded-chat ul').outerHeight(true) - $('.expanded-chat ul').height(),
inputHeight = $('.chat-input').outerHeight(true),
fromTop = messagesList.offset().top;
messagesList.height($(window).height() - (fromTop + inputHeight + (margin * 4)));
}
};
Chats.notifyTyping = function(toUid, typing) {
socket.emit('modules.chats.user' + (typing ? 'Start' : 'Stop') + 'Typing', {
touid: toUid,
fromUid: app.uid
});
};
Chats.sendMessage = function(toUid, inputEl) {
var msg = S(inputEl.val()).stripTags().s;
if (msg.length) {
msg = msg +'\n';
socket.emit('modules.chats.send', {
touid:toUid,
message:msg
});
inputEl.val('');
sounds.play('chat-outgoing');
Chats.notifyTyping(toUid, false);
}
};
Chats.scrollToBottom = function(containerEl) {
if (containerEl.length) {
containerEl.scrollTop(
containerEl[0].scrollHeight - containerEl.height()
);
}
};
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="' + recipientUid + '"]').addClass('bg-primary');
};
Chats.parseMessage = function(data, callback) {
templates.parse('partials/chat_message' + (Array.isArray(data) ? 's' : ''), {
messages: data
}, callback);
};
return Chats;
});