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