/* Jappix - An open social platform These are the chat JS scripts for Jappix ------------------------------------------------- License: AGPL Authors: Valérian Saliou, Eric, Maranda */ // Bundle var Chat = (function () { /** * Alias of this * @private */ var self = {}; /** * Correctly opens a new chat * @public * @param {string} xid * @param {string} type * @param {string} nickname * @param {string} password * @param {string} title * @return {boolean} */ self.checkCreate = function(xid, type, nickname, password, title) { try { // No XID? if(!xid) return false; // We generate some stuffs var hash = hex_md5(xid); var name; // Gets the name of the user/title of the room if(title) name = title; else { // Private groupchat chat if(type == 'private') name = Common.thisResource(xid); // XMPP-ID else if(xid.indexOf('@') != -1) name = Name.getBuddy(xid); // Gateway else name = xid; } // If the target div does not exist if(!Common.exists('#' + hash)) { // We check the type of the chat to open if((type == 'chat') || (type == 'private')) self.create(hash, xid, name, type); else if(type == 'groupchat') { // Try to read the room stored configuration if(!Utils.isAnonymous() && (!nickname || !password || !title)) { // Catch the room data var fData = $(Common.XMLFromString(DataStore.getDB(Connection.desktop_hash, 'favorites', xid))); var fNick = fData.find('nick').text(); var fPwd = fData.find('password').text(); var fName = fData.find('name').text(); // Apply the room data if(!nickname && fNick) nickname = fNick; if(!password && fPwd) password = fPwd; if(!title && fName) name = fName; } Groupchat.create(hash, xid, name, nickname, password); } } // Switch to the newly-created chat Interface.switchChan(hash); } catch(e) { Console.error('Chat.checkCreate', e); } finally { return false; } }; /** * Generates the chat DOM elements * @public * @param {string} type * @param {string} id * @param {string} xid * @param {string} nick * @return {undefined} */ self.generate = function(type, id, xid, nick) { try { // Generate some stuffs var path = '#' + id + ' .'; var escaped_xid = escape(xid); // Special code var specialAttributes, specialAvatar, specialName, specialCode, specialLink, specialDisabled, specialStyle, specialMAM; // Groupchat special code if(type == 'groupchat') { specialAttributes = ' data-type="groupchat"'; specialAvatar = ''; specialName = '

' + Common._e("Subject") + ' ' + Common._e("no subject defined for this room.") + '

'; specialCode = '

' + Common._e("Moderators") + '

' + Common._e("Participants") + '

' + Common._e("Visitors") + '

' + Common._e("Others") + '

'; specialLink = ''; specialStyle = ''; // Is this a gateway? if(xid.match(/%/)) specialDisabled = ''; else specialDisabled = ' disabled=""'; } // Chat (or other things?!) special code else { specialMAM = '
'; specialAttributes = ' data-type="chat"'; specialAvatar = '
'; specialName = '

'; specialCode = '
' + specialMAM + '
'; specialLink = '' + '' + ''; specialStyle = ' style="display: none;"'; specialDisabled = ''; } // Not a groupchat private chat, we can use the buddy add icon if((type == 'chat') || (type == 'groupchat')) { var addTitle; if(type == 'chat') addTitle = Common._e("Add this contact to your friends"); else addTitle = Common._e("Add this groupchat to your favorites"); specialLink += ''; } // IE DOM parsing bug fix var specialStylePicker = '
' + '' + '
'; if((BrowserDetect.browser == 'Explorer') && (BrowserDetect.version < 9)) specialStylePicker = ''; // Append the chat HTML code $('#page-engine').append( '
' + '
' + specialAvatar + '
' + '

' + nick.htmlEnc() + '

