mirror of
https://git.friendi.ca/friendica/friendica-addons.git
synced 2024-11-17 20:23:41 +00:00
900 lines
23 KiB
JavaScript
900 lines
23 KiB
JavaScript
/*
|
|
|
|
Jappix - An open social platform
|
|
These are the messages JS scripts for Jappix
|
|
|
|
-------------------------------------------------
|
|
|
|
License: AGPL
|
|
Authors: Vanaryon, Maranda
|
|
Last revision: 01/09/11
|
|
|
|
*/
|
|
|
|
// Handles the incoming message packets
|
|
function handleMessage(message) {
|
|
// Error packet? Stop!
|
|
if(handleErrorReply(message))
|
|
return;
|
|
|
|
// We get the message items
|
|
var from = fullXID(getStanzaFrom(message));
|
|
var id = message.getID();
|
|
var type = message.getType();
|
|
var body = trim(message.getBody());
|
|
var node = message.getNode();
|
|
var subject = trim(message.getSubject());
|
|
|
|
// We generate some values
|
|
var xid = bareXID(from);
|
|
var resource = thisResource(from);
|
|
var hash = hex_md5(xid);
|
|
var xHTML = $(node).find('html body').size();
|
|
var GCUser = false;
|
|
|
|
// This message comes from a groupchat user
|
|
if(isPrivate(xid) && ((type == 'chat') || !type) && resource) {
|
|
GCUser = true;
|
|
xid = from;
|
|
hash = hex_md5(xid);
|
|
}
|
|
|
|
// Get message date
|
|
var time, stamp, d_stamp;
|
|
|
|
// Read the delay
|
|
var delay = readMessageDelay(node);
|
|
|
|
// Any delay?
|
|
if(delay) {
|
|
time = relativeDate(delay);
|
|
d_stamp = Date.jab2date(delay);
|
|
}
|
|
|
|
// No delay: get actual time
|
|
else {
|
|
time = getCompleteTime();
|
|
d_stamp = new Date();
|
|
}
|
|
|
|
// Get the date stamp
|
|
stamp = extractStamp(d_stamp);
|
|
|
|
// Received message
|
|
if(hasReceived(message))
|
|
return messageReceived(hash, id);
|
|
|
|
// Chatstate message
|
|
if(node && !delay && ((((type == 'chat') || !type) && !exists('#page-switch .' + hash + ' .unavailable')) || (type == 'groupchat'))) {
|
|
/* REF: http://xmpp.org/extensions/xep-0085.html */
|
|
|
|
// Re-process the hash
|
|
var chatstate_hash = hash;
|
|
|
|
if(type == 'groupchat')
|
|
chatstate_hash = hex_md5(from);
|
|
|
|
// Do something depending of the received state
|
|
if($(node).find('active').size()) {
|
|
displayChatState('active', chatstate_hash, type);
|
|
|
|
// Tell Jappix the entity supports chatstates
|
|
$('#' + chatstate_hash + ' .message-area').attr('data-chatstates', 'true');
|
|
|
|
logThis('Active chatstate received from: ' + from);
|
|
}
|
|
|
|
else if($(node).find('composing').size())
|
|
displayChatState('composing', chatstate_hash, type);
|
|
|
|
else if($(node).find('paused').size())
|
|
displayChatState('paused', chatstate_hash, type);
|
|
|
|
else if($(node).find('inactive').size())
|
|
displayChatState('inactive', chatstate_hash, type);
|
|
|
|
else if($(node).find('gone').size())
|
|
displayChatState('gone', chatstate_hash, type);
|
|
}
|
|
|
|
// Invite message
|
|
if($(node).find('x[xmlns=' + NS_MUC_USER + '] invite').size()) {
|
|
// We get the needed values
|
|
var iFrom = $(node).find('x[xmlns=' + NS_MUC_USER + '] invite').attr('from');
|
|
var iRoom = $(node).find('x[xmlns=' + NS_XCONFERENCE + ']').attr('jid');
|
|
|
|
// Old invite method?
|
|
if(!iRoom)
|
|
iRoom = from;
|
|
|
|
// We display the notification
|
|
newNotification('invite_room', iFrom, [iRoom], body);
|
|
|
|
logThis('Invite Request from: ' + iFrom + ' to join: ' + iRoom);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Request message
|
|
if(message.getChild('confirm', NS_HTTP_AUTH)) {
|
|
// Open a new notification
|
|
newNotification('request', xid, [message], body);
|
|
|
|
logThis('HTTP Request from: ' + xid);
|
|
|
|
return false;
|
|
}
|
|
|
|
// OOB message
|
|
if(message.getChild('x', NS_XOOB)) {
|
|
handleOOB(from, id, 'x', node);
|
|
|
|
logThis('Message OOB request from: ' + xid);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Roster Item Exchange message
|
|
if(message.getChild('x', NS_ROSTERX)) {
|
|
// Open a new notification
|
|
newNotification('rosterx', xid, [message], body);
|
|
|
|
logThis('Roster Item Exchange from: ' + xid);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Normal message
|
|
if((type == 'normal') && body) {
|
|
// Message date
|
|
var messageDate = delay;
|
|
|
|
// No message date?
|
|
if(!messageDate)
|
|
messageDate = getXMPPTime('utc');
|
|
|
|
// Message ID
|
|
var messageID = hex_md5(xid + subject + messageDate);
|
|
|
|
// We store the received message
|
|
storeInboxMessage(xid, subject, body, 'unread', messageID, messageDate);
|
|
|
|
// Display the inbox message
|
|
if(exists('#inbox'))
|
|
displayInboxMessage(xid, subject, body, 'unread', messageID, messageDate);
|
|
|
|
// Check we have new messages (play a sound if any unread messages)
|
|
if(checkInboxMessages())
|
|
soundPlay(2);
|
|
|
|
// Send it to the server
|
|
storeInbox();
|
|
|
|
return false;
|
|
}
|
|
|
|
// PubSub event
|
|
if($(node).find('event').attr('xmlns') == NS_PUBSUB_EVENT) {
|
|
// We get the needed values
|
|
var iParse = $(node).find('event items');
|
|
var iNode = iParse.attr('node');
|
|
|
|
// Turn around the different result cases
|
|
if(iNode) {
|
|
switch(iNode) {
|
|
// Mood
|
|
case NS_MOOD:
|
|
// Retrieve the values
|
|
var iMood = iParse.find('mood');
|
|
var fValue = '';
|
|
var tText = '';
|
|
|
|
// There's something
|
|
if(iMood.children().size()) {
|
|
// Read the value
|
|
fValue = node.getElementsByTagName('mood').item(0).childNodes.item(0).nodeName;
|
|
|
|
// Read the text
|
|
tText = iMood.find('text').text();
|
|
|
|
// Avoid errors
|
|
if(!fValue)
|
|
fValue = '';
|
|
}
|
|
|
|
// Store the PEP event (and display it)
|
|
storePEP(xid, 'mood', fValue, tText);
|
|
|
|
break;
|
|
|
|
// Activity
|
|
case NS_ACTIVITY:
|
|
// Retrieve the values
|
|
var iActivity = iParse.find('activity');
|
|
var sValue = '';
|
|
var tText = '';
|
|
|
|
// There's something
|
|
if(iActivity.children().size()) {
|
|
// Read the value
|
|
fValue = node.getElementsByTagName('activity').item(0).childNodes.item(0).nodeName;
|
|
|
|
// Read the text
|
|
tText = iActivity.find('text').text();
|
|
|
|
// Avoid errors
|
|
if(!fValue)
|
|
fValue = '';
|
|
}
|
|
|
|
// Store the PEP event (and display it)
|
|
storePEP(xid, 'activity', fValue, tText);
|
|
|
|
break;
|
|
|
|
// Tune
|
|
case NS_TUNE:
|
|
// Retrieve the values
|
|
var iTune = iParse.find('tune');
|
|
var tArtist = iTune.find('artist').text();
|
|
var tSource = iTune.find('source').text();
|
|
var tTitle = iTune.find('title').text();
|
|
var tURI = iTune.find('uri').text();
|
|
|
|
// Store the PEP event (and display it)
|
|
storePEP(xid, 'tune', tArtist, tTitle, tSource, tURI);
|
|
|
|
break;
|
|
|
|
// Geolocation
|
|
case NS_GEOLOC:
|
|
// Retrieve the values
|
|
var iGeoloc = iParse.find('geoloc');
|
|
var tLat = iGeoloc.find('lat').text();
|
|
var tLon = iGeoloc.find('lon').text();
|
|
|
|
// Any extra-values?
|
|
var tLocality = iGeoloc.find('locality').text();
|
|
var tRegion = iGeoloc.find('region').text();
|
|
var tCountry = iGeoloc.find('country').text();
|
|
var tHuman = humanPosition(tLocality, tRegion, tCountry);
|
|
|
|
// Store the PEP event (and display it)
|
|
storePEP(xid, 'geoloc', tLat, tLon, tHuman);
|
|
|
|
break;
|
|
|
|
// Microblog
|
|
case NS_URN_MBLOG:
|
|
displayMicroblog(message, xid, hash, 'mixed', 'push');
|
|
|
|
break;
|
|
|
|
// Inbox
|
|
case NS_URN_INBOX:
|
|
// Do not handle friend's notifications
|
|
if(xid == getXID())
|
|
handleNotifications(message);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// If this is a room topic message
|
|
if(subject && (type == 'groupchat')) {
|
|
// Filter the vars
|
|
var filter_subject = subject.replace(/\n+/g, ' ');
|
|
var filteredSubject = filterThisMessage(filter_subject, resource, true);
|
|
var filteredName = resource.htmlEnc();
|
|
|
|
// Display the new subject at the top
|
|
$('#' + hash + ' .top .name .bc-infos .muc-topic').replaceWith('<span class="muc-topic" title="' + filter_subject + '">' + filteredSubject + '</span>');
|
|
|
|
// Display the new subject as a system message
|
|
if(resource) {
|
|
var topic_body = filteredName + ' ' + _e("changed the subject to:") + ' ' + filterThisMessage(subject, resource, true);
|
|
displayMessage(type, from, hash, filteredName, topic_body, time, stamp, 'system-message', false);
|
|
}
|
|
}
|
|
|
|
// If the message has a content
|
|
if(xHTML || body) {
|
|
var filteredMessage;
|
|
var notXHTML = true;
|
|
|
|
// IE bug fix
|
|
if((BrowserDetect.browser == 'Explorer') && (BrowserDetect.version < 9))
|
|
xHTML = 0;
|
|
|
|
//If this is a xHTML message
|
|
if(xHTML) {
|
|
notXHTML = false;
|
|
|
|
// Filter the xHTML message
|
|
body = filterThisXHTML(node);
|
|
}
|
|
|
|
// Groupchat message
|
|
if(type == 'groupchat') {
|
|
/* REF: http://xmpp.org/extensions/xep-0045.html */
|
|
|
|
// We generate the message type and time
|
|
var message_type = 'user-message';
|
|
|
|
// This is an old message
|
|
if(delay && resource)
|
|
message_type = 'old-message';
|
|
|
|
// This is a system message
|
|
else if(!resource)
|
|
message_type = 'system-message';
|
|
|
|
var nickQuote = '';
|
|
|
|
// If this is not an old message
|
|
if(message_type == 'user-message') {
|
|
var myNick = getMUCNick(hash);
|
|
|
|
// If an user quoted our nick (with some checks)
|
|
var regex = new RegExp('((^)|( )|(@))' + escapeRegex(myNick) + '(($)|(:)|(,)|( ))', 'gi');
|
|
|
|
if(body.match(regex) && (myNick != resource) && (message_type == 'user-message'))
|
|
nickQuote = ' my-nick';
|
|
|
|
// We notify the user if there's a new personnal message
|
|
if(nickQuote) {
|
|
messageNotify(hash, 'personnal');
|
|
soundPlay(1);
|
|
}
|
|
|
|
// We notify the user there's a new unread muc message
|
|
else
|
|
messageNotify(hash, 'unread');
|
|
}
|
|
|
|
// Display the received message
|
|
displayMessage(type, from, hash, resource.htmlEnc(), body, time, stamp, message_type, notXHTML, nickQuote);
|
|
}
|
|
|
|
// Chat message
|
|
else if((type == 'chat') || !type) {
|
|
// Gets the nickname of the user
|
|
var fromName = resource;
|
|
var chatType = 'chat';
|
|
|
|
// Must send a receipt notification?
|
|
if(hasReceipt(message) && (id != null))
|
|
sendReceived(type, from, id);
|
|
|
|
// It does not come from a groupchat user, get the full name
|
|
if(!GCUser)
|
|
fromName = getBuddyName(xid);
|
|
else
|
|
chatType = 'private';
|
|
|
|
// If the chat isn't yet opened, open it !
|
|
if(!exists('#' + hash)) {
|
|
// We create a new chat
|
|
chatCreate(hash, xid, fromName, chatType);
|
|
|
|
// We tell the user that a new chat has started
|
|
soundPlay(0);
|
|
}
|
|
|
|
else
|
|
soundPlay(1);
|
|
|
|
// Display the received message
|
|
displayMessage(type, xid, hash, fromName.htmlEnc(), body, time, stamp, 'user-message', notXHTML, '', 'him');
|
|
|
|
// We notify the user
|
|
messageNotify(hash, 'personnal');
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Sends a given message
|
|
function sendMessage(hash, type) {
|
|
// Get the values
|
|
var message_area = $('#' + hash + ' .message-area');
|
|
var body = trim(message_area.val());
|
|
var xid = unescape(message_area.attr('data-to'));
|
|
|
|
// If the user didn't entered any message, stop
|
|
if(!body || !xid)
|
|
return false;
|
|
|
|
try {
|
|
// We send the message through the XMPP network
|
|
var aMsg = new JSJaCMessage();
|
|
aMsg.setTo(xid);
|
|
|
|
// Set an ID
|
|
var id = genID();
|
|
aMsg.setID(id);
|
|
|
|
// /help shortcut
|
|
if(body.match(/^\/help\s*(.*)/)) {
|
|
// Help text
|
|
var help_text = '<p class="help" xmlns="http://www.w3.org/1999/xhtml">';
|
|
help_text += '<b>' + _e("Available shortcuts:") + '</b>';
|
|
|
|
// Shortcuts array
|
|
var shortcuts = [];
|
|
|
|
// Common shortcuts
|
|
shortcuts.push(printf(_e("%s removes the chat logs"), '<em>/clear</em>'));
|
|
shortcuts.push(printf(_e("%s joins a groupchat"), '<em>/join jid</em>'));
|
|
shortcuts.push(printf(_e("%s closes the chat"), '<em>/part</em>'));
|
|
shortcuts.push(printf(_e("%s shows the user profile"), '<em>/whois jid</em>'));
|
|
|
|
// Groupchat shortcuts
|
|
if(type == 'groupchat') {
|
|
shortcuts.push(printf(_e("%s sends a message to the room"), '<em>/say message</em>'));
|
|
shortcuts.push(printf(_e("%s changes your nickname"), '<em>/nick nickname</em>'));
|
|
shortcuts.push(printf(_e("%s sends a message to someone in the room"), '<em>/msg nickname message</em>'));
|
|
shortcuts.push(printf(_e("%s changes the room topic"), '<em>/topic subject</em>'));
|
|
shortcuts.push(printf(_e("%s kicks an user of the room"), '<em>/kick nickname reason</em>'));
|
|
shortcuts.push(printf(_e("%s bans an user of the room"), '<em>/ban nickname reason</em>'));
|
|
shortcuts.push(printf(_e("%s invites someone to join the room"), '<em>/invite jid message</em>'));
|
|
}
|
|
|
|
// Generate the code from the array
|
|
shortcuts = shortcuts.sort();
|
|
|
|
for(s in shortcuts)
|
|
help_text += shortcuts[s] + '<br />';
|
|
|
|
help_text += '</p>';
|
|
|
|
// Display the message
|
|
displayMessage(type, xid, hash, 'help', help_text, getCompleteTime(), getTimeStamp(), 'system-message', false);
|
|
|
|
// Reset chatstate
|
|
chatStateSend('active', xid, hash);
|
|
}
|
|
|
|
// /clear shortcut
|
|
else if(body.match(/^\/clear/)) {
|
|
cleanChat(hex_md5(xid));
|
|
|
|
// Reset chatstate
|
|
chatStateSend('active', xid, hash);
|
|
}
|
|
|
|
// /join shortcut
|
|
else if(body.match(/^\/join (\S+)\s*(.*)/)) {
|
|
// Join
|
|
var room = generateXID(RegExp.$1, 'groupchat');
|
|
var pass = RegExp.$2;
|
|
|
|
checkChatCreate(room, 'groupchat');
|
|
|
|
// Reset chatstate
|
|
chatStateSend('active', xid, hash);
|
|
}
|
|
|
|
// /part shortcut
|
|
else if(body.match(/^\/part\s*(.*)/) && (!isAnonymous() || (isAnonymous() && (xid != generateXID(ANONYMOUS_ROOM, 'groupchat')))))
|
|
quitThisChat(xid, hex_md5(xid), type);
|
|
|
|
// /whois shortcut
|
|
else if(body.match(/^\/whois(( (\S+))|($))/)) {
|
|
var whois_xid = RegExp.$3;
|
|
|
|
// Groupchat WHOIS
|
|
if(type == 'groupchat') {
|
|
var nXID = getMUCUserXID(xid, whois_xid);
|
|
|
|
if(!nXID)
|
|
openThisInfo(6);
|
|
else
|
|
openUserInfos(nXID);
|
|
}
|
|
|
|
// Chat or private WHOIS
|
|
else {
|
|
if(!whois_xid)
|
|
openUserInfos(xid);
|
|
else
|
|
openUserInfos(whois_xid);
|
|
}
|
|
|
|
// Reset chatstate
|
|
chatStateSend('active', xid, hash);
|
|
}
|
|
|
|
// Chat message type
|
|
else if(type == 'chat') {
|
|
aMsg.setType('chat');
|
|
|
|
// Generates the correct message depending of the choosen style
|
|
var notXHTML = true;
|
|
var genMsg = generateMessage(aMsg, body, hash);
|
|
|
|
if(genMsg == 'XHTML')
|
|
notXHTML = false;
|
|
|
|
// Receipt request
|
|
var receipt_request = receiptRequest(hash);
|
|
|
|
if(receipt_request)
|
|
aMsg.appendNode('request', {'xmlns': NS_URN_RECEIPTS});
|
|
|
|
// Chatstate
|
|
aMsg.appendNode('active', {'xmlns': NS_CHATSTATES});
|
|
|
|
// Send it!
|
|
con.send(aMsg, handleErrorReply);
|
|
|
|
// Filter the xHTML message (for us!)
|
|
if(!notXHTML)
|
|
body = filterThisXHTML(aMsg.getNode());
|
|
|
|
// Finally we display the message we just sent
|
|
var my_xid = getXID();
|
|
|
|
displayMessage('chat', my_xid, hash, getBuddyName(my_xid).htmlEnc(), body, getCompleteTime(), getTimeStamp(), 'user-message', notXHTML, '', 'me', id);
|
|
|
|
// Receipt timer
|
|
if(receipt_request)
|
|
checkReceived(hash, id);
|
|
}
|
|
|
|
// Groupchat message type
|
|
else if(type == 'groupchat') {
|
|
// /say shortcut
|
|
if(body.match(/^\/say (.+)/)) {
|
|
body = body.replace(/^\/say (.+)/, '$1');
|
|
|
|
aMsg.setType('groupchat');
|
|
generateMessage(aMsg, body, hash);
|
|
|
|
con.send(aMsg, handleErrorReply);
|
|
}
|
|
|
|
// /nick shortcut
|
|
else if(body.match(/^\/nick (.+)/)) {
|
|
var nick = body.replace(/^\/nick (.+)/, '$1');
|
|
|
|
// Does not exist yet?
|
|
if(!getMUCUserXID(xid, nick)) {
|
|
// Send a new presence
|
|
sendPresence(xid + '/' + nick, '', getUserShow(), getUserStatus(), '', false, false, handleErrorReply);
|
|
|
|
// Change the stored nickname
|
|
$('#' + hex_md5(xid)).attr('data-nick', escape(nick));
|
|
|
|
// Reset chatstate
|
|
chatStateSend('active', xid, hash);
|
|
}
|
|
}
|
|
|
|
// /msg shortcut
|
|
else if(body.match(/^\/msg (\S+)\s+(.+)/)) {
|
|
var nick = RegExp.$1;
|
|
var body = RegExp.$2;
|
|
var nXID = getMUCUserXID(xid, nick);
|
|
|
|
// We check if the user exists
|
|
if(!nXID)
|
|
openThisInfo(6);
|
|
|
|
// If the private message is not empty
|
|
else if(body) {
|
|
aMsg.setType('chat');
|
|
aMsg.setTo(nXID);
|
|
generateMessage(aMsg, body, hash);
|
|
|
|
con.send(aMsg, handleErrorReply);
|
|
}
|
|
}
|
|
|
|
// /topic shortcut
|
|
else if(body.match(/^\/topic (.+)/)) {
|
|
var topic = body.replace(/^\/topic (.+)/, '$1');
|
|
|
|
aMsg.setType('groupchat');
|
|
aMsg.setSubject(topic);
|
|
|
|
con.send(aMsg, handleMessageError);
|
|
|
|
// Reset chatstate
|
|
chatStateSend('active', xid, hash);
|
|
}
|
|
|
|
// /ban shortcut
|
|
else if(body.match(/^\/ban (\S+)\s*(.*)/)) {
|
|
var nick = RegExp.$1;
|
|
var reason = RegExp.$2;
|
|
var nXID = getMUCUserRealXID(xid, nick);
|
|
|
|
// We check if the user exists
|
|
if(!nXID)
|
|
openThisInfo(6);
|
|
|
|
else {
|
|
// We generate the ban IQ
|
|
var iq = new JSJaCIQ();
|
|
iq.setTo(xid);
|
|
iq.setType('set');
|
|
|
|
var iqQuery = iq.setQuery(NS_MUC_ADMIN);
|
|
var item = iqQuery.appendChild(iq.buildNode('item', {'affiliation': 'outcast', 'jid': nXID, 'xmlns': NS_MUC_ADMIN}));
|
|
|
|
if(reason)
|
|
item.appendChild(iq.buildNode('reason', {'xmlns': NS_MUC_ADMIN}, reason));
|
|
|
|
con.send(iq, handleErrorReply);
|
|
}
|
|
|
|
// Reset chatstate
|
|
chatStateSend('active', xid, hash);
|
|
}
|
|
|
|
// /kick shortcut
|
|
else if(body.match(/^\/kick (\S+)\s*(.*)/)) {
|
|
var nick = RegExp.$1;
|
|
var reason = RegExp.$2;
|
|
var nXID = getMUCUserXID(xid, nick);
|
|
|
|
// We check if the user exists
|
|
if(!nXID)
|
|
openThisInfo(6);
|
|
|
|
else {
|
|
// We generate the kick IQ
|
|
var iq = new JSJaCIQ();
|
|
iq.setTo(xid);
|
|
iq.setType('set');
|
|
|
|
var iqQuery = iq.setQuery(NS_MUC_ADMIN);
|
|
var item = iqQuery.appendChild(iq.buildNode('item', {'nick': nick, 'role': 'none', 'xmlns': NS_MUC_ADMIN}));
|
|
|
|
if(reason)
|
|
item.appendChild(iq.buildNode('reason', {'xmlns': NS_MUC_ADMIN}, reason));
|
|
|
|
con.send(iq, handleErrorReply);
|
|
}
|
|
|
|
// Reset chatstate
|
|
chatStateSend('active', xid, hash);
|
|
}
|
|
|
|
// /invite shortcut
|
|
else if(body.match(/^\/invite (\S+)\s*(.*)/)) {
|
|
var i_xid = RegExp.$1;
|
|
var reason = RegExp.$2;
|
|
|
|
var x = aMsg.appendNode('x', {'xmlns': NS_MUC_USER});
|
|
var aNode = x.appendChild(aMsg.buildNode('invite', {'to': i_xid, 'xmlns': NS_MUC_USER}));
|
|
|
|
if(reason)
|
|
aNode.appendChild(aMsg.buildNode('reason', {'xmlns': NS_MUC_USER}, reason));
|
|
|
|
con.send(aMsg, handleErrorReply);
|
|
|
|
// Reset chatstate
|
|
chatStateSend('active', xid, hash);
|
|
}
|
|
|
|
// No shortcut, this is a message
|
|
else {
|
|
aMsg.setType('groupchat');
|
|
|
|
// Chatstate
|
|
aMsg.appendNode('active', {'xmlns': NS_CHATSTATES});
|
|
|
|
generateMessage(aMsg, body, hash);
|
|
|
|
con.send(aMsg, handleMessageError);
|
|
|
|
logThis('Message sent to: ' + xid + ' / ' + type, 3);
|
|
}
|
|
}
|
|
|
|
// We reset the message input
|
|
$('#' + hash + ' .message-area').val('');
|
|
}
|
|
|
|
finally {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Generates the correct message area style
|
|
function generateStyle(hash) {
|
|
// Initialize the vars
|
|
var styles = '#' + hash + ' div.bubble-style';
|
|
var checkbox = styles + ' input[type=checkbox]';
|
|
var color = styles + ' a.color.selected';
|
|
var style = '';
|
|
|
|
// Loop the input values
|
|
$(checkbox).filter(':checked').each(function() {
|
|
// If there is a previous element
|
|
if(style)
|
|
style += ' ';
|
|
|
|
// Get the current style
|
|
switch($(this).attr('class')) {
|
|
case 'bold':
|
|
style += 'font-weight: bold;';
|
|
break;
|
|
|
|
case 'italic':
|
|
style += 'font-style: italic;';
|
|
break;
|
|
|
|
case 'underline':
|
|
style += 'text-decoration: underline;';
|
|
break;
|
|
}
|
|
});
|
|
|
|
// Get the color value
|
|
$(color).each(function() {
|
|
style += 'color: #' + $(this).attr('data-color');
|
|
});
|
|
|
|
return style;
|
|
}
|
|
|
|
// Generates the correct message code
|
|
function generateMessage(aMsg, body, hash) {
|
|
// Create the classical body
|
|
aMsg.setBody(body);
|
|
|
|
// Get the style
|
|
var style = $('#' + hash + ' .message-area').attr('style');
|
|
|
|
// A message style is choosen
|
|
if(style) {
|
|
// Explode the message body new lines (to create one <p /> element by line)
|
|
var new_lines = new Array(body);
|
|
|
|
if(body.match(/\n/))
|
|
new_lines = body.split('\n');
|
|
|
|
// Create the XML elements
|
|
var aHtml = aMsg.appendNode('html', {'xmlns': NS_XHTML_IM});
|
|
var aBody = aHtml.appendChild(aMsg.buildNode('body', {'xmlns': NS_XHTML}));
|
|
|
|
// Use the exploded body array to create one element per entry
|
|
for(i in new_lines) {
|
|
// Current line
|
|
var cLine = new_lines[i];
|
|
|
|
// Blank line, we put a <br />
|
|
if(cLine.match(/(^)(\s+)($)/) || !cLine)
|
|
aBody.appendChild(aMsg.buildNode('br', {'xmlns': NS_XHTML}));
|
|
|
|
// Line with content, we put a <p />
|
|
else {
|
|
// HTML encode the line
|
|
cLine = cLine.htmlEnc();
|
|
|
|
// Filter the links
|
|
cLine = applyLinks(cLine, 'xhtml-im', style);
|
|
|
|
// Append the filtered line
|
|
$(aBody).append($('<p style="' + style + '">' + cLine + '</p>'));
|
|
}
|
|
}
|
|
|
|
return 'XHTML';
|
|
}
|
|
|
|
return 'PLAIN';
|
|
}
|
|
|
|
// Displays a given message in a chat tab
|
|
function displayMessage(type, xid, hash, name, body, time, stamp, message_type, is_xhtml, nick_quote, mode, id) {
|
|
// Generate some stuffs
|
|
var has_avatar = false;
|
|
var xid_hash = '';
|
|
|
|
if(!nick_quote)
|
|
nick_quote = '';
|
|
|
|
if(message_type != 'system-message') {
|
|
has_avatar = true;
|
|
xid_hash = hex_md5(xid);
|
|
}
|
|
|
|
// Can scroll?
|
|
var cont_scroll = document.getElementById('chat-content-' + hash);
|
|
var can_scroll = false;
|
|
|
|
if(!cont_scroll.scrollTop || ((cont_scroll.clientHeight + cont_scroll.scrollTop) == cont_scroll.scrollHeight))
|
|
can_scroll = true;
|
|
|
|
// Any ID?
|
|
var data_id = '';
|
|
|
|
if(id)
|
|
data_id = ' data-id="' + id + '"';
|
|
|
|
// Filter the message
|
|
var filteredMessage = filterThisMessage(body, name, is_xhtml);
|
|
|
|
// Display the received message in the room
|
|
var messageCode = '<div class="one-line ' + message_type + nick_quote + '"' + data_id + '>';
|
|
|
|
// Name color attribute
|
|
if(type == 'groupchat')
|
|
attribute = ' style="color: ' + generateColor(name) + ';" class="name';
|
|
else {
|
|
attribute = ' class="name';
|
|
|
|
if(mode)
|
|
attribute += ' ' + mode;
|
|
}
|
|
|
|
// Close the class attribute
|
|
if(message_type == 'system-message')
|
|
attribute += ' hidden"';
|
|
else
|
|
attribute += '"';
|
|
|
|
// Filter the previous displayed message
|
|
var last = $('#' + hash + ' .one-group:last');
|
|
var last_name = last.find('b.name').attr('data-xid');
|
|
var last_type = last.attr('data-type');
|
|
var last_stamp = parseInt(last.attr('data-stamp'));
|
|
var grouped = false;
|
|
|
|
// We can group it with another previous message
|
|
if((last_name == xid) && (message_type == last_type) && ((stamp - last_stamp) <= 1800))
|
|
grouped = true;
|
|
|
|
// Is it a /me command?
|
|
if(body.match(/(^|>)(\/me )([^<]+)/))
|
|
filteredMessage = '<i>' + filteredMessage + '</i>';
|
|
|
|
messageCode += filteredMessage + '</div>';
|
|
|
|
// Must group it?
|
|
var group_path = ' .one-group:last';
|
|
|
|
if(!grouped) {
|
|
// Generate message headers
|
|
var message_head = '';
|
|
|
|
// Any avatar to add?
|
|
if(has_avatar)
|
|
message_head += '<div class="avatar-container"><img class="avatar" src="' + './img/others/default-avatar.png' + '" alt="" /></div>';
|
|
|
|
// Add the date & the name
|
|
message_head += '<span class="date">' + time + '</span><b data-xid="' + encodeQuotes(xid) + '" ' + attribute + '>' + name + '</b>';
|
|
|
|
// Generate message code
|
|
group_path = '';
|
|
messageCode = '<div class="one-group ' + xid_hash + '" data-type="' + message_type + '" data-stamp="' + stamp + '">' + message_head + messageCode + '</div>';
|
|
}
|
|
|
|
// Archive message
|
|
if(hash == 'archives')
|
|
$('#archives .logs' + group_path).append(messageCode);
|
|
|
|
// Instant message
|
|
else {
|
|
// Write the code in the DOM
|
|
$('#' + hash + ' .content' + group_path).append(messageCode);
|
|
|
|
// Must get the avatar?
|
|
if(has_avatar && xid)
|
|
getAvatar(xid, 'cache', 'true', 'forget');
|
|
}
|
|
|
|
// Scroll to this message
|
|
if(can_scroll)
|
|
autoScroll(hash);
|
|
}
|