mirror of
https://git.friendi.ca/friendica/friendica-addons.git
synced 2024-11-27 04:33:17 +00:00
1123 lines
30 KiB
JavaScript
1123 lines
30 KiB
JavaScript
|
/*
|
||
|
|
||
|
Jappix - An open social platform
|
||
|
These are the roster JS scripts for Jappix
|
||
|
|
||
|
-------------------------------------------------
|
||
|
|
||
|
License: AGPL
|
||
|
Author: Vanaryon
|
||
|
Last revision: 19/05/11
|
||
|
|
||
|
*/
|
||
|
|
||
|
// Gets the roster items
|
||
|
function getRoster() {
|
||
|
var iq = new JSJaCIQ();
|
||
|
|
||
|
iq.setType('get');
|
||
|
iq.setQuery(NS_ROSTER);
|
||
|
|
||
|
con.send(iq, handleRoster);
|
||
|
}
|
||
|
|
||
|
// Handles the roster items
|
||
|
function handleRoster(iq) {
|
||
|
// Define some variables
|
||
|
var handleXML = iq.getQuery();
|
||
|
var current, xid, dName, subscription, group, xidHash, getNick, nick;
|
||
|
|
||
|
// Parse the vcard xml
|
||
|
$(handleXML).find('item').each(function() {
|
||
|
parseRoster($(this), 'load');
|
||
|
});
|
||
|
|
||
|
// Update our avatar (if changed), and send our presence
|
||
|
getAvatar(getXID(), 'force', 'true', 'forget');
|
||
|
|
||
|
logThis('Roster received.');
|
||
|
}
|
||
|
|
||
|
// Parses the group XML and display the roster
|
||
|
function parseRoster(current, mode) {
|
||
|
// Get the values
|
||
|
xid = current.attr('jid');
|
||
|
dName = current.attr('name');
|
||
|
subscription = current.attr('subscription');
|
||
|
xidHash = hex_md5(xid);
|
||
|
|
||
|
// Create an array containing the groups
|
||
|
var groups = new Array();
|
||
|
|
||
|
current.find('group').each(function() {
|
||
|
var group_text = $(this).text();
|
||
|
|
||
|
if(group_text)
|
||
|
groups.push(group_text);
|
||
|
});
|
||
|
|
||
|
// No group?
|
||
|
if(!groups.length)
|
||
|
groups.push(_e("Unclassified"));
|
||
|
|
||
|
// If no name is defined, we get the default nick of the buddy
|
||
|
if(!dName)
|
||
|
dName = getXIDNick(xid);
|
||
|
|
||
|
displayRoster(xid, xidHash, dName, subscription, groups, mode);
|
||
|
}
|
||
|
|
||
|
// Updates the roster groups
|
||
|
function updateGroups() {
|
||
|
$('#buddy-list .one-group').each(function() {
|
||
|
// Current values
|
||
|
var check = $(this).find('.buddy').size();
|
||
|
var hidden = $(this).find('.buddy:not(.hidden-buddy:hidden)').size();
|
||
|
|
||
|
// Special case: the filtering tool
|
||
|
if(SEARCH_FILTERED)
|
||
|
hidden = $(this).find('.buddy:visible').size();
|
||
|
|
||
|
// If the group is empty
|
||
|
if(!check)
|
||
|
$(this).remove();
|
||
|
|
||
|
// If the group contains no online buddy (and is not just hidden)
|
||
|
if(!hidden && $(this).find('a.group').hasClass('minus'))
|
||
|
$(this).hide();
|
||
|
else
|
||
|
$(this).show();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Displays a defined roster item
|
||
|
function displayRoster(dXID, dXIDHash, dName, dSubscription, dGroup, dMode) {
|
||
|
// First remove the buddy
|
||
|
$('#buddy-list .' + dXIDHash).remove();
|
||
|
|
||
|
// Define some things around the groups
|
||
|
var is_gateway = isGateway(dXID);
|
||
|
var gateway = '';
|
||
|
|
||
|
if(is_gateway) {
|
||
|
gateway = ' gateway';
|
||
|
dGroup = new Array(_e("Gateways"));
|
||
|
}
|
||
|
|
||
|
// Remove request (empty his social channel)
|
||
|
if(dSubscription == 'remove')
|
||
|
$('#channel .mixed .one-update.update_' + dXIDHash).remove();
|
||
|
|
||
|
// Other request
|
||
|
else {
|
||
|
// Is this buddy blocked?
|
||
|
var privacy_class = '';
|
||
|
var privacy_state = statusPrivacy('block', dXID);
|
||
|
|
||
|
if(privacy_state == 'deny')
|
||
|
privacy_class = ' blocked';
|
||
|
|
||
|
// For each group this buddy has
|
||
|
for(i in dGroup) {
|
||
|
var cGroup = dGroup[i];
|
||
|
|
||
|
if(cGroup) {
|
||
|
// Process some vars
|
||
|
var groupHash = 'group' + hex_md5(cGroup);
|
||
|
var groupContent = '#buddy-list .' + groupHash;
|
||
|
var groupBuddies = groupContent + ' .group-buddies';
|
||
|
|
||
|
// Is this group blocked?
|
||
|
if((statusPrivacy('block', cGroup) == 'deny') && (privacy_state != 'allow'))
|
||
|
privacy_class = ' blocked';
|
||
|
|
||
|
// Group not yet displayed
|
||
|
if(!exists(groupContent)) {
|
||
|
// Define some things
|
||
|
var groupCont = '#buddy-list .content';
|
||
|
var groupToggle = groupCont + ' .' + groupHash + ' a.group';
|
||
|
|
||
|
// Create the HTML markup of the group
|
||
|
$(groupCont).prepend(
|
||
|
'<div class="' + groupHash + ' one-group" data-group="' + escape(cGroup) + '">' +
|
||
|
'<a href="#" class="group talk-images minus">' + cGroup.htmlEnc() + '</a>' +
|
||
|
'<div class="group-buddies"></div>' +
|
||
|
'</div>'
|
||
|
);
|
||
|
|
||
|
// Create the click event which will hide and show the content
|
||
|
$(groupToggle).click(function() {
|
||
|
var group = $(groupBuddies);
|
||
|
var group_toggle = $(groupContent + ' a.group');
|
||
|
|
||
|
// We must hide the buddies
|
||
|
if(group_toggle.hasClass('minus')) {
|
||
|
group.hide();
|
||
|
group_toggle.removeClass('minus').addClass('plus');
|
||
|
|
||
|
// Remove the group opened buddy-info
|
||
|
closeBubbles();
|
||
|
}
|
||
|
|
||
|
// We must show the buddies
|
||
|
else {
|
||
|
group_toggle.removeClass('plus').addClass('minus');
|
||
|
group.show();
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Initialize the HTML code
|
||
|
var name_code = '<p class="buddy-name">' + dName.htmlEnc() + '</p>';
|
||
|
var presence_code = '<p class="buddy-presence talk-images unavailable">' + _e("Unavailable") + '</p>';
|
||
|
|
||
|
var html = '<div class="hidden-buddy buddy ibubble ' + dXIDHash + gateway + privacy_class + '" data-xid="' + escape(dXID) + '">' +
|
||
|
'<div class="buddy-click">';
|
||
|
|
||
|
// Display avatar if not gateway
|
||
|
if(!is_gateway)
|
||
|
html += '<div class="avatar-container">' +
|
||
|
'<img class="avatar" src="' + './img/others/default-avatar.png' + '" alt="" />' +
|
||
|
'</div>';
|
||
|
|
||
|
html += '<div class="name">';
|
||
|
|
||
|
// Special gateway code
|
||
|
if(is_gateway)
|
||
|
html += presence_code +
|
||
|
name_code;
|
||
|
|
||
|
else
|
||
|
html += name_code +
|
||
|
presence_code;
|
||
|
|
||
|
html += '</div></div></div>';
|
||
|
|
||
|
// Create the DOM element for this buddy
|
||
|
$(groupBuddies).append(html);
|
||
|
|
||
|
// Apply the hover event
|
||
|
applyBuddyHover(dXID, dXIDHash, dName, dSubscription, dGroup, groupHash);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Click event on this buddy
|
||
|
$('#buddy-list .' + dXIDHash + ' .buddy-click').click(function() {
|
||
|
return checkChatCreate(dXID, 'chat');
|
||
|
});
|
||
|
|
||
|
// We get the user presence if necessary
|
||
|
if(dMode == 'presence')
|
||
|
presenceFunnel(dXID, dXIDHash);
|
||
|
|
||
|
// If the buddy must be shown
|
||
|
if(BLIST_ALL)
|
||
|
$('#buddy-list .' + dXIDHash).show();
|
||
|
}
|
||
|
|
||
|
// We update our groups
|
||
|
if(!SEARCH_FILTERED)
|
||
|
updateGroups();
|
||
|
else
|
||
|
funnelFilterBuddySearch();
|
||
|
}
|
||
|
|
||
|
// Applies the buddy editing input events
|
||
|
function applyBuddyInput(xid) {
|
||
|
// Initialize
|
||
|
var path = '#buddy-list .buddy[data-xid=' + escape(xid) + ']';
|
||
|
var rename = path + ' .bm-rename input';
|
||
|
var group = path + ' .bm-group input';
|
||
|
var manage_infos = path + ' .manage-infos';
|
||
|
var bm_choose = manage_infos + ' div.bm-choose';
|
||
|
|
||
|
// Keyup events
|
||
|
$(rename).keyup(function(e) {
|
||
|
if(e.keyCode == 13) {
|
||
|
// Send the item
|
||
|
sendRoster(xid, '', trim($(rename).val()), thisBuddyGroups(xid));
|
||
|
|
||
|
// Remove the buddy editor
|
||
|
closeBubbles();
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
$(group).keyup(function(e) {
|
||
|
if(e.keyCode == 13) {
|
||
|
// Empty input?
|
||
|
if(!trim($(this).val())) {
|
||
|
// Send the item
|
||
|
sendRoster(xid, '', trim($(rename).val()), thisBuddyGroups(xid));
|
||
|
|
||
|
// Remove the buddy editor
|
||
|
closeBubbles();
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Get the values
|
||
|
var this_value = trim($(this).val());
|
||
|
var escaped_value = escape(this_value);
|
||
|
|
||
|
// Check if the group yet exists
|
||
|
var group_exists = false;
|
||
|
|
||
|
$(bm_choose + ' label span').each(function() {
|
||
|
if($(this).text() == this_value)
|
||
|
group_exists = true;
|
||
|
});
|
||
|
|
||
|
// Create a new checked checkbox
|
||
|
if(!group_exists)
|
||
|
$(bm_choose).prepend('<label><input type="checkbox" data-group="' + escaped_value + '" /><span>' + this_value.htmlEnc() + '</span></label>');
|
||
|
|
||
|
// Check the checkbox
|
||
|
$(bm_choose + ' input[data-group=' + escaped_value + ']').attr('checked', true);
|
||
|
|
||
|
// Reset the value of this input
|
||
|
$(this).val('');
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Click events
|
||
|
$(manage_infos + ' p.bm-authorize a.to').click(function() {
|
||
|
closeBubbles();
|
||
|
sendSubscribe(xid, 'subscribed');
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
$(manage_infos + ' p.bm-authorize a.from').click(function() {
|
||
|
closeBubbles();
|
||
|
sendSubscribe(xid, 'subscribe');
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
$(manage_infos + ' p.bm-authorize a.unblock').click(function() {
|
||
|
closeBubbles();
|
||
|
|
||
|
// Update privacy settings
|
||
|
pushPrivacy('block', ['jid'], [xid], ['allow'], ['1'], [false], [true], [true], [true], '', 'roster');
|
||
|
$(path).removeClass('blocked');
|
||
|
|
||
|
// Enable the "block" list
|
||
|
changePrivacy('block', 'active');
|
||
|
changePrivacy('block', 'default');
|
||
|
|
||
|
// Send an available presence
|
||
|
sendPresence(xid, 'available', getUserShow(), getUserStatus());
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
$(manage_infos + ' p.bm-remove a.remove').click(function() {
|
||
|
closeBubbles();
|
||
|
sendRoster(xid, 'remove');
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
$(manage_infos + ' p.bm-remove a.prohibit').click(function() {
|
||
|
closeBubbles();
|
||
|
sendSubscribe(xid, 'unsubscribed');
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
$(manage_infos + ' p.bm-remove a.block').click(function() {
|
||
|
closeBubbles();
|
||
|
|
||
|
// Update privacy settings
|
||
|
pushPrivacy('block', ['jid'], [xid], ['deny'], ['1'], [false], [true], [true], [true], '', 'roster');
|
||
|
$(path).addClass('blocked');
|
||
|
|
||
|
// Enable the "block" list
|
||
|
changePrivacy('block', 'active');
|
||
|
changePrivacy('block', 'default');
|
||
|
|
||
|
// Send an unavailable presence
|
||
|
sendPresence(xid, 'unavailable');
|
||
|
|
||
|
// Remove the user presence
|
||
|
for(var i = 0; i < sessionStorage.length; i++) {
|
||
|
// Get the pointer values
|
||
|
var current = sessionStorage.key(i);
|
||
|
|
||
|
// If the pointer is on a stored presence
|
||
|
if((explodeThis('_', current, 0) == 'presence') && (bareXID(explodeThis('_', current, 1)) == xid))
|
||
|
sessionStorage.removeItem(current);
|
||
|
}
|
||
|
|
||
|
// Manage his new presence
|
||
|
presenceFunnel(xid, hex_md5(xid));
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
$(manage_infos + ' a.save').click(function() {
|
||
|
// Send the item
|
||
|
sendRoster(xid, '', trim($(rename).val()), thisBuddyGroups(xid));
|
||
|
|
||
|
// Remove the buddy editor
|
||
|
closeBubbles();
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Applies the buddy editing hover events
|
||
|
function applyBuddyHover(xid, hash, nick, subscription, groups, group_hash) {
|
||
|
// Generate the values
|
||
|
var bPath = '#buddy-list .' + group_hash + ' .buddy[data-xid=' + escape(xid) + ']';
|
||
|
var iPath = bPath + ' .buddy-infos';
|
||
|
|
||
|
// Apply the hover event
|
||
|
$(bPath).hover(function() {
|
||
|
// Another bubble exist
|
||
|
if(exists('#buddy-list .buddy-infos'))
|
||
|
return false;
|
||
|
|
||
|
$(bPath).oneTime(200, function() {
|
||
|
// Another bubble exist
|
||
|
if(exists('#buddy-list .buddy-infos'))
|
||
|
return false;
|
||
|
|
||
|
// Add this bubble!
|
||
|
showBubble(iPath);
|
||
|
|
||
|
// Create the buddy infos DOM element
|
||
|
$(bPath).append(
|
||
|
'<div class="buddy-infos bubble removable">' +
|
||
|
'<div class="buddy-infos-subarrow talk-images"></div>' +
|
||
|
'<div class="buddy-infos-subitem">' +
|
||
|
'<div class="pep-infos">' +
|
||
|
'<p class="bi-status talk-images unavailable">' + _e("unknown") + '</p>' +
|
||
|
'<p class="bi-mood talk-images mood-four">' + _e("unknown") + '</p>' +
|
||
|
'<p class="bi-activity talk-images activity-exercising">' + _e("unknown") + '</p>' +
|
||
|
'<p class="bi-tune talk-images tune-note">' + _e("unknown") + '</p>' +
|
||
|
'<p class="bi-geoloc talk-images location-world">' + _e("unknown") + '</p>' +
|
||
|
'<p class="bi-view talk-images view-individual"><a href="#" class="profile">' + _e("Profile") + '</a> / <a href="#" class="channel">' + _e("Channel") + '</a> / <a href="#" class="commands">' + _e("Commands") + '</a></p>' +
|
||
|
'<p class="bi-edit talk-images edit-buddy"><a href="#">' + _e("Edit") + '</a></p>' +
|
||
|
'</div>' +
|
||
|
'</div>' +
|
||
|
'</div>'
|
||
|
);
|
||
|
|
||
|
// Sets the good position
|
||
|
buddyInfosPosition(xid, group_hash);
|
||
|
|
||
|
// Get the presence
|
||
|
presenceFunnel(xid, hash);
|
||
|
|
||
|
// Get the PEP infos
|
||
|
displayAllPEP(xid);
|
||
|
|
||
|
// Click events
|
||
|
$(bPath + ' .bi-view a').click(function() {
|
||
|
// Renitialize the buddy infos
|
||
|
closeBubbles();
|
||
|
|
||
|
// Profile
|
||
|
if($(this).is('.profile'))
|
||
|
openUserInfos(xid);
|
||
|
|
||
|
// Channel
|
||
|
else if($(this).is('.channel'))
|
||
|
fromInfosMicroblog(xid, hash);
|
||
|
|
||
|
// Command
|
||
|
else if($(this).is('.commands'))
|
||
|
retrieveAdHoc(xid);
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
$(bPath + ' .bi-edit a').click(function() {
|
||
|
buddyEdit(xid, nick, subscription, groups);
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
});
|
||
|
}, function() {
|
||
|
if(!exists(iPath + ' .manage-infos'))
|
||
|
closeBubbles();
|
||
|
|
||
|
$(bPath).stopTime();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Sets the good buddy-infos position
|
||
|
function buddyInfosPosition(xid, group_hash) {
|
||
|
// Paths
|
||
|
var group = '#buddy-list .' + group_hash;
|
||
|
var buddy = group + ' .buddy[data-xid=' + escape(xid) + ']';
|
||
|
var buddy_infos = buddy + ' .buddy-infos';
|
||
|
|
||
|
// Get the offset to define
|
||
|
var offset = 3;
|
||
|
|
||
|
if(isGateway(xid))
|
||
|
offset = -8;
|
||
|
|
||
|
// Process the position
|
||
|
var top = $(buddy).position().top + offset;
|
||
|
var left = $(buddy).width() - 10;
|
||
|
|
||
|
// Apply the top position
|
||
|
$(buddy_infos).css('top', top)
|
||
|
.css('left', left);
|
||
|
}
|
||
|
|
||
|
// Generates an array of the current groups of a buddy
|
||
|
function thisBuddyGroups(xid) {
|
||
|
var path = '#buddy-list .buddy[data-xid=' + escape(xid) + '] ';
|
||
|
var array = new Array();
|
||
|
|
||
|
// Each checked checkboxes
|
||
|
$(path + 'div.bm-choose input[type=checkbox]').filter(':checked').each(function() {
|
||
|
array.push(unescape($(this).attr('data-group')));
|
||
|
});
|
||
|
|
||
|
// Entered input value (and not yet in the array)
|
||
|
var value = trim($(path + 'p.bm-group input').val());
|
||
|
|
||
|
if(value && !existArrayValue(array, value))
|
||
|
array.push(value);
|
||
|
|
||
|
return array;
|
||
|
}
|
||
|
|
||
|
// Adds a given contact to our roster
|
||
|
function addThisContact(xid, name) {
|
||
|
logThis('Add this contact: ' + xid + ', as ' + name, 3);
|
||
|
|
||
|
// Cut the resource of this XID
|
||
|
xid = bareXID(xid);
|
||
|
|
||
|
// If the form is complete
|
||
|
if(xid) {
|
||
|
// We send the subscription
|
||
|
sendSubscribe(xid, 'subscribe');
|
||
|
sendRoster(xid, '', name);
|
||
|
|
||
|
// We hide the bubble
|
||
|
closeBubbles();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Gets an array of all the groups in the roster
|
||
|
function getAllGroups() {
|
||
|
var groups = new Array();
|
||
|
|
||
|
$('#buddy-list .one-group').each(function() {
|
||
|
var current = unescape($(this).attr('data-group'));
|
||
|
|
||
|
if((current != _e("Unclassified")) && (current != _e("Gateways")))
|
||
|
groups.push(current);
|
||
|
});
|
||
|
|
||
|
return groups.sort();
|
||
|
}
|
||
|
|
||
|
// Edits buddy informations
|
||
|
function buddyEdit(xid, nick, subscription, groups) {
|
||
|
logThis('Buddy edit: ' + xid, 3);
|
||
|
|
||
|
// Initialize
|
||
|
var path = '#buddy-list .buddy[data-xid=' + escape(xid) + '] .';
|
||
|
var html = '<div class="manage-infos">';
|
||
|
|
||
|
// Get the privacy state
|
||
|
var privacy_state = statusPrivacy('block', xid);
|
||
|
var privacy_active = getDB('privacy-marker', 'available');
|
||
|
|
||
|
// Get the group privacy state
|
||
|
for(g in groups) {
|
||
|
if((statusPrivacy('block', groups[g]) == 'deny') && (privacy_state != 'allow'))
|
||
|
privacy_state = 'deny';
|
||
|
}
|
||
|
|
||
|
// The subscription with this buddy is not full
|
||
|
if((subscription != 'both') || ((privacy_state == 'deny') && privacy_active)) {
|
||
|
var authorize_links = '';
|
||
|
html += '<p class="bm-authorize talk-images">';
|
||
|
|
||
|
// Link to allow to see our status
|
||
|
if((subscription == 'to') || (subscription == 'none'))
|
||
|
authorize_links += '<a href="#" class="to">' + _e("Authorize") + '</a>';
|
||
|
|
||
|
// Link to ask to see his/her status
|
||
|
if((subscription == 'from') || (subscription == 'none')) {
|
||
|
if(authorize_links)
|
||
|
authorize_links += ' / ';
|
||
|
|
||
|
authorize_links += '<a href="#" class="from">' + _e("Ask for authorization") + '</a>';
|
||
|
}
|
||
|
|
||
|
// Link to unblock this buddy
|
||
|
if((privacy_state == 'deny') && privacy_active) {
|
||
|
if(authorize_links)
|
||
|
authorize_links += ' / ';
|
||
|
|
||
|
html += '<a href="#" class="unblock">' + _e("Unblock") + '</a>';
|
||
|
}
|
||
|
|
||
|
html += authorize_links + '</p>';
|
||
|
}
|
||
|
|
||
|
// Complete the HTML code
|
||
|
var remove_links = '';
|
||
|
html += '<p class="bm-remove talk-images">';
|
||
|
remove_links = '<a href="#" class="remove">' + _e("Remove") + '</a>';
|
||
|
|
||
|
// This buddy is allowed to see our presence, we can show a "prohibit" link
|
||
|
if((subscription == 'both') || (subscription == 'from'))
|
||
|
remove_links += ' / <a href="#" class="prohibit">' + _e("Prohibit") + '</a>';
|
||
|
|
||
|
// Complete the HTML code
|
||
|
if((privacy_state != 'deny') && privacy_active) {
|
||
|
if(remove_links)
|
||
|
remove_links += ' / ';
|
||
|
|
||
|
remove_links += '<a href="#" class="block">' + _e("Block") + '</a>';
|
||
|
}
|
||
|
|
||
|
// Complete the HTML code
|
||
|
html += remove_links +
|
||
|
'</p>' +
|
||
|
'<p class="bm-rename talk-images"><label>' + _e("Rename") + '</label> <input type="text" value="' + encodeQuotes(nick) + '" /></p>';
|
||
|
|
||
|
// Only show group tool if not a gateway
|
||
|
if(!isGateway(xid))
|
||
|
html += '<p class="bm-group talk-images"><label>' + _e("Groups") + '</label> <input type="text" /></p>' +
|
||
|
'<div class="bm-choose">' +
|
||
|
'<div></div>' +
|
||
|
'</div>';
|
||
|
|
||
|
// Close the DOM element
|
||
|
html += '<a href="#" class="save">' + _e("Save") + '</a>' +
|
||
|
'</div>';
|
||
|
|
||
|
// We update the DOM elements
|
||
|
$(path + 'pep-infos').replaceWith(html);
|
||
|
|
||
|
// Gets all the existing groups
|
||
|
var all_groups = getAllGroups();
|
||
|
var all_groups_dom = '';
|
||
|
|
||
|
for(a in all_groups) {
|
||
|
// Current group
|
||
|
var all_groups_current = all_groups[a];
|
||
|
|
||
|
// Is the current group checked?
|
||
|
var checked = '';
|
||
|
|
||
|
if(existArrayValue(groups, all_groups_current))
|
||
|
checked = ' checked="true"';
|
||
|
|
||
|
// Add the current group HTML
|
||
|
all_groups_dom += '<label><input type="checkbox" data-group="' + escape(all_groups_current) + '"' + checked + ' /><span>' + all_groups_current.htmlEnc() + '</span></label>';
|
||
|
}
|
||
|
|
||
|
// Prepend this in the DOM
|
||
|
var bm_choose = path + 'manage-infos div.bm-choose';
|
||
|
|
||
|
$(bm_choose).prepend(all_groups_dom);
|
||
|
|
||
|
// Apply the editing input events
|
||
|
applyBuddyInput(xid);
|
||
|
}
|
||
|
|
||
|
// Updates the roster items
|
||
|
function sendRoster(xid, subscription, name, group) {
|
||
|
// We send the new buddy name
|
||
|
var iq = new JSJaCIQ();
|
||
|
iq.setType('set');
|
||
|
|
||
|
var iqQuery = iq.setQuery(NS_ROSTER);
|
||
|
var item = iqQuery.appendChild(iq.buildNode('item', {'xmlns': NS_ROSTER, 'jid': xid}));
|
||
|
|
||
|
// Any subscription?
|
||
|
if(subscription)
|
||
|
item.setAttribute('subscription', subscription);
|
||
|
|
||
|
// Any name?
|
||
|
if(name)
|
||
|
item.setAttribute('name', name);
|
||
|
|
||
|
// Any group?
|
||
|
if(group && group.length) {
|
||
|
for(i in group)
|
||
|
item.appendChild(iq.buildNode('group', {'xmlns': NS_ROSTER}, group[i]));
|
||
|
}
|
||
|
|
||
|
con.send(iq);
|
||
|
|
||
|
logThis('Roster item sent: ' + xid, 3);
|
||
|
}
|
||
|
|
||
|
// Adapts the roster height, depending of the window size
|
||
|
function adaptRoster() {
|
||
|
// Process the new height
|
||
|
var new_height = $('#left-content').height() - $('#my-infos').height() - 97;
|
||
|
|
||
|
// New height too small
|
||
|
if(new_height < 211)
|
||
|
new_height = 211;
|
||
|
|
||
|
// Apply the new height
|
||
|
$('#buddy-list .content').css('height', new_height);
|
||
|
}
|
||
|
|
||
|
// Gets all the buddies in our roster
|
||
|
function getAllBuddies() {
|
||
|
var buddies = new Array();
|
||
|
|
||
|
$('#buddy-list .buddy').each(function() {
|
||
|
var xid = unescape($(this).attr('data-xid'));
|
||
|
|
||
|
if(xid)
|
||
|
buddies.push(xid);
|
||
|
});
|
||
|
|
||
|
return buddies;
|
||
|
}
|
||
|
|
||
|
// Gets the user gateways
|
||
|
function getGateways() {
|
||
|
// New array
|
||
|
var gateways = new Array();
|
||
|
var buddies = getAllBuddies();
|
||
|
|
||
|
// Get the gateways
|
||
|
for(c in buddies) {
|
||
|
if(isGateway(buddies[c]))
|
||
|
gateways.push(buddies[c]);
|
||
|
}
|
||
|
|
||
|
return gateways;
|
||
|
}
|
||
|
|
||
|
// Define a global var for buddy list all buddies displayed
|
||
|
var BLIST_ALL = false;
|
||
|
|
||
|
// Plugin launcher
|
||
|
function launchRoster() {
|
||
|
// Filtering tool
|
||
|
var iFilter = $('#buddy-list .filter input');
|
||
|
var aFilter = $('#buddy-list .filter a');
|
||
|
|
||
|
iFilter.placeholder()
|
||
|
|
||
|
.blur(function() {
|
||
|
// Nothing is entered, put the placeholder instead
|
||
|
if(!trim($(this).val()))
|
||
|
aFilter.hide();
|
||
|
else
|
||
|
aFilter.show();
|
||
|
})
|
||
|
|
||
|
.keyup(function(e) {
|
||
|
funnelFilterBuddySearch(e.keyCode);
|
||
|
});
|
||
|
|
||
|
aFilter.click(function() {
|
||
|
// Reset the input
|
||
|
$(this).hide();
|
||
|
iFilter.val('');
|
||
|
iFilter.placeholder();
|
||
|
|
||
|
// Security: show all the groups, empty or not
|
||
|
$('#buddy-list .one-group').show();
|
||
|
|
||
|
// Reset the filtering tool
|
||
|
resetFilterBuddySearch();
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
// When the user click on the add button, show the contact adding tool
|
||
|
$('#buddy-list .foot .add').click(function() {
|
||
|
// Yet displayed?
|
||
|
if(exists('#buddy-conf-add'))
|
||
|
return closeBubbles();
|
||
|
|
||
|
// Add the bubble
|
||
|
showBubble('#buddy-conf-add');
|
||
|
|
||
|
// Append the content
|
||
|
$('#buddy-list .buddy-list-add').append(
|
||
|
'<div id="buddy-conf-add" class="buddy-conf-item bubble removable">' +
|
||
|
'<div class="buddy-conf-subarrow talk-images"></div>' +
|
||
|
|
||
|
'<div class="buddy-conf-subitem">' +
|
||
|
'<p class="buddy-conf-p">' + _e("Add a friend") + '</p>' +
|
||
|
|
||
|
'<label><span>' + _e("Address") + '</span><input type="text" class="buddy-conf-input add-contact-jid" required="" /></label>' +
|
||
|
'<label><span>' + _e("Name") + '</span><input type="text" class="buddy-conf-input add-contact-name" /></label>' +
|
||
|
'<label>' +
|
||
|
'<span>' + _e("Gateway") + '</span>' +
|
||
|
'<select class="buddy-conf-select add-contact-gateway">' +
|
||
|
'<option value="none" selected="">' + _e("None") + '</option>' +
|
||
|
'</select>' +
|
||
|
'</label>' +
|
||
|
'<span class="add-contact-name-get">' + _e("Getting the name...") + '</span>' +
|
||
|
|
||
|
'<p class="buddy-conf-text">' +
|
||
|
'<a href="#" class="buddy-conf-add-search">' + _e("Search a friend") + '</a>' +
|
||
|
'</p>' +
|
||
|
'</div>' +
|
||
|
'</div>'
|
||
|
);
|
||
|
|
||
|
// Add the gateways
|
||
|
var gateways = getGateways();
|
||
|
|
||
|
// Any gateway?
|
||
|
if(gateways.length) {
|
||
|
// Append the gateways
|
||
|
for(i in gateways)
|
||
|
$('.add-contact-gateway').append('<option value="' + escape(gateways[i]) + '">' + gateways[i].htmlEnc() + '</option>');
|
||
|
|
||
|
// Show the gateway selector
|
||
|
$('.add-contact-gateway').parent().show();
|
||
|
}
|
||
|
|
||
|
// No gateway?
|
||
|
else
|
||
|
$('.add-contact-gateway').parent().hide();
|
||
|
|
||
|
// Blur event on the add contact input
|
||
|
$('.add-contact-jid').blur(function() {
|
||
|
// Read the value
|
||
|
var value = trim($(this).val());
|
||
|
|
||
|
// Try to catch the buddy name
|
||
|
if(value && !trim($('.add-contact-name').val()) && ($('.add-contact-gateway').val() == 'none')) {
|
||
|
// User XID
|
||
|
var xid = generateXID(value, 'chat');
|
||
|
|
||
|
// Notice for the user
|
||
|
$('.add-contact-name-get').attr('data-for', escape(xid)).show();
|
||
|
|
||
|
// Request the user vCard
|
||
|
getAddUserName(xid);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// When a key is pressed...
|
||
|
$('#buddy-conf-add input, #buddy-conf-add select').keyup(function(e) {
|
||
|
// Enter : continue
|
||
|
if(e.keyCode == 13) {
|
||
|
// Get the values
|
||
|
var xid = trim($('.add-contact-jid').val());
|
||
|
var name = trim($('.add-contact-name').val());
|
||
|
var gateway = unescape($('.add-contact-gateway').val());
|
||
|
|
||
|
// Generate the XID to add
|
||
|
if((gateway != 'none') && xid)
|
||
|
xid = xid.replace(/@/g, '%') + '@' + gateway;
|
||
|
else
|
||
|
xid = generateXID(xid, 'chat');
|
||
|
|
||
|
// Submit the form
|
||
|
if(xid && (xid != getXID()))
|
||
|
addThisContact(xid, name);
|
||
|
else
|
||
|
$(document).oneTime(10, function() {
|
||
|
$('.add-contact-jid').addClass('please-complete').focus();
|
||
|
});
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Escape : quit
|
||
|
if(e.keyCode == 27)
|
||
|
closeBubbles();
|
||
|
});
|
||
|
|
||
|
// Click event on search link
|
||
|
$('.buddy-conf-add-search').click(function() {
|
||
|
closeBubbles();
|
||
|
return openDirectory();
|
||
|
});
|
||
|
|
||
|
// Focus on the input
|
||
|
$(document).oneTime(10, function() {
|
||
|
$('.add-contact-jid').focus();
|
||
|
});
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
// When the user click on the join button, show the chat joining tool
|
||
|
$('#buddy-list .foot .join').click(function() {
|
||
|
// Yet displayed?
|
||
|
if(exists('#buddy-conf-join'))
|
||
|
return closeBubbles();
|
||
|
|
||
|
// Add the bubble
|
||
|
showBubble('#buddy-conf-join');
|
||
|
|
||
|
// Append the content
|
||
|
$('#buddy-list .buddy-list-join').append(
|
||
|
'<div id="buddy-conf-join" class="buddy-conf-item bubble removable">' +
|
||
|
'<div class="buddy-conf-subarrow talk-images"></div>' +
|
||
|
|
||
|
'<div class="buddy-conf-subitem search">' +
|
||
|
'<p class="buddy-conf-p" style="margin-bottom: 0;">' + _e("Join a chat") + '</p>' +
|
||
|
|
||
|
'<input type="text" class="buddy-conf-input join-jid" required="" />' +
|
||
|
'<select class="buddy-conf-select buddy-conf-join-select join-type">' +
|
||
|
'<option value="chat" selected="">' + _e("Chat") + '</option>' +
|
||
|
'<option value="groupchat">' + _e("Groupchat") + '</option>' +
|
||
|
'</select>' +
|
||
|
'</div>' +
|
||
|
'</div>'
|
||
|
);
|
||
|
|
||
|
// Input vars
|
||
|
var destination = '#buddy-conf-join .search';
|
||
|
var dHovered = destination + ' ul li.hovered:first';
|
||
|
|
||
|
// When a key is pressed...
|
||
|
$('#buddy-conf-join input, #buddy-conf-join select').keyup(function(e) {
|
||
|
// Enter: continue
|
||
|
if(e.keyCode == 13) {
|
||
|
// Select something from the search
|
||
|
if(exists(dHovered))
|
||
|
addBuddySearch(destination, $(dHovered).attr('data-xid'));
|
||
|
|
||
|
// Join something
|
||
|
else {
|
||
|
var xid = trim($('.join-jid').val());
|
||
|
var type = $('.buddy-conf-join-select').val();
|
||
|
|
||
|
if(xid && type) {
|
||
|
// Generate a correct XID
|
||
|
xid = generateXID(xid, type);
|
||
|
|
||
|
// Not me
|
||
|
if(xid != getXID()) {
|
||
|
// Update some things
|
||
|
$('.join-jid').removeClass('please-complete');
|
||
|
closeBubbles();
|
||
|
|
||
|
// Create a new chat
|
||
|
checkChatCreate(xid, type);
|
||
|
}
|
||
|
|
||
|
else
|
||
|
$('.join-jid').addClass('please-complete');
|
||
|
}
|
||
|
|
||
|
else
|
||
|
$('.join-jid').addClass('please-complete');
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Escape: quit
|
||
|
else if(e.keyCode == 27)
|
||
|
closeBubbles();
|
||
|
|
||
|
// Buddy search?
|
||
|
else if($('.buddy-conf-join-select').val() == 'chat') {
|
||
|
// New buddy search
|
||
|
if((e.keyCode != 40) && (e.keyCode != 38))
|
||
|
createBuddySearch(destination);
|
||
|
|
||
|
// Navigating with keyboard in the results
|
||
|
arrowsBuddySearch(e, destination);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Buddy search lost focus
|
||
|
$('#buddy-conf-join input').blur(function() {
|
||
|
if(!$(destination + ' ul').attr('mouse-hover'))
|
||
|
resetBuddySearch(destination);
|
||
|
});
|
||
|
|
||
|
// Re-focus on the text input
|
||
|
$('#buddy-conf-join select').change(function() {
|
||
|
$(document).oneTime(10, function() {
|
||
|
$('#buddy-conf-join input').focus();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
// We focus on the input
|
||
|
$(document).oneTime(10, function() {
|
||
|
$('#buddy-conf-join .join-jid').focus();
|
||
|
});
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
// When the user click on the groupchat button, show the groupchat menu
|
||
|
$('#buddy-list .foot .groupchat').click(function() {
|
||
|
// Yet displayed?
|
||
|
if(exists('#buddy-conf-groupchat'))
|
||
|
return closeBubbles();
|
||
|
|
||
|
// Add the bubble
|
||
|
showBubble('#buddy-conf-groupchat');
|
||
|
|
||
|
// Append the content
|
||
|
$('#buddy-list .buddy-list-groupchat').append(
|
||
|
'<div id="buddy-conf-groupchat" class="buddy-conf-item bubble removable">' +
|
||
|
'<div class="buddy-conf-subarrow talk-images"></div>' +
|
||
|
|
||
|
'<div class="buddy-conf-subitem">' +
|
||
|
'<p class="buddy-conf-p">' + _e("Your groupchats") + '</p>' +
|
||
|
|
||
|
'<select name="groupchat-join" class="buddy-conf-select buddy-conf-groupchat-select"></select>' +
|
||
|
|
||
|
'<p class="buddy-conf-text">' +
|
||
|
'- <a href="#" class="buddy-conf-groupchat-edit">' + _e("Manage your favorite groupchats") + '</a>' +
|
||
|
'</p>' +
|
||
|
'</div>' +
|
||
|
'</div>'
|
||
|
);
|
||
|
|
||
|
// When the user wants to edit his groupchat favorites
|
||
|
$('.buddy-conf-groupchat-edit').click(function() {
|
||
|
openFavorites();
|
||
|
closeBubbles();
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
// Change event
|
||
|
$('.buddy-conf-groupchat-select').change(function() {
|
||
|
var groupchat = trim($(this).val());
|
||
|
|
||
|
if(groupchat != 'none') {
|
||
|
// We hide the bubble
|
||
|
closeBubbles();
|
||
|
|
||
|
// Create the chat
|
||
|
checkChatCreate(groupchat, 'groupchat');
|
||
|
|
||
|
// We reset the select value
|
||
|
$(this).val('none');
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Load the favorites
|
||
|
loadFavorites();
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
// When the user click on the more button, show the more menu
|
||
|
$('#buddy-list .foot .more').click(function() {
|
||
|
// Yet displayed?
|
||
|
if(exists('#buddy-conf-more'))
|
||
|
return closeBubbles();
|
||
|
|
||
|
// Add the bubble
|
||
|
showBubble('#buddy-conf-more');
|
||
|
|
||
|
// Append the content
|
||
|
$('#buddy-list .buddy-list-more').append(
|
||
|
'<div id="buddy-conf-more" class="buddy-conf-item bubble removable">' +
|
||
|
'<div class="buddy-conf-subarrow talk-images"></div>' +
|
||
|
|
||
|
'<div class="buddy-conf-subitem">' +
|
||
|
'<p class="buddy-conf-p">' + _e("More stuff") + '</p>' +
|
||
|
|
||
|
'<p class="buddy-conf-text">' +
|
||
|
'- <a href="#" class="buddy-conf-more-display-unavailable">' + _e("Show all friends") + '</a>' +
|
||
|
'<a href="#" class="buddy-conf-more-display-available">' + _e("Only show connected friends") + '</a>' +
|
||
|
'</p>' +
|
||
|
|
||
|
'<p class="buddy-conf-text archives-hidable">' +
|
||
|
'- <a href="#" class="buddy-conf-more-archives">' + _e("Message archives") + '</a>' +
|
||
|
'</p>' +
|
||
|
|
||
|
'<p class="buddy-conf-text privacy-hidable">' +
|
||
|
'- <a href="#" class="buddy-conf-more-privacy">' + _e("Privacy") + '</a>' +
|
||
|
'</p>' +
|
||
|
|
||
|
'<p class="buddy-conf-text">' +
|
||
|
'- <a href="#" class="buddy-conf-more-service-disco">' + _e("Service discovery") + '</a>' +
|
||
|
'</p>' +
|
||
|
|
||
|
'<p class="buddy-conf-text commands-hidable"">' +
|
||
|
'- <a href="#" class="buddy-conf-more-commands">' + _e("Commands") + '</a>' +
|
||
|
'</p>' +
|
||
|
'</div>' +
|
||
|
'</div>'
|
||
|
);
|
||
|
|
||
|
// Close bubble when link clicked
|
||
|
$('#buddy-conf-more a').click(function() {
|
||
|
closeBubbles();
|
||
|
});
|
||
|
|
||
|
// When the user wants to display all his buddies
|
||
|
$('.buddy-conf-more-display-unavailable').click(function() {
|
||
|
showAllBuddies('roster');
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
// When the user wants to display only online buddies
|
||
|
$('.buddy-conf-more-display-available').click(function() {
|
||
|
showOnlineBuddies('roster');
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
// When the user click on the archives link
|
||
|
$('.buddy-conf-more-archives').click(openArchives);
|
||
|
|
||
|
// When the user click on the privacy link
|
||
|
$('.buddy-conf-more-privacy').click(openPrivacy);
|
||
|
|
||
|
// When the user click on the service discovery link
|
||
|
$('.buddy-conf-more-service-disco').click(openDiscovery);
|
||
|
|
||
|
// When the user click on the command link
|
||
|
$('.buddy-conf-more-commands').click(function() {
|
||
|
serverAdHoc(con.domain);
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
// Manage the displayed links
|
||
|
if(BLIST_ALL) {
|
||
|
$('.buddy-conf-more-display-unavailable').hide();
|
||
|
$('.buddy-conf-more-display-available').show();
|
||
|
}
|
||
|
|
||
|
if(enabledArchives() || enabledArchives('auto') || enabledArchives('manual') || enabledArchives('manage'))
|
||
|
$('.buddy-conf-more-archives').parent().show();
|
||
|
|
||
|
if(enabledCommands())
|
||
|
$('.buddy-conf-more-commands').parent().show();
|
||
|
|
||
|
if(getDB('privacy-marker', 'available'))
|
||
|
$('.buddy-conf-more-privacy').parent().show();
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
// When the user scrolls the buddy list
|
||
|
$('#buddy-list .content').scroll(function() {
|
||
|
// Close the opened buddy infos bubble
|
||
|
closeBubbles();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Window resize event handler
|
||
|
$(window).resize(adaptRoster);
|