]> git.mxchange.org Git - friendica.git/blob - js/main.js
API: add docs to `api_item_get_user()`
[friendica.git] / js / main.js
1         function resizeIframe(obj) {
2                 //obj.style.height = 0;
3                 _resizeIframe(obj, 0);
4         }
5
6         function _resizeIframe(obj, desth) {
7                 var h = obj.style.height;
8                 var ch = obj.contentWindow.document.body.scrollHeight + 'px';
9                 if (h==ch) {
10                         return;
11                 }
12                 //console.log("_resizeIframe", obj, desth, ch);
13                 if (desth!=ch) {
14                         setTimeout(_resizeIframe, 500, obj, ch);
15                 } else {
16                         if (ch>0) obj.style.height  = ch;
17                         setTimeout(_resizeIframe, 1000, obj, ch);
18                 }
19         }
20
21   function openClose(theID) {
22     if(document.getElementById(theID).style.display == "block") {
23       document.getElementById(theID).style.display = "none"
24     }
25     else {
26       document.getElementById(theID).style.display = "block"
27     }
28   }
29
30   function openMenu(theID) {
31       document.getElementById(theID).style.display = "block"
32   }
33
34   function closeMenu(theID) {
35       document.getElementById(theID).style.display = "none"
36   }
37
38
39
40         var src = null;
41         var prev = null;
42         var livetime = null;
43         var force_update = false;
44         var stopped = false;
45         var totStopped = false;
46         var timer = null;
47         var pr = 0;
48         var liking = 0;
49         var in_progress = false;
50         var langSelect = false;
51         var commentBusy = false;
52         var last_popup_menu = null;
53         var last_popup_button = null;
54         var lockLoadContent = false;
55
56         $(function() {
57                 $.ajaxSetup({cache: false});
58
59                 /* setup tooltips *//*
60                 $("a,.tt").each(function(){
61                         var e = $(this);
62                         var pos="bottom";
63                         if (e.hasClass("tttop")) pos="top";
64                         if (e.hasClass("ttbottom")) pos="bottom";
65                         if (e.hasClass("ttleft")) pos="left";
66                         if (e.hasClass("ttright")) pos="right";
67                         e.tipTip({defaultPosition: pos, edgeOffset: 8});
68                 });*/
69
70                 /* setup comment textarea buttons */
71                 /* comment textarea buttons needs some "data-*" attributes to work:
72                  *              data-role="insert-formatting" : to mark the element as a formatting button
73                  *              data-comment="<string>" : string for "Comment", used by insertFormatting() function
74                  *              data-bbcode="<string>" : name of the bbcode element to insert. insertFormatting() will insert it as "[name][/name]"
75                  *              data-id="<string>" : id of the comment, used to find other comment-related element, like the textarea
76                  * */
77                 $('body').on('click','[data-role="insert-formatting"]', function(e) {
78                         e.preventDefault();
79                         var o = $(this);
80                         var comment = o.data('comment');
81                         var bbcode  = o.data('bbcode');
82                         var id = o.data('id');
83                         if (bbcode=="img") {
84                                 Dialog.doImageBrowser("comment", id);
85                                 return;
86                         }
87                         insertFormatting(comment, bbcode, id);
88                 });
89
90                 /* event from comment textarea button popups */
91                 /* insert returned bbcode at cursor position or replace selected text */
92                 $("body").on("fbrowser.image.comment", function(e, filename, bbcode, id) {
93                         console.log("on", id);
94                         $.colorbox.close();
95                         var textarea = document.getElementById("comment-edit-text-" +id);
96                         var start = textarea.selectionStart;
97                         var end = textarea.selectionEnd;
98                         textarea.value = textarea.value.substring(0, start) + bbcode + textarea.value.substring(end, textarea.value.length);
99                 });
100
101
102
103                 /* setup onoff widgets */
104                 $(".onoff input").each(function(){
105                         val = $(this).val();
106                         id = $(this).attr("id");
107                         $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
108
109                 });
110                 $(".onoff > a").click(function(event){
111                         event.preventDefault();
112                         var input = $(this).siblings("input");
113                         var val = 1-input.val();
114                         var id = input.attr("id");
115                         $("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
116                         $("#"+id+"_onoff ."+ (val==1?"on":"off")).removeClass("hidden");
117                         input.val(val);
118                         //console.log(id);
119                 });
120
121                 /* setup field_richtext */
122                 setupFieldRichtext();
123
124                 /* popup menus */
125                 function close_last_popup_menu() {
126                         if(last_popup_menu) {
127                                 last_popup_menu.hide();
128                                 last_popup_button.removeClass("selected");
129                                 last_popup_menu = null;
130                                 last_popup_button = null;
131                         }
132                 }
133                 $('a[rel^=#]').click(function(e){
134                         e.preventDefault();
135                         var parent = $(this).parent();
136                         var isSelected = (last_popup_button && parent.attr('id') == last_popup_button.attr('id'));
137                         close_last_popup_menu();
138                         if(isSelected) return false;
139                         menu = $( $(this).attr('rel') );
140                         e.preventDefault();
141                         e.stopPropagation();
142                         if (menu.attr('popup')=="false") return false;
143                         parent.toggleClass("selected");
144                         menu.toggle();
145                         if (menu.css("display") == "none") {
146                                 last_popup_menu = null;
147                                 last_popup_button = null;
148                         } else {
149                                 last_popup_menu = menu;
150                                 last_popup_button = parent;
151                                 $('#nav-notifications-menu').perfectScrollbar('update');
152                         }
153                         return false;
154                 });
155                 $('html').click(function() {
156                         close_last_popup_menu();
157                 });
158
159                 // fancyboxes
160                 $("a.popupbox").colorbox({
161                         'inline' : true,
162                         'transition' : 'elastic'
163                 });
164                 $("a.ajax-popupbox").colorbox({
165                         'transition' : 'elastic'
166                 });
167
168                 /* notifications template */
169                 var notifications_tpl= unescape($("#nav-notifications-template[rel=template]").html());
170                 var notifications_all = unescape($('<div>').append( $("#nav-notifications-see-all").clone() ).html()); //outerHtml hack
171                 var notifications_mark = unescape($('<div>').append( $("#nav-notifications-mark-all").clone() ).html()); //outerHtml hack
172                 var notifications_empty = unescape($("#nav-notifications-menu").html());
173
174                 /* enable perfect-scrollbars for different elements */
175                 $('#nav-notifications-menu, aside').perfectScrollbar();
176
177                 /* nav update event  */
178                 $('nav').bind('nav-update', function(e,data){
179                         var invalid = $(data).find('invalid').text();
180                         if(invalid == 1) { window.location.href=window.location.href }
181
182                         var net = $(data).find('net').text();
183                         if(net == 0) { net = ''; $('#net-update').removeClass('show') } else { $('#net-update').addClass('show') }
184                         $('#net-update').html(net);
185
186                         var home = $(data).find('home').text();
187                         if(home == 0) { home = '';  $('#home-update').removeClass('show') } else { $('#home-update').addClass('show') }
188                         $('#home-update').html(home);
189
190                         var intro = $(data).find('intro').text();
191                         if(intro == 0) { intro = '';  $('#intro-update').removeClass('show') } else { $('#intro-update').addClass('show') }
192                         $('#intro-update').html(intro);
193
194                         var mail = $(data).find('mail').text();
195                         if(mail == 0) { mail = '';  $('#mail-update').removeClass('show') } else { $('#mail-update').addClass('show') }
196                         $('#mail-update').html(mail);
197
198                         var intro = $(data).find('intro').text();
199                         if(intro == 0) { intro = '';  $('#intro-update-li').removeClass('show') } else { $('#intro-update-li').addClass('show') }
200                         $('#intro-update-li').html(intro);
201
202                         var mail = $(data).find('mail').text();
203                         if(mail == 0) { mail = '';  $('#mail-update-li').removeClass('show') } else { $('#mail-update-li').addClass('show') }
204                         $('#mail-update-li').html(mail);
205
206
207                         var allevents = $(data).find('all-events').text();
208                         if(allevents == 0) { allevents = ''; $('#allevents-update').removeClass('show') } else { $('#allevents-update').addClass('show') }
209                         $('#allevents-update').html(allevents);
210
211                         var alleventstoday = $(data).find('all-events-today').text();
212                         if(alleventstoday == 0) { $('#allevents-update').removeClass('notif-allevents-today') } else { $('#allevents-update').addClass('notif-allevents-today') }
213
214                         var events = $(data).find('events').text();
215                         if(events == 0) { events = ''; $('#events-update').removeClass('show') } else { $('#events-update').addClass('show') }
216                         $('#events-update').html(events);
217
218                         var eventstoday = $(data).find('events-today').text();
219                         if(eventstoday == 0) { $('#events-update').removeClass('notif-events-today') } else { $('#events-update').addClass('notif-events-today') }
220
221                         var birthdays = $(data).find('birthdays').text();
222                         if(birthdays == 0) {birthdays = ''; $('#birthdays-update').removeClass('show') } else { $('#birthdays-update').addClass('show') }
223                         $('#birthdays-update').html(birthdays);
224
225                         var birthdaystoday = $(data).find('birthdays-today').text();
226                         if(birthdaystoday == 0) { $('#birthdays-update').removeClass('notif-birthdays-today') } else { $('#birthdays-update').addClass('notif-birthdays-today') }
227
228                         $(".sidebar-group-li .notify").removeClass("show");
229                         $(data).find("group").each(function() {
230                                 var gid = this.id;
231                                 var gcount = this.innerHTML;
232                                 $(".group-"+gid+" .notify").addClass("show").text(gcount);
233                         });
234
235                         $(".forum-widget-entry .notify").removeClass("show");
236                         $(data).find("forum").each(function() {
237                                 var fid = this.id;
238                                 var fcount = this.innerHTML;
239                                 $(".forum-"+fid+" .notify").addClass("show").text(fcount);
240                         });
241
242
243                         var eNotif = $(data).find('notif')
244
245                         if (eNotif.children("note").length==0){
246                                 $("#nav-notifications-menu").html(notifications_empty);
247                         } else {
248                                 nnm = $("#nav-notifications-menu");
249                                 nnm.html(notifications_all + notifications_mark);
250                                 //nnm.attr('popup','true');
251
252                                 var notification_lastitem = parseInt(localStorage.getItem("notification-lastitem"));
253                                 var notification_id = 0;
254                                 eNotif.children("note").each(function(){
255                                         e = $(this);
256                                         var text = e.text().format("<span class='contactname'>"+e.attr('name')+"</span>");
257                                         var contact = ("<a href="+e.attr('url')+"><span class='contactname'>"+e.attr('name')+"</span></a>");
258                                         var seenclass = (e.attr('seen')==1)?"notify-seen":"notify-unseen";
259                                         var html = notifications_tpl.format(
260                                                 e.attr('href'),                     // {0}  // link to the source
261                                                 e.attr('photo'),                    // {1}  // photo of the contact
262                                                 text,                               // {2}  // preformatet text (autor + text)
263                                                 e.attr('date'),                     // {3}  // date of notification (time ago)
264                                                 seenclass,                          // {4}  // vistiting status of the notification
265                                                 new Date(e.attr('timestamp')*1000), // {5}  //date of notification
266                                                 e.attr('url'),                      // {6}  // profile url of the contact
267                                                 e.text().format(""),                // {7}  // clean status text
268                                                 contact                             // {8}  //preformatat author (name + profile url)
269                                         );
270                                         nnm.append(html);
271                                 });
272                                 $(eNotif.children("note").get().reverse()).each(function(){
273                                         e = $(this);
274                                         notification_id = parseInt(e.attr('timestamp'));
275                                         if (notification_lastitem!== null && notification_id > notification_lastitem) {
276                                                 if (getNotificationPermission()==="granted") {
277                                                         var notification = new Notification(document.title, {
278                                                                                           body: e.text().replace('&rarr; ','').format(e.attr('name')),
279                                                                                           icon: e.attr('photo'),
280                                                                                          });
281                                                         notification['url'] = e.attr('href');
282                                                         notification.addEventListener("click", function(ev){
283                                                                 window.location = ev.target.url;
284                                                         });
285                                                 }
286                                         }
287
288                                 });
289                                 notification_lastitem = notification_id;
290                                 localStorage.setItem("notification-lastitem", notification_lastitem)
291
292                                 $("img[data-src]", nnm).each(function(i, el){
293                                         // Add src attribute for images with a data-src attribute
294                                         // However, don't bother if the data-src attribute is empty, because
295                                         // an empty "src" tag for an image will cause some browsers
296                                         // to prefetch the root page of the Friendica hub, which will
297                                         // unnecessarily load an entire profile/ or network/ page
298                                         if($(el).data("src") != '') $(el).attr('src', $(el).data("src"));
299                                 });
300                         }
301
302                         notif = eNotif.attr('count');
303                         if (notif>0){
304                                 $("#nav-notifications-linkmenu").addClass("on");
305                         } else {
306                                 $("#nav-notifications-linkmenu").removeClass("on");
307                         }
308                         if(notif == 0) { notif = ''; $('#notify-update').removeClass('show') } else { $('#notify-update').addClass('show') }
309                         $('#notify-update').html(notif);
310
311                         var eSysmsg = $(data).find('sysmsgs');
312                         eSysmsg.children("notice").each(function(){
313                                 text = $(this).text();
314                                 $.jGrowl(text, { sticky: true, theme: 'notice' });
315                         });
316                         eSysmsg.children("info").each(function(){
317                                 text = $(this).text();
318                                 $.jGrowl(text, { sticky: false, theme: 'info', life: 5000 });
319                         });
320
321                         /* update the js scrollbars */
322                         $('#nav-notifications-menu').perfectScrollbar('update');
323
324                 });
325
326                 NavUpdate();
327                 // Allow folks to stop the ajax page updates with the pause/break key
328                 $(document).keydown(function(event) {
329                         if(event.keyCode == '8') {
330                                 var target = event.target || event.srcElement;
331                                 if (!/input|textarea/i.test(target.nodeName)) {
332                                         return false;
333                                 }
334                         }
335                         if(event.keyCode == '19' || (event.ctrlKey && event.which == '32')) {
336                                 event.preventDefault();
337                                 if(stopped == false) {
338                                         stopped = true;
339                                         if (event.ctrlKey) {
340                                                 totStopped = true;
341                                         }
342                                         $('#pause').html('<img src="images/pause.gif" alt="pause" style="border: 1px solid black;" />');
343                                 } else {
344                                         unpause();
345                                 }
346                         } else {
347                                 if (!totStopped) {
348                                         unpause();
349                                 }
350                         }
351                 });
352
353                 // Set an event listener for infinite scroll
354                 if(typeof infinite_scroll !== 'undefined') {
355                         $(window).scroll(function(e){
356                                 if ($(document).height() != $(window).height()) {
357                                         // First method that is expected to work - but has problems with Chrome
358                                         if ($(window).scrollTop() > ($(document).height() - $(window).height() * 1.5))
359                                                 loadScrollContent();
360                                 } else {
361                                         // This method works with Chrome - but seems to be much slower in Firefox
362                                         if ($(window).scrollTop() > (($("section").height() + $("header").height() + $("footer").height()) - $(window).height() * 1.5))
363                                                 loadScrollContent();
364                                 }
365                         });
366                 }
367
368
369         });
370
371         function NavUpdate() {
372
373                 if(! stopped) {
374                         var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : '');
375                         $.get(pingCmd,function(data) {
376                                 $(data).find('result').each(function() {
377                                         // send nav-update event
378                                         $('nav').trigger('nav-update', this);
379
380
381                                         // start live update
382
383                                         if($('#live-network').length)   { src = 'network'; liveUpdate(); }
384                                         if($('#live-profile').length)   { src = 'profile'; liveUpdate(); }
385                                         if($('#live-community').length) { src = 'community'; liveUpdate(); }
386                                         if($('#live-notes').length)     { src = 'notes'; liveUpdate(); }
387                                         if($('#live-display').length)     { src = 'display'; liveUpdate(); }
388 /*                                      if($('#live-display').length) {
389                                                 if(liking) {
390                                                         liking = 0;
391                                                         window.location.href=window.location.href
392                                                 }
393                                         }*/
394                                         if($('#live-photos').length) {
395                                                 if(liking) {
396                                                         liking = 0;
397                                                         window.location.href=window.location.href
398                                                 }
399                                         }
400
401
402
403
404                                 });
405                         }) ;
406                 }
407                 timer = setTimeout(NavUpdate,updateInterval);
408         }
409
410         function liveUpdate() {
411                 if((src == null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; }
412                 if(($('.comment-edit-text-full').length) || (in_progress)) {
413                         if(livetime) {
414                                 clearTimeout(livetime);
415                         }
416                         livetime = setTimeout(liveUpdate, 5000);
417                         return;
418                 }
419                 if(livetime != null)
420                         livetime = null;
421
422                 prev = 'live-' + src;
423
424                 in_progress = true;
425
426                 if ($(document).scrollTop() == 0)
427                         force_update = true;
428
429                 var udargs = ((netargs.length) ? '/' + netargs : '');
430                 var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page + '&force=' + ((force_update) ? 1 : 0);
431
432                 $.get(update_url,function(data) {
433                         in_progress = false;
434                         force_update = false;
435                         //                      $('.collapsed-comments',data).each(function() {
436                         //      var ident = $(this).attr('id');
437                         //      var is_hidden = $('#' + ident).is(':hidden');
438                         //      if($('#' + ident).length) {
439                         //              $('#' + ident).replaceWith($(this));
440                         //              if(is_hidden)
441                         //                      $('#' + ident).hide();
442                         //      }
443                         //});
444
445                         // add a new thread
446                         $('.toplevel_item',data).each(function() {
447                                 var ident = $(this).attr('id');
448
449                                 if($('#' + ident).length == 0 && profile_page == 1) {
450                                         $('img',this).each(function() {
451                                                 $(this).attr('src',$(this).attr('dst'));
452                                         });
453                                         $('#' + prev).after($(this));
454                                 }
455                                 else {
456                                         // Find out if the hidden comments are open, so we can keep it that way
457                                         // if a new comment has been posted
458                                         var id = $('.hide-comments-total', this).attr('id');
459                                         if(typeof id != 'undefined') {
460                                                 id = id.split('-')[3];
461                                                 var commentsOpen = $("#collapsed-comments-" + id).is(":visible");
462                                         }
463
464                                         $('img',this).each(function() {
465                                                 $(this).attr('src',$(this).attr('dst'));
466                                         });
467                                         //vScroll = $(document).scrollTop();
468                                         $('html').height($('html').height());
469                                         $('#' + ident).replaceWith($(this));
470
471                                         if(typeof id != 'undefined') {
472                                                 if(commentsOpen) showHideComments(id);
473                                         }
474                                         $('html').height('auto');
475                                         //$(document).scrollTop(vScroll);
476                                 }
477                                 prev = ident;
478                         });
479
480                         // reset vars for inserting individual items
481
482                         /*                      prev = 'live-' + src;
483
484                         $('.wall-item-outside-wrapper',data).each(function() {
485                                 var ident = $(this).attr('id');
486
487                                 if($('#' + ident).length == 0 && prev != 'live-' + src) {
488                                                 $('img',this).each(function() {
489                                                         $(this).attr('src',$(this).attr('dst'));
490                                                 });
491                                                 $('#' + prev).after($(this));
492                                 }
493                                 else {
494                                         $('#' + ident + ' ' + '.wall-item-ago').replaceWith($(this).find('.wall-item-ago'));
495                                         if($('#' + ident + ' ' + '.comment-edit-text-empty').length)
496                                                 $('#' + ident + ' ' + '.wall-item-comment-wrapper').replaceWith($(this).find('.wall-item-comment-wrapper'));
497                                         $('#' + ident + ' ' + '.hide-comments-total').replaceWith($(this).find('.hide-comments-total'));
498                                         $('#' + ident + ' ' + '.wall-item-like').replaceWith($(this).find('.wall-item-like'));
499                                         $('#' + ident + ' ' + '.wall-item-dislike').replaceWith($(this).find('.wall-item-dislike'));
500                                         $('#' + ident + ' ' + '.my-comment-photo').each(function() {
501                                                 $(this).attr('src',$(this).attr('dst'));
502                                         });
503                                 }
504                                 prev = ident;
505                         });
506                         */
507                         $('.like-rotator').hide();
508                         if(commentBusy) {
509                                 commentBusy = false;
510                                 $('body').css('cursor', 'auto');
511                         }
512                         /* autocomplete @nicknames */
513                         $(".comment-edit-form  textarea").editor_autocomplete(baseurl+"/acl");
514                         /* autocomplete bbcode */
515                         $(".comment-edit-form  textarea").bbco_autocomplete('bbcode');
516                         
517                         // setup videos, since VideoJS won't take care of any loaded via AJAX
518                         if(typeof videojs != 'undefined') videojs.autoSetup();
519                 });
520         }
521
522         function imgbright(node) {
523                 $(node).removeClass("drophide").addClass("drop");
524         }
525
526         function imgdull(node) {
527                 $(node).removeClass("drop").addClass("drophide");
528         }
529
530         // Since our ajax calls are asynchronous, we will give a few
531         // seconds for the first ajax call (setting like/dislike), then
532         // run the updater to pick up any changes and display on the page.
533         // The updater will turn any rotators off when it's done.
534         // This function will have returned long before any of these
535         // events have completed and therefore there won't be any
536         // visible feedback that anything changed without all this
537         // trickery. This still could cause confusion if the "like" ajax call
538         // is delayed and NavUpdate runs before it completes.
539
540         function dolike(ident,verb) {
541                 unpause();
542                 $('#like-rotator-' + ident.toString()).show();
543                 $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate );
544                 liking = 1;
545                 force_update = true;
546         }
547
548         function dosubthread(ident) {
549                 unpause();
550                 $('#like-rotator-' + ident.toString()).show();
551                 $.get('subthread/' + ident.toString(), NavUpdate );
552                 liking = 1;
553         }
554
555
556         function dostar(ident) {
557                 ident = ident.toString();
558                 $('#like-rotator-' + ident).show();
559                 $.get('starred/' + ident, function(data) {
560                         if(data.match(/1/)) {
561                                 $('#starred-' + ident).addClass('starred');
562                                 $('#starred-' + ident).removeClass('unstarred');
563                                 $('#star-' + ident).addClass('hidden');
564                                 $('#unstar-' + ident).removeClass('hidden');
565                         }
566                         else {
567                                 $('#starred-' + ident).addClass('unstarred');
568                                 $('#starred-' + ident).removeClass('starred');
569                                 $('#star-' + ident).removeClass('hidden');
570                                 $('#unstar-' + ident).addClass('hidden');
571                         }
572                         $('#like-rotator-' + ident).hide();
573                 });
574         }
575
576         function doignore(ident) {
577                 ident = ident.toString();
578                 $('#like-rotator-' + ident).show();
579                 $.get('ignored/' + ident, function(data) {
580                         if(data.match(/1/)) {
581                                 $('#ignored-' + ident).addClass('ignored');
582                                 $('#ignored-' + ident).removeClass('unignored');
583                                 $('#ignore-' + ident).addClass('hidden');
584                                 $('#unignore-' + ident).removeClass('hidden');
585                         }
586                         else {
587                                 $('#ignored-' + ident).addClass('unignored');
588                                 $('#ignored-' + ident).removeClass('ignored');
589                                 $('#ignore-' + ident).removeClass('hidden');
590                                 $('#unignore-' + ident).addClass('hidden');
591                         }
592                         $('#like-rotator-' + ident).hide();
593                 });
594         }
595
596         function getPosition(e) {
597                 var cursor = {x:0, y:0};
598                 if ( e.pageX || e.pageY  ) {
599                         cursor.x = e.pageX;
600                         cursor.y = e.pageY;
601                 }
602                 else {
603                         if( e.clientX || e.clientY ) {
604                                 cursor.x = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
605                                 cursor.y = e.clientY + (document.documentElement.scrollTop  || document.body.scrollTop)  - document.documentElement.clientTop;
606                         }
607                         else {
608                                 if( e.x || e.y ) {
609                                         cursor.x = e.x;
610                                         cursor.y = e.y;
611                                 }
612                         }
613                 }
614                 return cursor;
615         }
616
617         var lockvisible = false;
618
619         function lockview(event,id) {
620                 event = event || window.event;
621                 cursor = getPosition(event);
622                 if(lockvisible) {
623                         lockviewhide();
624                 }
625                 else {
626                         lockvisible = true;
627                         $.get('lockview/' + id, function(data) {
628                                 $('#panel').html(data);
629                                 $('#panel').css({ 'left': cursor.x + 5 , 'top': cursor.y + 5});
630                                 $('#panel').show();
631                         });
632                 }
633         }
634
635         function lockviewhide() {
636                 lockvisible = false;
637                 $('#panel').hide();
638         }
639
640         function post_comment(id) {
641                 unpause();
642                 commentBusy = true;
643                 $('body').css('cursor', 'wait');
644                 $("#comment-preview-inp-" + id).val("0");
645                 $.post(
646                         "item",
647                         $("#comment-edit-form-" + id).serialize(),
648                         function(data) {
649                                 if(data.success) {
650                                         $("#comment-edit-wrapper-" + id).hide();
651                                         $("#comment-edit-text-" + id).val('');
652                                         var tarea = document.getElementById("comment-edit-text-" + id);
653                                         if(tarea)
654                                                 commentClose(tarea,id);
655                                         if(timer) clearTimeout(timer);
656                                         timer = setTimeout(NavUpdate,10);
657                                         force_update = true;
658                                 }
659                                 if(data.reload) {
660                                         window.location.href=data.reload;
661                                 }
662                         },
663                         "json"
664                 );
665                 return false;
666         }
667
668
669         function preview_comment(id) {
670                 $("#comment-preview-inp-" + id).val("1");
671                 $("#comment-edit-preview-" + id).show();
672                 $.post(
673                         "item",
674                         $("#comment-edit-form-" + id).serialize(),
675                         function(data) {
676                                 if(data.preview) {
677                                         $("#comment-edit-preview-" + id).html(data.preview);
678                                         $("#comment-edit-preview-" + id + " a").click(function() { return false; });
679                                 }
680                         },
681                         "json"
682                 );
683                 return true;
684         }
685
686
687
688         function showHideComments(id) {
689                 if( $("#collapsed-comments-" + id).is(":visible")) {
690                         $("#collapsed-comments-" + id).hide();
691                         $("#hide-comments-" + id).html(window.showMore);
692                 }
693                 else {
694                         $("#collapsed-comments-" + id).show();
695                         $("#hide-comments-" + id).html(window.showFewer);
696                 }
697         }
698
699
700
701         function preview_post() {
702                 $("#jot-preview").val("1");
703                 $("#jot-preview-content").show();
704                 tinyMCE.triggerSave();
705                 $.post(
706                         "item",
707                         $("#profile-jot-form").serialize(),
708                         function(data) {
709                                 if(data.preview) {
710                                         $("#jot-preview-content").html(data.preview);
711                                         $("#jot-preview-content" + " a").click(function() { return false; });
712                                 }
713                         },
714                         "json"
715                 );
716                 $("#jot-preview").val("0");
717                 return true;
718         }
719
720
721         function unpause() {
722                 // unpause auto reloads if they are currently stopped
723                 totStopped = false;
724                 stopped = false;
725                 $('#pause').html('');
726         }
727
728         // load more network content (used for infinite scroll)
729         function loadScrollContent() {
730                 if (lockLoadContent) return;
731                 lockLoadContent = true;
732
733                 $("#scroll-loader").fadeIn('normal');
734
735                 // the page number to load is one higher than the actual
736                 // page number
737                 infinite_scroll.pageno+=1;
738
739                 console.log('Loading page ' + infinite_scroll.pageno);
740
741                 // get the raw content from the next page and insert this content
742                 // right before "#conversation-end"
743                 $.get('network?mode=raw' + infinite_scroll.reload_uri + '&page=' + infinite_scroll.pageno, function(data) {
744                         $("#scroll-loader").hide();
745                         if ($(data).length > 0) {
746                                 $(data).insertBefore('#conversation-end');
747                                 lockLoadContent = false;
748                         } else {
749                                 $("#scroll-end").fadeIn('normal');
750                         }
751                 });
752         }
753
754     function bin2hex(s){
755         // Converts the binary representation of data to hex
756         //
757         // version: 812.316
758         // discuss at: http://phpjs.org/functions/bin2hex
759         // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
760         // +   bugfixed by: Onno Marsman
761         // +   bugfixed by: Linuxworld
762         // *     example 1: bin2hex('Kev');
763         // *     returns 1: '4b6576'
764         // *     example 2: bin2hex(String.fromCharCode(0x00));
765         // *     returns 2: '00'
766         var v,i, f = 0, a = [];
767         s += '';
768         f = s.length;
769
770         for (i = 0; i<f; i++) {
771             a[i] = s.charCodeAt(i).toString(16).replace(/^([\da-f])$/,"0$1");
772         }
773
774         return a.join('');
775     }
776
777         function groupChangeMember(gid, cid, sec_token) {
778                 $('body .fakelink').css('cursor', 'wait');
779                 $.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
780                                 $('#group-update-wrapper').html(data);
781                                 $('body .fakelink').css('cursor', 'auto');
782                 });
783         }
784
785         function profChangeMember(gid,cid) {
786                 $('body .fakelink').css('cursor', 'wait');
787                 $.get('profperm/' + gid + '/' + cid, function(data) {
788                                 $('#prof-update-wrapper').html(data);
789                                 $('body .fakelink').css('cursor', 'auto');
790                 });
791         }
792
793         function contactgroupChangeMember(gid,cid) {
794                 $('body').css('cursor', 'wait');
795                 $.get('contactgroup/' + gid + '/' + cid, function(data) {
796                                 $('body').css('cursor', 'auto');
797                 });
798         }
799
800
801 function checkboxhighlight(box) {
802   if($(box).is(':checked')) {
803         $(box).addClass('checkeditem');
804   }
805   else {
806         $(box).removeClass('checkeditem');
807   }
808 }
809
810 function notifyMarkAll() {
811         $.get('notify/mark/all', function(data) {
812                 if(timer) clearTimeout(timer);
813                 timer = setTimeout(NavUpdate,1000);
814                 force_update = true;
815         });
816 }
817
818
819 // code from http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser
820 function fcFileBrowser (field_name, url, type, win) {
821     /* TODO: If you work with sessions in PHP and your client doesn't accept cookies you might need to carry
822        the session name and session ID in the request string (can look like this: "?PHPSESSID=88p0n70s9dsknra96qhuk6etm5").
823        These lines of code extract the necessary parameters and add them back to the filebrowser URL again. */
824
825
826     var cmsURL = baseurl+"/fbrowser/"+type+"/";
827
828     tinyMCE.activeEditor.windowManager.open({
829         file : cmsURL,
830         title : 'File Browser',
831         width : 420,  // Your dimensions may differ - toy around with them!
832         height : 400,
833         resizable : "yes",
834         inline : "yes",  // This parameter only has an effect if you use the inlinepopups plugin!
835         close_previous : "no"
836     }, {
837         window : win,
838         input : field_name
839     });
840     return false;
841   }
842
843 function setupFieldRichtext(){
844         tinyMCE.init({
845                 theme : "advanced",
846                 mode : "specific_textareas",
847                 editor_selector: "fieldRichtext",
848                 plugins : "bbcode,paste, inlinepopups",
849                 theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
850                 theme_advanced_buttons2 : "",
851                 theme_advanced_buttons3 : "",
852                 theme_advanced_toolbar_location : "top",
853                 theme_advanced_toolbar_align : "center",
854                 theme_advanced_blockformats : "blockquote,code",
855                 theme_advanced_resizing : true,
856                 paste_text_sticky : true,
857                 entity_encoding : "raw",
858                 add_unload_trigger : false,
859                 remove_linebreaks : false,
860                 //force_p_newlines : false,
861                 //force_br_newlines : true,
862                 forced_root_block : 'div',
863                 convert_urls: false,
864                 content_css: baseurl+"/view/custom_tinymce.css",
865                 theme_advanced_path : false,
866                 file_browser_callback : "fcFileBrowser",
867         });
868 }
869
870
871 /**
872  * sprintf in javascript
873  *      "{0} and {1}".format('zero','uno');
874  **/
875 String.prototype.format = function() {
876     var formatted = this;
877     for (var i = 0; i < arguments.length; i++) {
878         var regexp = new RegExp('\\{'+i+'\\}', 'gi');
879         formatted = formatted.replace(regexp, arguments[i]);
880     }
881     return formatted;
882 };
883 // Array Remove
884 Array.prototype.remove = function(item) {
885   to=undefined; from=this.indexOf(item);
886   var rest = this.slice((to || from) + 1 || this.length);
887   this.length = from < 0 ? this.length + from : from;
888   return this.push.apply(this, rest);
889 };
890
891 function previewTheme(elm) {
892         theme = $(elm).val();
893         $.getJSON('pretheme?f=&theme=' + theme,function(data) {
894                         $('#theme-preview').html('<div id="theme-desc">' + data.desc + '</div><div id="theme-version">' + data.version + '</div><div id="theme-credits">' + data.credits + '</div><a href="' + data.img + '"><img src="' + data.img + '" width="320" height="240" alt="' + theme + '" /></a>');
895         });
896
897 }
898
899 // notification permission settings in localstorage
900 // set by settings page
901 function getNotificationPermission() {
902         if (window["Notification"] === undefined) {
903                 return null;
904         }
905     if (Notification.permission === 'granted') {
906         var val = localStorage.getItem('notification-permissions');
907                 if (val === null) return 'denied';
908                 return val;
909     } else {
910         return Notification.permission;
911     }
912 }
913
914 /**
915  * Show a dialog loaded from an url
916  * By defaults this load the url in an iframe in colorbox
917  * Themes can overwrite `show()` function to personalize it
918  */
919 var Dialog = {
920         /**
921          * Show the dialog
922          *
923          * @param string url
924          * @return object colorbox
925          */
926         show : function (url) {
927                 var size = Dialog._get_size();
928                 return $.colorbox({href: url, iframe:true,innerWidth: size.width+'px',innerHeight: size.height+'px'})
929         },
930
931         /**
932          * Show the Image browser dialog
933          *
934          * @param string name
935          * @param string id (optional)
936          * @return object
937          *
938          * The name will be used to build the event name
939          * fired by image browser dialog when the user select
940          * an image. The optional id will be passed as argument
941          * to the event handler
942          */
943         doImageBrowser : function (name, id) {
944                 var url = Dialog._get_url("image",name,id);
945                 return Dialog.show(url);
946         },
947
948         /**
949          * Show the File browser dialog
950          *
951          * @param string name
952          * @param string id (optional)
953          * @return object
954          *
955          * The name will be used to build the event name
956          * fired by file browser dialog when the user select
957          * a file. The optional id will be passed as argument
958          * to the event handler
959          */
960         doFileBrowser : function (name, id) {
961                 var url = Dialog._get_url("file",name,id);
962                 return Dialog.show(url);
963         },
964
965         _get_url : function(type, name, id) {
966                 var hash = name;
967                 if (id !== undefined) hash = hash + "-" + id;
968                 return baseurl + "/fbrowser/"+type+"/?mode=minimal#"+hash;
969         },
970
971         _get_size: function() {
972                 return {
973                         width: window.innerWidth-50,
974                         height: window.innerHeight-100
975                 };
976         }
977 }