' + specialName + '
' + '
' + specialCode + '
' + '' + '
' + '' + '
' + '
' + '
' ); // Click event: chat cleaner $(path + 'tools-clear').click(function() { self.clean(id); }); // Click event: call (audio) $(path + 'tools-jingle-audio').click(function() { Jingle.start(xid, 'audio'); }); // Click event: call (video) $(path + 'tools-jingle-video').click(function() { Jingle.start(xid, 'video'); }); // Click event: user-infos $(path + 'tools-infos').click(function() { UserInfos.open(xid); }); } catch(e) { Console.error('Chat.generate', e); } }; /** * Generates the chat switch elements * @public * @param {string} type * @param {string} id * @param {string} xid * @param {string} nick * @return {undefined} */ self.generateSwitch = function(type, id, xid, nick) { try { // Path to the element var chat_switch = '#page-switch .'; // Special code var specialClass = ' unavailable'; var show_close = true; // Groupchat if(type == 'groupchat') { specialClass = ' groupchat-default'; if(Utils.isAnonymous() && (xid == Common.generateXID(ANONYMOUS_ROOM, 'groupchat'))) show_close = false; } // Generate the HTML code var html = '
' + '
' + '
' + nick.htmlEnc() + '
'; // Show the close button if not MUC and not anonymous if(show_close) html += '
x
'; // Close the HTML html += '
'; // Append the HTML code $(chat_switch + 'chans, ' + chat_switch + 'more-content').append(html); } catch(e) { Console.error('Chat.generateSwitch', e); } }; /** * Cleans given the chat lines * @public * @param {string} chat * @return {undefined} */ self.clean = function(chat) { try { // Remove the messages $('#page-engine #' + chat + ' .content .one-group').remove(); // Clear the history database Message.removeLocalArchive(chat); // Focus again $(document).oneTime(10, function() { $('#page-engine #' + chat + ' .text .message-area').focus(); }); } catch(e) { Console.error('Chat.clean', e); } }; /** * Returns whether chat exists or not * @public * @param {string} hash * @return {boolean} */ self.exists = function(hash) { exists = false; try { if(hash) { exists = Common.exists('#' + hash + '.page-engine-chan[data-type="chat"]'); } } catch(e) { Console.error('Chat.exists', e); } finally { return exists; } }; /** * Creates a new chat * @public * @param {string} hash * @param {string} xid * @param {string} nick * @param {string} type * @return {undefined} */ self.create = function(hash, xid, nick, type) { try { Console.info('New chat: ' + xid); // Create the chat content self.generate(type, hash, xid, nick); // Create the chat switcher self.generateSwitch(type, hash, xid, nick); // If the user is not in our roster if(type == 'chat') { // MAM? Get archives from there! if(Features.enabledMAM()) { MAM.getArchives({ 'with': xid }, { 'max': MAM.REQ_MAX, 'before': '' }); } else { // Restore the chat history var chat_history = Message.readLocalArchive(hash); if(chat_history) { // Generate hashs var my_hash = hex_md5(Common.getXID()); var friend_hash = hex_md5(xid); // Add chat history HTML $('#' + hash + ' .content').append(chat_history); // Filter old groups & messages $('#' + hash + ' .one-group[data-type="user-message"]').addClass('from-history').attr('data-type', 'old-message'); $('#' + hash + ' .user-message').removeClass('user-message').addClass('old-message'); // Regenerate user names $('#' + hash + ' .one-group.' + my_hash + ' b.name').text(Name.getBuddy(Common.getXID())); $('#' + hash + ' .one-group.' + friend_hash + ' b.name').text(Name.getBuddy(xid)); // Regenerate group dates $('#' + hash + ' .one-group').each(function() { var current_stamp = parseInt($(this).attr('data-stamp')); $(this).find('span.date').text(DateUtils.relative(current_stamp)); }); // Regenerate avatars if(Common.exists('#' + hash + ' .one-group.' + my_hash + ' .avatar-container')) Avatar.get(Common.getXID(), 'cache', 'true', 'forget'); if(Common.exists('#' + hash + ' .one-group.' + friend_hash + ' .avatar-container')) Avatar.get(xid, 'cache', 'true', 'forget'); } } // Add button if(!Roster.isFriend(xid)) $('#' + hash + ' .tools-add').click(function() { // Hide the icon (to tell the user all is okay) $(this).hide(); // Send the subscribe request Roster.addThisContact(xid, nick); }).show(); } // We catch the user's informations (like this avatar, vcard, and so on...) UserInfos.get(hash, xid, nick, type); // The icons-hover functions Tooltip.icons(xid, hash); // The event handlers var inputDetect = $('#page-engine #' + hash + ' .message-area'); inputDetect.focus(function() { // Clean notifications for this chat Interface.chanCleanNotify(hash); // Store focus on this chat! Interface.chat_focus_hash = hash; }); inputDetect.blur(function() { // Reset storage about focus on this chat! if(Interface.chat_focus_hash == hash) Interface.chat_focus_hash = null; }); inputDetect.keypress(function(e) { // Enter key if(e.keyCode == 13) { // Add a new line if(e.shiftKey || e.ctrlKey) { inputDetect.val(inputDetect.val() + '\n'); } else { // Send the message Message.send(hash, 'chat'); // Reset the composing database entry DataStore.setDB(Connection.desktop_hash, 'chatstate', xid, 'off'); } return false; } }); // Scroll in chat content $('#page-engine #' + hash + ' .content').scroll(function() { var self = this; if(Features.enabledMAM() && !(xid in MAM.map_pending)) { var has_state = xid in MAM.map_states; var rsm_count = has_state ? MAM.map_states[xid].rsm.count : 1; var rsm_before = has_state ? MAM.map_states[xid].rsm.first : ''; // Request more archives? if(rsm_count > 0 && $(this).scrollTop() < MAM.SCROLL_THRESHOLD) { var was_scroll_top = $(self).scrollTop() <= 32; var wait_mam = $('#' + hash).find('.wait-mam'); wait_mam.show(); MAM.getArchives({ 'with': xid }, { 'max': MAM.REQ_MAX, 'before': rsm_before }, function() { var wait_mam_height = was_scroll_top ? 0 : wait_mam.height(); wait_mam.hide(); // Restore scroll? if($(self).scrollTop() < MAM.SCROLL_THRESHOLD) { var sel_mam_chunk = $(self).find('.mam-chunk:first'); var cont_padding_top = parseInt($(self).css('padding-top').replace(/[^-\d\.]/g, '')); var cont_one_group_margin_bottom = parseInt(sel_mam_chunk.find('.one-group:last').css('margin-bottom').replace(/[^-\d\.]/g, '')); var cont_mam_chunk_height = sel_mam_chunk.height(); $(self).scrollTop(wait_mam_height + cont_padding_top + cont_one_group_margin_bottom + cont_mam_chunk_height); } }); } } }); // Chatstate events ChatState.events(inputDetect, xid, hash, 'chat'); } catch(e) { Console.error('Chat.create', e); } }; /** * Return class scope */ return self; })();