3 Jappix - An open social platform
4 These are the notification JS scripts for Jappix
6 -------------------------------------------------
10 Last revision: 27/08/11
14 // Resets the notifications alert if no one remaining
15 function closeEmptyNotifications() {
16 if(!$('.one-notification').size())
20 // Checks if there are pending notifications
21 function checkNotifications() {
22 // Define the selectors
23 var notif = '#top-content .notifications';
24 var nothing = '.notifications-content .nothing';
25 var empty = '.notifications-content .empty';
27 // Get the notifications number
28 var number = $('.one-notification').size();
30 // Remove the red notify bubble
31 $(notif + ' .notify').remove();
35 $(notif).prepend('<div class="notify one-counter" data-counter="' + number + '">' + number + '</div>');
45 // Purge the social inbox node
49 // Update the page title
53 // Creates a new notification
54 function newNotification(type, from, data, body, id, inverse) {
58 // Generate an ID hash
60 var id = hex_md5(type + from);
62 // Generate the text to be displayed
63 var text, action, code;
64 var yes_path = 'href="#"';
68 var hash = hex_md5(from);
72 // Get the name to display
73 var display_name = data[1];
76 display_name = data[0];
78 text = '<b>' + display_name.htmlEnc() + '</b> ' + _e("would like to add you as a friend.") + ' ' + _e("Do you accept?");
83 text = '<b>' + getBuddyName(from).htmlEnc() + '</b> ' + _e("would like you to join this chatroom:") + ' <em>' + data[0].htmlEnc() + '</em> ' + _e("Do you accept?");
88 text = '<b>' + from.htmlEnc() + '</b> ' + _e("would like to get authorization.") + ' ' + _e("Do you accept?");
93 yes_path = 'href="' + encodeQuotes(data[1]) + '" target="_blank"';
95 text = '<b>' + getBuddyName(from).htmlEnc() + '</b> ' + printf(_e("would like to send you a file: “%s”.").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>') + ' ' + _e("Do you accept?");
100 text = '<b>' + getBuddyName(from).htmlEnc() + '</b> ' + printf(_e("has received a file exchange request: “%s”.").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>');
105 text = '<b>' + getBuddyName(from).htmlEnc() + '</b> ' + printf(_e("has accepted to received your file: “%s”.").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>');
110 text = '<b>' + getBuddyName(from).htmlEnc() + '</b> ' + printf(_e("has rejected to receive your file: “%s”.").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>');
115 text = '<b>' + getBuddyName(from).htmlEnc() + '</b> ' + printf(_e("could not receive your file: “%s”.").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>');
120 text = printf(_e("Do you want to see the friends %s suggests you?").htmlEnc(), '<b>' + getBuddyName(from).htmlEnc() + '</b>');
125 text = '<b>' + data[0].htmlEnc() + '</b> ' + printf(_e("commented an item you follow: “%s”.").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>');
130 text = '<b>' + data[0].htmlEnc() + '</b> ' + printf(_e("liked your post: “%s”.").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>');
135 text = '<b>' + data[0].htmlEnc() + '</b> ' + printf(_e("quoted you somewhere: “%s”.").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>');
140 text = '<b>' + data[0].htmlEnc() + '</b> ' + printf(_e("published on your wall: “%s”.").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>');
145 text = '<b>' + data[0].htmlEnc() + '</b> ' + printf(_e("tagged you in a photo (%s).").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>');
150 text = '<b>' + data[0].htmlEnc() + '</b> ' + printf(_e("tagged you in a video (%s).").htmlEnc(), '<em>' + truncate(body, 25).htmlEnc() + '</em>');
163 if((type == 'send_pending') || (type == 'send_accept') || (type == 'send_reject') || (type == 'send_fail') || (type == 'comment') || (type == 'like') || (type == 'quote') || (type == 'wall') || (type == 'photo') || (type == 'video')) {
164 action = '<a href="#" class="no">' + _e("Hide") + '</a>';
167 if((type == 'comment') && data[2])
168 action = '<a href="#" class="yes">' + _e("Show") + '</a>' + action;
172 action = '<a ' + yes_path + ' class="yes">' + _e("Yes") + '</a><a href="#" class="no">' + _e("No") + '</a>';
175 // We display the notification
176 if(!exists('.notifications-content .' + id)) {
177 // We create the html markup depending of the notification type
178 code = '<div class="one-notification ' + id + ' ' + hash + '" title="' + encodeQuotes(body) + '" data-type="' + encodeQuotes(type) + '">' +
179 '<div class="avatar-container">' +
180 '<img class="avatar" src="' + './img/others/default-avatar.png' + '" alt="" />' +
183 '<p class="notification-text">' + text + '</p>' +
184 '<p class="notification-actions">' +
185 '<span class="talk-images" />' +
192 $('.notifications-content .nothing').before(code);
194 $('.notifications-content .empty').after(code);
196 // Play a sound to alert the user
199 // The yes click function
200 $('.' + id + ' a.yes').click(function() {
201 actionNotification(type, data, 'yes', id);
203 if(($(this).attr('href') == '#') && ($(this).attr('target') != '_blank'))
207 // The no click function
208 $('.' + id + ' a.no').click(function() {
209 return actionNotification(type, data, 'no', id);
212 // Get the user avatar
213 getAvatar(from, 'cache', 'true', 'forget');
217 // We tell the user he has a new pending notification
218 checkNotifications();
220 logThis('New notification: ' + from, 3);
223 // Performs an action on a given notification
224 function actionNotification(type, data, value, id) {
225 // We launch a function depending of the type
226 if((type == 'subscribe') && (value == 'yes'))
227 acceptSubscribe(data[0], data[1]);
229 else if((type == 'subscribe') && (value == 'no'))
230 sendSubscribe(data[0], 'unsubscribed');
232 else if((type == 'invite_room') && (value == 'yes'))
233 checkChatCreate(data[0], 'groupchat');
235 else if(type == 'request')
236 requestReply(value, data[0]);
238 if((type == 'send') && (value == 'yes'))
239 replyOOB(data[0], data[3], 'accept', data[2], data[4]);
241 else if((type == 'send') && (value == 'no'))
242 replyOOB(data[0], data[3], 'reject', data[2], data[4]);
244 else if((type == 'rosterx') && (value == 'yes'))
245 openRosterX(data[0]);
247 else if((type == 'comment') || (type == 'like') || (type == 'quote') || (type == 'wall') || (type == 'photo') || (type == 'video')) {
249 // Get the microblog item
250 fromInfosMicroblog(data[2]);
253 $('#channel .top.individual').append('<input type="hidden" name="comments" value="' + encodeQuotes(data[1]) + '" />');
256 removeNotification(data[3]);
259 // We remove the notification
260 $('.notifications-content .' + id).remove();
262 // We check if there's any other pending notification
263 closeEmptyNotifications();
264 checkNotifications();
269 // Clear the social notifications
270 function clearNotifications() {
271 // Remove notifications
272 $('.one-notification').remove();
275 closeEmptyNotifications();
276 checkNotifications();
281 // Gets the pending social notifications
282 function getNotifications() {
283 var iq = new JSJaCIQ();
286 var pubsub = iq.appendNode('pubsub', {'xmlns': NS_PUBSUB});
287 pubsub.appendChild(iq.buildNode('items', {'node': NS_URN_INBOX, 'xmlns': NS_PUBSUB}));
289 con.send(iq, handleNotifications);
291 logThis('Getting social notifications...');
294 // Handles the social notifications
295 function handleNotifications(iq) {
297 if((iq.getType() == 'error') && $(iq.getNode()).find('item-not-found').size()) {
298 // The node may not exist, create it!
299 setupMicroblog('', NS_URN_INBOX, '1', '1000000', 'whitelist', 'open', true);
301 logThis('Error while getting social notifications, trying to reconfigure the Pubsub node!', 2);
305 var items = $(iq.getNode()).find('item');
307 // Should we inverse?
310 if(items.size() == 1)
313 // Parse notifications
314 items.each(function() {
315 // Parse the current item
316 var current_item = $(this).attr('id');
317 var current_type = $(this).find('link[rel=via]:first').attr('title');
318 var current_href = $(this).find('link[rel=via]:first').attr('href');
319 var current_parent_href = $(this).find('link[rel=related]:first').attr('href');
320 var current_xid = explodeThis(':', $(this).find('source author uri').text(), 1);
321 var current_name = $(this).find('source author name').text();
322 var current_text = $(this).find('content[type=text]:first').text();
323 var current_bname = getBuddyName(current_xid);
324 var current_id = hex_md5(current_type + current_xid + current_href + current_text);
326 // Choose the good name!
327 if(!current_name || (current_bname != getXIDNick(current_xid)))
328 current_name = current_bname;
331 newNotification(current_type, current_xid, [current_name, current_href, current_parent_href, current_item], current_text, current_id, inverse);
334 logThis(items.size() + ' social notification(s) got!', 3);
337 // Sends a social notification
338 function sendNotification(xid, type, href, text, parent) {
340 var id = hex_md5(xid + text + getTimeStamp());
343 var iq = new JSJaCIQ();
348 var pubsub = iq.appendNode('pubsub', {'xmlns': NS_PUBSUB});
349 var publish = pubsub.appendChild(iq.buildNode('publish', {'node': NS_URN_INBOX, 'xmlns': NS_PUBSUB}));
350 var item = publish.appendChild(iq.buildNode('item', {'id': id, 'xmlns': NS_PUBSUB}));
351 var entry = item.appendChild(iq.buildNode('entry', {'xmlns': NS_ATOM}));
353 // Notification author (us)
354 var Source = entry.appendChild(iq.buildNode('source', {'xmlns': NS_ATOM}));
355 var author = Source.appendChild(iq.buildNode('author', {'xmlns': NS_ATOM}));
356 author.appendChild(iq.buildNode('name', {'xmlns': NS_ATOM}, getName()));
357 author.appendChild(iq.buildNode('uri', {'xmlns': NS_ATOM}, 'xmpp:' + getXID()));
359 // Notification content
360 entry.appendChild(iq.buildNode('published', {'xmlns': NS_ATOM}, getXMPPTime('utc')));
361 entry.appendChild(iq.buildNode('content', {'type': 'text', 'xmlns': NS_ATOM}, text));
362 entry.appendChild(iq.buildNode('link', {'rel': 'via', 'title': type, 'href': href, 'xmlns': NS_ATOM}));
365 if(parent && parent[0] && parent[1] && parent[2]) {
366 // Generate the parent XMPP URI
367 var parent_href = 'xmpp:' + parent[0] + '?;node=' + encodeURIComponent(parent[1]) + ';item=' + encodeURIComponent(parent[2]);
369 entry.appendChild(iq.buildNode('link', {'rel': 'related', 'href': parent_href, 'xmlns': NS_ATOM}));
374 logThis('Sending a social notification to ' + xid + ' (type: ' + type + ')...');
377 // Removes a social notification
378 function removeNotification(id) {
379 var iq = new JSJaCIQ();
382 var pubsub = iq.appendNode('pubsub', {'xmlns': NS_PUBSUB});
383 var retract = pubsub.appendChild(iq.buildNode('retract', {'node': NS_URN_INBOX, 'xmlns': NS_PUBSUB}));
384 retract.appendChild(iq.buildNode('item', {'id': id, 'xmlns': NS_PUBSUB}));
389 // Purge the social notifications
390 function purgeNotifications() {
391 var iq = new JSJaCIQ();
394 var pubsub = iq.appendNode('pubsub', {'xmlns': NS_PUBSUB_OWNER});
395 pubsub.appendChild(iq.buildNode('purge', {'node': NS_URN_INBOX, 'xmlns': NS_PUBSUB_OWNER}));
402 // Adapt the notifications bubble max-height
403 function adaptNotifications() {
404 // Process the new height
405 var max_height = $('#right-content').height() - 22;
407 // New height too small
411 // Apply the new height
412 $('.notifications-content .tools-content-subitem').css('max-height', max_height);
416 function launchNotifications() {
417 // Adapt the notifications height
418 adaptNotifications();
421 // Window resize event handler
422 $(window).resize(adaptNotifications);