]> git.mxchange.org Git - friendica-addons.git/blob - jappixmini/jappix/js/pep.js
Merge branch '3.6-release'
[friendica-addons.git] / jappixmini / jappix / js / pep.js
1 /*
2
3 Jappix - An open social platform
4 These are the PEP JS scripts for Jappix
5
6 -------------------------------------------------
7
8 License: AGPL
9 Author: Vanaryon
10 Last revision: 26/08/11
11
12 */
13
14 // Stores the PEP items
15 function storePEP(xid, type, value1, value2, value3, value4) {
16         // Handle the correct values
17         if(!value1)
18                 value1 = '';
19         if(!value2)
20                 value2 = '';
21         if(!value3)
22                 value3 = '';
23         if(!value4)
24                 value4 = '';
25         
26         // If one value
27         if(value1 || value2 || value3 || value4) {
28                 // Define the XML variable
29                 var xml = '<pep type="' + type + '">';
30                 
31                 // Generate the correct XML
32                 if(type == 'tune')
33                         xml += '<artist>' + value1.htmlEnc() + '</artist><title>' + value2.htmlEnc() + '</title><album>' + value3.htmlEnc() + '</album><uri>' + value4.htmlEnc() + '</uri>';
34                 else if(type == 'geoloc')
35                         xml += '<lat>' + value1.htmlEnc() + '</lat><lon>' + value2.htmlEnc() + '</lon><human>' + value3.htmlEnc() + '</human>';
36                 else
37                         xml += '<value>' + value1.htmlEnc() + '</value><text>' + value2.htmlEnc() + '</text>';
38                 
39                 // End the XML node
40                 xml += '</pep>';
41                 
42                 // Update the input with the new value
43                 setDB('pep-' + type, xid, xml);
44         }
45         
46         else
47                 removeDB('pep-' + type, xid);
48         
49         // Display the PEP event
50         displayPEP(xid, type);
51 }
52
53 // Displays a PEP item
54 function displayPEP(xid, type) {
55         // Read the target input for values
56         var value = $(XMLFromString(getDB('pep-' + type, xid)));
57         var dText;
58         var aLink = ''
59         
60         // If the PEP element exists
61         if(type) {
62                 // Get the user hash
63                 var hash = hex_md5(xid);
64                 
65                 // Initialize
66                 var fText, fValue;
67                 var dText = '';
68                 
69                 // Parse the XML for mood and activity
70                 if((type == 'mood') || (type == 'activity')) {
71                         if(value) {
72                                 var pepValue = value.find('value').text();
73                                 var pepText = value.find('text').text();
74                                 
75                                 // No value?
76                                 if(!pepValue)
77                                         pepValue = 'none';
78                                 
79                                 // Apply the good values
80                                 if(type == 'mood')
81                                         fValue = moodIcon(pepValue);
82                                 else if(type == 'activity')
83                                         fValue = activityIcon(pepValue);
84                                 if(!pepText)
85                                         fText = _e("unknown");
86                                 else
87                                         fText = pepText;
88                         }
89                         
90                         else {
91                                 if(type == 'mood')
92                                         fValue = moodIcon('undefined');
93                                 else if(type == 'activity')
94                                         fValue = activityIcon('exercising');
95                                 
96                                 fText = _e("unknown");
97                         }
98                         
99                         dText = fText;
100                         fText = fText.htmlEnc();
101                 }
102                 
103                 else if(type == 'tune') {
104                         fValue = 'tune-note';
105                         
106                         if(value) {
107                                 // Parse the tune XML
108                                 var tArtist = value.find('artist').text();
109                                 var tTitle = value.find('title').text();
110                                 var tAlbum = value.find('album').text();
111                                 var tURI = value.find('uri').text();
112                                 var fArtist, fTitle, fAlbum, fURI;
113                                 
114                                 // Apply the good values
115                                 if(!tArtist && !tAlbum && !tTitle) {
116                                         fText = _e("unknown");
117                                         dText = fText;
118                                 }
119                                 
120                                 else {
121                                         // URI element
122                                         if(!tURI)
123                                                 fURI = 'http://grooveshark.com/search?q=' + encodeURIComponent(tArtist + ' ' + tTitle + ' ' + tAlbum);
124                                         else
125                                                 fURI = tURI;
126                                         
127                                         // Artist element
128                                         if(!tArtist)
129                                                 fArtist = _e("unknown");
130                                         else
131                                                 fArtist = tArtist;
132                                         
133                                         // Title element
134                                         if(!tTitle)
135                                                 fTitle = _e("unknown");
136                                         else
137                                                 fTitle = tTitle;
138                                         
139                                         // Album element
140                                         if(!tAlbum)
141                                                 fAlbum = _e("unknown");
142                                         else
143                                                 fAlbum = tAlbum;
144                                         
145                                         // Generate the link to the title
146                                         aLink = ' href="' + fURI + '" target="_blank"';
147                                         
148                                         // Generate the text to be displayed
149                                         dText = fArtist + ' - ' + fTitle + ' (' + fAlbum + ')';
150                                         fText =  '<a' + aLink + '>' + dText + '</a>';
151                                 }
152                         }
153                         
154                         else {
155                                 fText = _e("unknown");
156                                 dText = fText;
157                         }
158                 }
159                 
160                 else if(type == 'geoloc') {
161                         fValue = 'location-world';
162                         
163                         if(value) {
164                                 // Parse the geoloc XML
165                                 var tLat = value.find('lat').text();
166                                 var tLon = value.find('lon').text();
167                                 var tHuman = value.find('human').text();
168                                 var tReal = tHuman;
169                                 
170                                 // No human location?
171                                 if(!tHuman)
172                                         tHuman = _e("See his/her position on the globe");
173                                 
174                                 // Generate the text to be displayed
175                                 if(tLat && tLon) {
176                                         aLink = ' href="http://maps.google.com/?q=' + encodeQuotes(tLat) + ',' + encodeQuotes(tLon) + '" target="_blank"';
177                                         fText = '<a' + aLink + '>' + tHuman.htmlEnc() + '</a>';
178                                         
179                                         if(tReal)
180                                                 dText = tReal;
181                                         else
182                                                 dText = tLat + '; ' + tLon;
183                                 }
184                                 
185                                 else {
186                                         fText = _e("unknown");
187                                         dText = fText;
188                                 }
189                         }
190                         
191                         else {
192                                 fText = _e("unknown");
193                                 dText = fText;
194                         }
195                 }
196                 
197                 // Apply the text to the buddy infos
198                 var this_buddy = '#buddy-list .buddy[data-xid=' + escape(xid) + ']';
199                 
200                 if(exists(this_buddy))
201                         $(this_buddy + ' .bi-' + type).replaceWith('<p class="bi-' + type + ' talk-images ' + fValue + '" title="' + encodeQuotes(dText) + '">' + fText + '</p>');
202                 
203                 // Apply the text to the buddy chat
204                 if(exists('#' + hash)) {
205                         // Selector
206                         var bc_pep = $('#' + hash + ' .bc-pep');
207                         
208                         // We remove the old PEP item
209                         bc_pep.find('a.bi-' + type).remove();
210                         
211                         // If the new PEP item is not null, create a new one
212                         if(fText != _e("unknown"))
213                                 bc_pep.prepend(
214                                         '<a' + aLink + ' class="bi-' + type + ' talk-images ' + fValue + '" title="' + encodeQuotes(dText) + '"></a>'
215                                 );
216                         
217                         // Process the new status position
218                         adaptChatPresence(hash);
219                 }
220                 
221                 // If this is the PEP values of the logged in user
222                 if(xid == getXID()) {
223                         // Change the icon/value of the target element
224                         if((type == 'mood') || (type == 'activity')) {
225                                 // Change the input value
226                                 var dVal = '';
227                                 var dAttr = pepValue;
228                                 
229                                 // Must apply default values?
230                                 if(pepValue == 'none') {
231                                         if(type == 'mood')
232                                                 dAttr = 'happy';
233                                         else
234                                                 dAttr = 'exercising';
235                                 }
236                                 
237                                 // No text?
238                                 if(dText != _e("unknown"))
239                                         dVal = dText;
240                                 
241                                 // Store this user event in our database
242                                 setDB(type + '-value', 1, dAttr);
243                                 setDB(type + '-text', 1, dVal);
244                                 
245                                 // Apply this PEP event
246                                 $('#my-infos .f-' + type + ' a.picker').attr('data-value', dAttr);
247                                 $('#my-infos .f-' + type + ' input').val(dVal);
248                                 $('#my-infos .f-' + type + ' input').placeholder();
249                         }
250                         
251                         else if((type == 'tune') || (type == 'geoloc')) {
252                                 // Reset the values
253                                 $('#my-infos .f-others a.' + type).remove();
254                                 
255                                 // Not empty?
256                                 if(dText != _e("unknown")) {
257                                         // Specific stuffs
258                                         var href, title, icon_class;
259                                         
260                                         if(type == 'tune') {
261                                                 href = fURI;
262                                                 title = dText;
263                                                 icon_class = 'tune-note';
264                                         }
265                                         
266                                         else {
267                                                 href = 'http://maps.google.com/?q=' + encodeQuotes(tLat) + ',' + encodeQuotes(tLon);
268                                                 title = _e("Where are you?") + ' (' + dText + ')';
269                                                 icon_class = 'location-world';
270                                         }
271                                         
272                                         // Must create the container?
273                                         if(!exists('#my-infos .f-others'))
274                                                 $('#my-infos .content').append('<div class="element f-others"></div>');
275                                         
276                                         // Create the element
277                                         $('#my-infos .f-others').prepend(
278                                                 '<a class="icon ' + type + '" href="' + encodeQuotes(href) + '" target="_blank" title="' + encodeQuotes(title) +  '">' + 
279                                                         '<span class="talk-images ' + icon_class + '"></span>' + 
280                                                 '</a>'
281                                         );
282                                 }
283                                 
284                                 // Empty?
285                                 else if(!exists('#my-infos .f-others a.icon'))
286                                         $('#my-infos .f-others').remove();
287                                 
288                                 // Process the buddy-list height again
289                                 adaptRoster();
290                         }
291                 }
292         }
293 }
294
295 // Changes the mood icon
296 function moodIcon(value) {
297         // The main var
298         var icon;
299         
300         // Switch the values
301         switch(value) {
302                 case 'angry':
303                 case 'cranky':
304                 case 'hot':
305                 case 'invincible':
306                 case 'mean':
307                 case 'restless':
308                 case 'serious':
309                 case 'strong':
310                         icon = 'mood-one';
311                         break;
312                 
313                 case 'contemplative':
314                 case 'happy':
315                 case 'playful':
316                         icon = 'mood-two';
317                         break;
318                 
319                 case 'aroused':
320                 case 'envious':
321                 case 'excited':
322                 case 'interested':
323                 case 'lucky':
324                 case 'proud':
325                 case 'relieved':
326                 case 'satisfied':
327                 case 'shy':
328                         icon = 'mood-three';
329                         break;
330                 
331                 case 'calm':
332                 case 'cautious':
333                 case 'contented':
334                 case 'creative':
335                 case 'humbled':
336                 case 'lonely':
337                 case 'undefined':
338                 case 'none':
339                         icon = 'mood-four';
340                         break;
341                 
342                 case 'afraid':
343                 case 'amazed':
344                 case 'confused':
345                 case 'dismayed':
346                 case 'hungry':
347                 case 'in_awe':
348                 case 'indignant':
349                 case 'jealous':
350                 case 'lost':
351                 case 'offended':
352                 case 'outraged':
353                 case 'shocked':
354                 case 'surprised':
355                 case 'embarrassed':
356                 case 'impressed':
357                         icon = 'mood-five';
358                         break;
359                 
360                 case 'crazy':
361                 case 'distracted':
362                 case 'neutral':
363                 case 'relaxed':
364                 case 'thirsty':
365                         icon = 'mood-six';
366                         break;
367                 
368                 case 'amorous':
369                 case 'curious':
370                 case 'in_love':
371                 case 'nervous':
372                 case 'sarcastic':
373                         icon = 'mood-eight';
374                         break;
375                 
376                 case 'brave':
377                 case 'confident':
378                 case 'hopeful':
379                 case 'grateful':
380                 case 'spontaneous':
381                 case 'thankful':
382                         icon = 'mood-nine';
383                         break;
384                 
385                 default:
386                         icon = 'mood-seven';
387                         break;
388         }
389         
390         // Return the good icon name
391         return icon;
392 }
393
394 // Changes the activity icon
395 function activityIcon(value) {
396         // The main var
397         var icon;
398         
399         // Switch the values
400         switch(value) {
401                 case 'doing_chores':
402                         icon = 'activity-doing_chores';
403                         break;
404                 
405                 case 'drinking':
406                         icon = 'activity-drinking';
407                         break;
408                 
409                 case 'eating':
410                         icon = 'activity-eating';
411                         break;
412                 
413                 case 'grooming':
414                         icon = 'activity-grooming';
415                         break;
416                 
417                 case 'having_appointment':
418                         icon = 'activity-having_appointment';
419                         break;
420                 
421                 case 'inactive':
422                         icon = 'activity-inactive';
423                         break;
424                 
425                 case 'relaxing':
426                         icon = 'activity-relaxing';
427                         break;
428                 
429                 case 'talking':
430                         icon = 'activity-talking';
431                         break;
432                 
433                 case 'traveling':
434                         icon = 'activity-traveling';
435                         break;
436                 
437                 case 'working':
438                         icon = 'activity-working';
439                         break;
440                 default:
441                         icon = 'activity-exercising';
442                         break;
443         }
444         
445         // Return the good icon name
446         return icon;
447 }
448
449 // Sends the user's mood
450 function sendMood(value, text) {
451         /* REF: http://xmpp.org/extensions/xep-0107.html */
452         
453         // We propagate the mood on the xmpp network
454         var iq = new JSJaCIQ();
455         iq.setType('set');
456         
457         // We create the XML document
458         var pubsub = iq.appendNode('pubsub', {'xmlns': NS_PUBSUB});
459         var publish = pubsub.appendChild(iq.buildNode('publish', {'node': NS_MOOD, 'xmlns': NS_PUBSUB}));
460         var item = publish.appendChild(iq.buildNode('item', {'xmlns': NS_PUBSUB}));
461         var mood = item.appendChild(iq.buildNode('mood', {'xmlns': NS_MOOD}));
462         
463         if(value != 'none') {
464                 mood.appendChild(iq.buildNode(value, {'xmlns': NS_MOOD}));
465                 mood.appendChild(iq.buildNode('text', {'xmlns': NS_MOOD}, text));
466         }
467         
468         // And finally we send the mood that is set
469         con.send(iq);
470         
471         logThis('New mood sent: ' + value + ' (' + text + ')', 3);
472 }
473
474 // Sends the user's activity
475 function sendActivity(main, sub, text) {
476         // We propagate the mood on the xmpp network
477         var iq = new JSJaCIQ();
478         iq.setType('set');
479         
480         // We create the XML document
481         var pubsub = iq.appendNode('pubsub', {'xmlns': NS_PUBSUB});
482         var publish = pubsub.appendChild(iq.buildNode('publish', {'node': NS_ACTIVITY, 'xmlns': NS_PUBSUB}));
483         var item = publish.appendChild(iq.buildNode('item', {'xmlns': NS_PUBSUB}));
484         var activity = item.appendChild(iq.buildNode('activity', {'xmlns': NS_ACTIVITY}));
485         
486         if(main != 'none') {
487                 var mainType = activity.appendChild(iq.buildNode(main, {'xmlns': NS_ACTIVITY}));
488                 
489                 // Child nodes
490                 if(sub)
491                         mainType.appendChild(iq.buildNode(sub, {'xmlns': NS_ACTIVITY}));
492                 if(text)
493                         activity.appendChild(iq.buildNode('text', {'xmlns': NS_ACTIVITY}, text));
494         }
495         
496         // And finally we send the mood that is set
497         con.send(iq);
498         
499         logThis('New activity sent: ' + main + ' (' + text + ')', 3);
500 }
501
502 // Sends the user's geographic position
503 function sendPosition(vLat, vLon, vAlt, vCountry, vCountrycode, vRegion, vPostalcode, vLocality, vStreet, vBuilding, vText, vURI) {
504         /* REF: http://xmpp.org/extensions/xep-0080.html */
505         
506         // We propagate the position on pubsub
507         var iq = new JSJaCIQ();
508         iq.setType('set');
509         
510         // We create the XML document
511         var pubsub = iq.appendNode('pubsub', {'xmlns': NS_PUBSUB});
512         var publish = pubsub.appendChild(iq.buildNode('publish', {'node': NS_GEOLOC, 'xmlns': NS_PUBSUB}));
513         var item = publish.appendChild(iq.buildNode('item', {'xmlns': NS_PUBSUB}));
514         var geoloc = item.appendChild(iq.buildNode('geoloc', {'xmlns': NS_GEOLOC}));
515         
516         // Create two position arrays
517         var pos_names  = ['lat', 'lon', 'alt', 'country', 'countrycode', 'region', 'postalcode', 'locality', 'street', 'building', 'text', 'uri', 'timestamp'];
518         var pos_values = [ vLat,  vLon,  vAlt,  vCountry,  vCountrycode,  vRegion,  vPostalcode,  vLocality,  vStreet,  vBuilding,  vText,  vURI,  getXMPPTime('utc')];
519         
520         for(var i = 0; i < pos_names.length; i++) {
521                 if(pos_names[i] && pos_values[i])
522                         geoloc.appendChild(iq.buildNode(pos_names[i], {'xmlns': NS_GEOLOC}, pos_values[i]));
523         }
524         
525         // And finally we send the XML
526         con.send(iq);
527         
528         // For logger
529         if(vLat && vLon)
530                 logThis('Geolocated.', 3);
531         else
532                 logThis('Not geolocated.', 2);
533 }
534
535 // Parses the user's geographic position
536 function parsePosition(data) {
537         var result = $(data).find('result:first');
538         
539         // Get latitude and longitude
540         var lat = result.find('geometry:first location:first lat').text();
541         var lng = result.find('geometry:first location:first lng').text();
542         
543         var array = [
544                      lat,
545                      lng,
546                      result.find('address_component:has(type:contains("country")):first long_name').text(),
547                      result.find('address_component:has(type:contains("country")):first short_name').text(),
548                      result.find('address_component:has(type:contains("administrative_area_level_1")):first long_name').text(),
549                      result.find('address_component:has(type:contains("postal_code")):first long_name').text(),
550                      result.find('address_component:has(type:contains("locality")):first long_name').text(),
551                      result.find('address_component:has(type:contains("route")):first long_name').text(),
552                      result.find('address_component:has(type:contains("street_number")):first long_name').text(),
553                      result.find('formatted_address:first').text(),
554                      'http://maps.google.com/?q=' + encodeQuotes(lat) + ',' + encodeQuotes(lng)
555                     ];
556         
557         return array;
558 }
559
560 // Converts a position into an human-readable one
561 function humanPosition(tLocality, tRegion, tCountry) {
562         var tHuman = '';
563         
564         // Any locality?
565         if(tLocality) {
566                 tHuman += tLocality;
567                 
568                 if(tRegion)
569                         tHuman += ', ' + tRegion;
570                 if(tCountry)
571                         tHuman += ', ' + tCountry;
572         }
573         
574         // Any region?
575         else if(tRegion) {
576                 tHuman += tRegion;
577                 
578                 if(tCountry)
579                         tHuman += ', ' + tCountry;
580         }
581         
582         // Any country?
583         else if(tCountry)
584                 tHuman += tCountry;
585         
586         return tHuman;
587 }
588
589 // Gets the user's geographic position
590 function getPosition(position) {
591         // Convert integers to strings
592         var vLat = '' + position.coords.latitude;
593         var vLon = '' + position.coords.longitude;
594         var vAlt = '' + position.coords.altitude;
595         
596         // Get full position (from Google Maps API)
597         $.get('./php/geolocation.php', {latitude: vLat, longitude: vLon, language: XML_LANG}, function(data) {
598                 // Parse data!
599                 var results = parsePosition(data);
600                 
601                 // Handled!
602                 sendPosition(
603                              vLat,
604                              vLon,
605                              vAlt,
606                              results[2],
607                              results[3],
608                              results[4],
609                              results[5],
610                              results[6],
611                              results[7],
612                              results[8],
613                              results[9],
614                              results[10]
615                             );
616                 
617                 // Store data
618                 setDB('geolocation', 'now', xmlToString(data));
619                 
620                 logThis('Position details got from Google Maps API.');
621         });
622         
623         logThis('Position got: latitude > ' + vLat + ' / longitude > ' + vLon + ' / altitude > ' + vAlt);
624 }
625
626 // Geolocates the user
627 function geolocate() {
628         // Don't fire it until options & features are not retrieved!
629         if(!getDB('options', 'geolocation') || (getDB('options', 'geolocation') == '0') || !enabledPEP())
630                 return;
631         
632         // We publish the user location if allowed
633         if(navigator.geolocation) {
634                 // Wait a bit... (to fix a bug)
635                 $('#my-infos').stopTime().oneTime('1s', function() {
636                         navigator.geolocation.getCurrentPosition(getPosition);
637                 });
638                 
639                 logThis('Geolocating...', 3);
640         }
641         
642         // Any error?
643         else
644                 logThis('Not geolocated: browser does not support it.', 1);
645 }
646
647 // Displays all the supported PEP events for a given XID
648 function displayAllPEP(xid) {
649         displayPEP(xid, 'mood');
650         displayPEP(xid, 'activity');
651         displayPEP(xid, 'tune');
652         displayPEP(xid, 'geoloc');
653 }
654
655 // Addon launcher
656 function launchPEP() {
657         // Apply empty values to the PEP database
658         setDB('mood-value', 1, '');
659         setDB('mood-text', 1, '');
660         setDB('activity-value', 1, '');
661         setDB('activity-text', 1, '');
662         
663         // Click event for user mood
664         $('#my-infos .f-mood a.picker').click(function() {
665                 // Initialize some vars
666                 var path = '#my-infos .f-mood div.bubble';
667                 var mood_id = ['crazy', 'excited', 'playful', 'happy', 'shocked', 'hot', 'sad', 'amorous', 'confident'];
668                 var mood_lang = [_e("Crazy"), _e("Excited"), _e("Playful"), _e("Happy"), _e("Shocked"), _e("Hot"), _e("Sad"), _e("Amorous"), _e("Confident")];
669                 var mood_val = $('#my-infos .f-mood a.picker').attr('data-value');
670                 
671                 // Yet displayed?
672                 var can_append = true;
673                 
674                 if(exists(path))
675                         can_append = false;
676                 
677                 // Add this bubble!
678                 showBubble(path);
679                 
680                 if(!can_append)
681                         return false;
682                 
683                 // Generate the HTML code
684                 var html = '<div class="bubble removable">';
685                 
686                 for(i in mood_id) {
687                         // Yet in use: no need to display it!
688                         if(mood_id[i] == mood_val)
689                                 continue;
690                         
691                         html += '<a href="#" class="talk-images" data-value="' + mood_id[i] + '" title="' + mood_lang[i] + '"></a>';
692                 }
693                 
694                 html += '</div>';
695                 
696                 // Append the HTML code
697                 $('#my-infos .f-mood').append(html);
698                 
699                 // Click event
700                 $(path + ' a').click(function() {
701                         // Update the mood marker
702                         $('#my-infos .f-mood a.picker').attr('data-value', $(this).attr('data-value'));
703                         
704                         // Close the bubble
705                         closeBubbles();
706                         
707                         // Focus on the status input
708                         $(document).oneTime(10, function() {
709                                 $('#mood-text').focus();
710                         });
711                         
712                         return false;
713                 });
714                 
715                 return false;
716         });
717         
718         // Click event for user activity
719         $('#my-infos .f-activity a.picker').click(function() {
720                 // Initialize some vars
721                 var path = '#my-infos .f-activity div.bubble';
722                 var activity_id = ['doing_chores', 'drinking', 'eating', 'exercising', 'grooming', 'having_appointment', 'inactive', 'relaxing', 'talking', 'traveling', 'working'];
723                 var activity_lang = [_e("Chores"), _e("Drinking"), _e("Eating"), _e("Exercising"), _e("Grooming"), _e("Appointment"), _e("Inactive"), _e("Relaxing"), _e("Talking"), _e("Traveling"), _e("Working")];
724                 var activity_val = $('#my-infos .f-activity a.picker').attr('data-value');
725                 
726                 // Yet displayed?
727                 var can_append = true;
728                 
729                 if(exists(path))
730                         can_append = false;
731                 
732                 // Add this bubble!
733                 showBubble(path);
734                 
735                 if(!can_append)
736                         return false;
737                 
738                 // Generate the HTML code
739                 var html = '<div class="bubble removable">';
740                 
741                 for(i in activity_id) {
742                         // Yet in use: no need to display it!
743                         if(activity_id[i] == activity_val)
744                                 continue;
745                         
746                         html += '<a href="#" class="talk-images" data-value="' + activity_id[i] + '" title="' + activity_lang[i] + '"></a>';
747                 }
748                 
749                 html += '</div>';
750                 
751                 // Append the HTML code
752                 $('#my-infos .f-activity').append(html);
753                 
754                 // Click event
755                 $(path + ' a').click(function() {
756                         // Update the activity marker
757                         $('#my-infos .f-activity a.picker').attr('data-value', $(this).attr('data-value'));
758                         
759                         // Close the bubble
760                         closeBubbles();
761                         
762                         // Focus on the status input
763                         $(document).oneTime(10, function() {
764                                 $('#activity-text').focus();
765                         });
766                         
767                         return false;
768                 });
769                 
770                 return false;
771         });
772         
773         // Submit events for PEP inputs
774         $('#mood-text, #activity-text').placeholder()
775         
776         .keyup(function(e) {
777                 if(e.keyCode == 13) {
778                         $(this).blur();
779                         
780                         return false;
781                 }
782         });
783         
784         // Input blur handler
785         $('#mood-text').blur(function() {
786                 // Read the parameters
787                 var value = $('#my-infos .f-mood a.picker').attr('data-value');
788                 var text = $(this).val();
789                 
790                 // Must send the mood?
791                 if((value != getDB('mood-value', 1)) || (text != getDB('mood-text', 1))) {
792                         // Update the local stored values
793                         setDB('mood-value', 1, value);
794                         setDB('mood-text', 1, text);
795                         
796                         // Send it!
797                         sendMood(value, text);
798                 }
799         })
800         
801         // Input focus handler
802         .focus(function() {
803                 closeBubbles();
804         });
805         
806         // Input blur handler
807         $('#activity-text').blur(function() {
808                 // Read the parameters
809                 var value = $('#my-infos .f-activity a.picker').attr('data-value');
810                 var text = $(this).val();
811                 
812                 // Must send the activity?
813                 if((value != getDB('activity-value', 1)) || (text != getDB('activity-text', 1))) {
814                         // Update the local stored values
815                         setDB('activity-value', 1, value);
816                         setDB('activity-text', 1, text);
817                         
818                         // Send it!
819                         sendActivity(value, '', text);
820                 }
821         })
822         
823         // Input focus handler
824         .focus(function() {
825                 closeBubbles();
826         });
827 }