'
);
// 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
Bubble.close();
}
// We must show the buddies
else {
group_toggle.removeClass('plus').addClass('minus');
group.show();
}
return false;
});
}
// Initialize the HTML code
var name_code = '
' + dName.htmlEnc() + '
';
var presence_code = '
' + Common._e("Unavailable") + '
';
var html = '
' +
'
';
// Display avatar if not gateway
if(!is_gateway) {
html += '
' +
'' +
'
';
}
html += '
';
// Special gateway code
if(is_gateway) {
html += presence_code +
name_code;
} else {
html += name_code +
presence_code;
}
html += '
';
// Create the DOM element for this buddy
$(groupBuddies).append(html);
// Apply the hover event
self.applyBuddyHover(dXID, dXIDHash, dName, dSubscription, dGroup, groupHash);
}
});
// Click event on this buddy
$('#roster .' + dXIDHash + ' .buddy-click').click(function() {
return Chat.checkCreate(dXID, 'chat');
});
// We get the user presence if necessary
if(dMode == 'presence') {
Presence.funnel(dXID, dXIDHash);
}
// If the buddy must be shown
if(self.blist_all) {
$('#roster .' + dXIDHash).show();
}
}
// We update our groups
if(!Search.search_filtered) {
self.updateGroups();
} else {
Search.funnelFilterBuddy();
}
} catch(e) {
Console.error('Roster.display', e);
}
};
/**
* Applies the buddy editing input events
* @public
* @param {string} xid
* @return {undefined}
*/
self.applyBuddyInput = function(xid) {
try {
// Initialize
var path = '#roster .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
self.send(xid, '', $.trim($(rename).val()), self.thisBuddyGroups(xid));
// Remove the buddy editor
Bubble.close();
return false;
}
});
$(group).keyup(function(e) {
if(e.keyCode == 13) {
// Empty input?
if(!$.trim($(this).val())) {
// Send the item
self.send(xid, '', $.trim($(rename).val()), self.thisBuddyGroups(xid));
// Remove the buddy editor
Bubble.close();
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('');
}
// 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() {
Bubble.close();
Presence.sendSubscribe(xid, 'subscribed');
return false;
});
$(manage_infos + ' p.bm-authorize a.from').click(function() {
Bubble.close();
Presence.sendSubscribe(xid, 'subscribe');
return false;
});
$(manage_infos + ' p.bm-authorize a.unblock').click(function() {
Bubble.close();
// Update privacy settings
Privacy.push('block', ['jid'], [xid], ['allow'], [false], [true], [true], [true], '', 'roster');
$(path).removeClass('blocked');
// Enable the "block" list
Privacy.change('block', 'active');
Privacy.change('block', 'default');
// Send an available presence
Presence.send(xid, 'available', Presence.getUserShow(), getUserStatus());
return false;
});
$(manage_infos + ' p.bm-remove a.remove').click(function() {
Bubble.close();
// First unregister if gateway
if(Common.isGateway(xid)) {
self.unregisterGateway(xid);
}
// Then send roster removal query
self.send(xid, 'remove');
return false;
});
$(manage_infos + ' p.bm-remove a.prohibit').click(function() {
Bubble.close();
Presence.sendSubscribe(xid, 'unsubscribed');
return false;
});
$(manage_infos + ' p.bm-remove a.block').click(function() {
Bubble.close();
// Update privacy settings
Privacy.push('block', ['jid'], [xid], ['deny'], [false], [true], [true], [true], '', 'roster');
$(path).addClass('blocked');
// Enable the "block" list
Privacy.change('block', 'active');
Privacy.change('block', 'default');
// Send an unavailable presence
Presence.send(xid, 'unavailable');
// Remove the user presence
var db_regex = new RegExp(('^' + Connection.desktop_hash + '_') + 'presence' + ('_(.+)'));
for(var i = 0; i < DataStore.storageDB.length; i++) {
// Get the pointer values
var current = DataStore.storageDB.key(i);
// If the pointer is on a stored presence
if(current.match(db_regex)) {
if(Common.bareXID(RegExp.$1) == xid) {
DataStore.storageDB.removeItem(current);
}
}
}
// Manage his new presence
Presence.funnel(xid, hex_md5(xid));
return false;
});
$(manage_infos + ' a.save').click(function() {
// Send the item
self.send(xid, '', $.trim($(rename).val()), self.thisBuddyGroups(xid));
// Remove the buddy editor
Bubble.close();
return false;
});
} catch(e) {
Console.error('Roster.applyBuddyInput', e);
}
};
/**
* Applies the buddy editing hover events
* @public
* @param {string} xid
* @param {string} hash
* @param {string} nick
* @param {string} subscription
* @param {object} groups
* @param {string} group_hash
* @return {undefined}
*/
self.applyBuddyHover = function(xid, hash, nick, subscription, groups, group_hash) {
try {
// Generate the values
var bPath = '#roster .' + group_hash + ' .buddy[data-xid="' + escape(xid) + '"]';
var iPath = bPath + ' .buddy-infos';
// Apply the hover event
$(bPath).hover(function() {
// Another bubble exist
if(Common.exists('#roster .buddy-infos')) {
return false;
}
$(bPath).oneTime(200, function() {
// Another bubble exist
if(Common.exists('#roster .buddy-infos')) {
return false;
}
// Add this bubble!
Bubble.show(iPath);
// Create the buddy infos DOM element
$(bPath).append(
'
'
);
// Sets the good position
self.buddyInfosPosition(xid, group_hash);
// Get the presence
Presence.funnel(xid, hash);
// Get the PEP infos
PEP.displayAll(xid);
// Click events
$(bPath + ' .bi-view a').click(function() {
var this_sel = $(this);
// Renitialize the buddy infos
Bubble.close();
// Profile
if(this_sel.is('.profile')) {
UserInfos.open(xid);
}
// Channel
else if(this_sel.is('.channel')) {
Microblog.fromInfos(xid, hash);
}
// Command
else if(this_sel.is('.commands')) {
AdHoc.retrieve(xid);
}
return false;
});
// Jingle events
$(bPath + ' .bi-jingle a').click(function() {
var this_sel = $(this);
// Renitialize the buddy infos
Bubble.close();
// Audio call?
if(this_sel.is('.audio')) {
Jingle.start(xid, 'audio');
}
// Video call?
else if(this_sel.is('.video')) {
Jingle.start(xid, 'video');
}
return false;
});
$(bPath + ' .bi-edit a').click(function() {
self.buddyEdit(xid, nick, subscription, groups);
return false;
});
});
}, function() {
if(!Common.exists(iPath + ' .manage-infos')) {
Bubble.close();
}
$(bPath).stopTime();
});
} catch(e) {
Console.error('Roster.applyBuddyHover', e);
}
};
/**
* Sets the good buddy-infos position
* @public
* @param {string} xid
* @param {string} group_hash
* @return {undefined}
*/
self.buddyInfosPosition = function(xid, group_hash) {
try {
// Paths
var group = '#roster .' + 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(Common.isGateway(xid)) {
offset = -8;
}
// Process the position
var v_position = $(buddy).position().top + offset;
var h_position = $(buddy).width() - 10;
// Apply the top position
$(buddy_infos).css('top', v_position);
// Apply the left/right position
if($('html').attr('dir') == 'rtl') {
$(buddy_infos).css('right', h_position);
} else {
$(buddy_infos).css('left', h_position);
}
} catch(e) {
Console.error('Roster.buddyInfosPosition', e);
}
};
/**
* Generates an array of the current groups of a buddy
* @public
* @param {string} xid
* @return {undefined}
*/
self.thisBuddyGroups = function(xid) {
try {
var path = '#roster .buddy[data-xid="' + escape(xid) + '"] ';
var 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 && !Utils.existArrayValue(array, value)) {
array.push(value);
}
return array;
} catch(e) {
Console.error('Roster.thisBuddyGroups', e);
}
};
/**
* Adds a given contact to our roster
* @public
* @param {string} xid
* @param {string} name
* @return {undefined}
*/
self.addThisContact = function(xid, name) {
try {
Console.info('Add this contact: ' + xid + ', as ' + name);
// Cut the resource of this XID
xid = Common.bareXID(xid);
// If the form is complete
if(xid) {
// We send the subscription
Presence.sendSubscribe(xid, 'subscribe');
self.send(xid, '', name);
// We hide the bubble
Bubble.close();
}
} catch(e) {
Console.error('Roster.addThisContact', e);
}
};
/**
* Gets an array of all the groups in the roster
* @public
* @param {type} name
* @return {undefined}
*/
self.getAllGroups = function() {
try {
var groups = [];
$('#roster .one-group').each(function() {
var current = unescape(
$(this).attr('data-group')
);
if((current != Common._e("Unclassified")) && (current != Common._e("Gateways"))) {
groups.push(current);
}
});
return groups.sort();
} catch(e) {
Console.error('Roster.getAllGroups', e);
}
};
/**
* Edits buddy informations
* @public
* @param {string} xid
* @param {string} nick
* @param {string} subscription
* @param {object} groups
* @return {undefined}
*/
self.buddyEdit = function(xid, nick, subscription, groups) {
try {
Console.info('Buddy edit: ' + xid);
// Initialize
var path = '#roster .buddy[data-xid="' + escape(xid) + '"] .';
var html = '
';
// Get the privacy state
var privacy_state = Privacy.status('block', xid);
var privacy_active = DataStore.getDB(Connection.desktop_hash, 'privacy-marker', 'available');
// Get the group privacy state
for(var g in groups) {
if((Privacy.status('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 += '
';
// Link to allow to see our status
if((subscription == 'to') || (subscription == 'none')) {
authorize_links += '' + Common._e("Authorize") + '';
}
// Link to ask to see his/her status
if((subscription == 'from') || (subscription == 'none')) {
if(authorize_links) {
authorize_links += ' / ';
}
authorize_links += '' + Common._e("Ask for authorization") + '';
}
// Link to unblock this buddy
if((privacy_state == 'deny') && privacy_active) {
if(authorize_links) {
authorize_links += ' / ';
}
html += '' + Common._e("Unblock") + '';
}
html += authorize_links + '
';
}
// Complete the HTML code
var remove_links = '';
html += '
';
remove_links = '' + Common._e("Remove") + '';
// This buddy is allowed to see our presence, we can show a "prohibit" link
if((subscription == 'both') || (subscription == 'from')) {
remove_links += ' / ' + Common._e("Prohibit") + '';
}
// Complete the HTML code
if((privacy_state != 'deny') && privacy_active) {
if(remove_links) {
remove_links += ' / ';
}
remove_links += '' + Common._e("Block") + '';
}
// Complete the HTML code
html += remove_links +
'
' +
'
';
// Only show group tool if not a gateway
if(!Common.isGateway(xid)) {
html += '
'
);
// When the user wants to edit his groupchat favorites
$('.buddy-conf-groupchat-edit').click(function() {
Favorites.open();
Bubble.close();
return false;
});
// Change event
$('.buddy-conf-groupchat-select').change(function() {
var groupchat = $.trim($(this).val());
if(groupchat != 'none') {
// We hide the bubble
Bubble.close();
// Create the chat
Chat.checkCreate(groupchat, 'groupchat');
// We reset the select value
$(this).val('none');
}
});
// Load the favorites
Favorites.load();
return false;
});
// When the user click on the muji button, show the muji menu
$('#roster .foot .muji').click(function() {
// Yet displayed?
if(Common.exists('#buddy-conf-muji') || Call.is_ongoing()) {
return Bubble.close();
}
// Add the bubble
Bubble.show('#buddy-conf-muji');
// Append the content
$('#roster .roster-muji').append(
'
'
);
// When the user wants to launch
$('.buddy-conf-muji-conference').click(function() {
var media = $(this).attr('data-media');
var room_name = hex_md5(media + DateUtils.getTimeStamp() + Math.random());
var room = Common.generateXID(room_name, 'groupchat');
if(media && room && room_name) {
Muji.start(room, media);
}
Bubble.close();
return false;
});
return false;
});
// When the user click on the more button, show the more menu
$('#roster .foot .more').click(function() {
// Yet displayed?
if(Common.exists('#buddy-conf-more')) {
return Bubble.close();
}
// Add the bubble
Bubble.show('#buddy-conf-more');
// Append the content
$('#roster .roster-more').append(
'
'
);
// Close bubble when link clicked
$('#buddy-conf-more a').click(function() {
Bubble.close();
});
// When the user wants to display all his buddies
$('.buddy-conf-more-display-unavailable').click(function() {
Interface.showAllBuddies('roster');
return false;
});
// When the user wants to display only online buddies
$('.buddy-conf-more-display-available').click(function() {
Interface.showOnlineBuddies('roster');
return false;
});
// When the user click on the privacy link
$('.buddy-conf-more-privacy').click(Privacy.open);
// When the user click on the service discovery link
$('.buddy-conf-more-service-disco').click(Discovery.open);
// When the user click on the command link
$('.buddy-conf-more-commands').click(function() {
AdHoc.server(con.domain);
return false;
});
// Manage the displayed links
if(self.blist_all) {
$('.buddy-conf-more-display-unavailable').hide();
$('.buddy-conf-more-display-available').show();
}
if(Features.enabledCommands()) {
$('.buddy-conf-more-commands').parent().show();
}
if(DataStore.getDB(Connection.desktop_hash, 'privacy-marker', 'available')) {
$('.buddy-conf-more-privacy').parent().show();
}
return false;
});
// When the user scrolls the buddy list
$('#roster .content').scroll(function() {
// Close the opened buddy infos bubble
Bubble.close();
});
} catch(e) {
Console.error('Roster.instance', e);
}
};
/**
* Plugin launcher
* @public
* @return {undefined}
*/
self.launch = function() {
try {
// Window resize event handler
$(window).resize(self.adapt);
} catch(e) {
Console.error('Roster.launch', e);
}
};
/**
* Return class scope
*/
return self;
})();
Roster.launch();