Merge git://github.com/M2Ys4U/KiwiIRC
[KiwiIRC.git] / js / front.js
1 var front = {
2 revision: 38,
3
4 cur_channel: '',
5 windows: {},
6 tabviews: {},
7 boxes: {},
8
9 buffer: [],
10 buffer_pos: 0,
11
12 init: function () {
13 gateway.nick = 'kiwi_' + Math.ceil(100 * Math.random()) + Math.ceil(100 * Math.random());
14 gateway.session_id = null;
15
16 $(gateway).bind("onmsg", front.onMsg);
17 $(gateway).bind("onnotice", front.onNotice);
18 $(gateway).bind("onaction", front.onAction);
19 $(gateway).bind("onmotd", front.onMOTD);
20 $(gateway).bind("onoptions", front.onOptions);
21 $(gateway).bind("onconnect", front.onConnect);
22 $(gateway).bind("ondisconnect", front.onDisconnect);
23 $(gateway).bind("onnick", front.onNick);
24 $(gateway).bind("onuserlist", front.onUserList);
25 $(gateway).bind("onuserlist_end", front.onUserListEnd);
26 $(gateway).bind("onjoin", front.onJoin);
27 $(gateway).bind("ontopic", front.onTopic);
28 $(gateway).bind("onpart", front.onPart);
29 $(gateway).bind("onkick", front.onKick);
30 $(gateway).bind("onquit", front.onQuit);
31 $(gateway).bind("onwhois", front.onWhois);
32 $(gateway).bind("onsync", front.onSync);
33 $(gateway).bind("onchannel_redirect", front.onChannelRedirect);
34 $(gateway).bind("ondebug", front.onDebug);
35
36 this.buffer = [];
37
38 // Build the about box
39 front.boxes.about = new box("about");
40 var about_info = 'UI adapted for ' + agent;
41 if (touchscreen) about_info += ' touchscreen ';
42 about_info += 'usage';
43 $('#tmpl_about_box').tmpl({
44 about:about_info,
45 front_revision:front.revision,
46 gateway_revision:gateway.revision
47 }).appendTo(front.boxes.about.content);
48
49 //$(window).bind("beforeunload", function(){ gateway.quit(); });
50
51 if(touchscreen){
52 $('#kiwi').addClass('touchscreen');
53
54 // Single touch scrolling through scrollback for touchscreens
55 scroll_opts = {};
56 touch_scroll = new iScroll('windows', scroll_opts);
57 }
58
59 front.registerKeys();
60
61
62 $('#kiwi .formconnectwindow').submit(function () {
63 var netsel = $('#kiwi .formconnectwindow .network');
64 var nick = $('#kiwi .formconnectwindow .nick');
65
66 if (nick.val() === '') {
67 nick.val('Nick please!');
68 nick.focus();
69 return false;
70 }
71
72 var tmp = nick.val().split(' ');
73 gateway.nick = tmp[0];
74 front.doLayout();
75 try {
76 front.run('/connect ' + netsel.val());
77 } catch (e) {
78 alert(e);
79 }
80
81 $('#kiwi .connectwindow').slideUp();
82 $(document).mouseup(function(){ $('#kiwi_msginput').focus(); });
83
84 return false;
85 });
86
87 var supportsOrientationChange = "onorientationchange" in window,
88 orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
89 window.addEventListener(orientationEvent, front.doLayoutSize, false);
90 //$('#kiwi').bind("resize", front.doLayoutSize, false);
91
92 front.doLayout();
93 //front.windowAdd('server');
94 front.tabviewAdd('server');
95
96 // Any pre-defined nick?
97 if (typeof init_data.nick === "string") {
98 $('#kiwi .formconnectwindow .nick').val(init_data.nick);
99 }
100
101 //gateway.session_id = 'testses';
102
103 gateway.start();
104 //front.sync();
105 },
106
107 doLayoutSize: function () {
108 var kiwi = $('#kiwi');
109 if (kiwi.width() < 330 && !kiwi.hasClass('small_kiwi')) {
110 console.log("switching to small kiwi");
111 kiwi.removeClass('large_kiwi');
112 kiwi.addClass('small_kiwi');
113 } else if (kiwi.width() >= 330 && !kiwi.hasClass('large_kiwi')) {
114 kiwi.removeClass('small_kiwi');
115 kiwi.addClass('large_kiwi');
116 }
117
118 var ct = $('#kiwi .cur_topic');
119 var ul = $('#kiwi .userlist');
120
121 var top = parseInt(ct.offset().top) + parseInt(ct.height());
122 top = top + parseInt(ct.css('border-top-width').replace('px', ''));
123 top = top + parseInt(ct.css('border-bottom-width').replace('px', ''));
124 top = top + parseInt(ct.css('padding-top').replace('px', ''));
125 top = top + parseInt(ct.css('padding-bottom').replace('px', ''));
126 top = top + 1;
127
128 $('#kiwi .windows').css('top', top + "px");
129 $('#kiwi .userlist').css('top', top + "px");
130 },
131
132
133 doLayout: function () {
134 $('#kiwi .msginput .nick a').text(gateway.nick);
135 $('#kiwi_msginput').val(' ');
136 $('#kiwi_msginput').focus();
137 },
138
139
140 joinChannel: function (chan_name) {
141 var chans = chan_name.split(','),
142 i;
143 for (i in chans) {
144 chan = chans[i];
145 if (front.tabviews[chan.toLowerCase()] === undefined) {
146 gateway.join(chan);
147 front.tabviewAdd(chan);
148 } else {
149 front.tabviews[chan.toLowerCase()].show();
150 }
151 }
152 },
153
154
155 run: function (msg) {
156 console.log("running "+msg);
157 if (msg.substring(0, 1) === '/') {
158 var parts = msg.split(' ');
159 switch (parts[0].toLowerCase()) {
160 case '/j':
161 case '/join':
162 front.joinChannel(parts[1]);
163 break;
164
165 case '/connect':
166 case '/server':
167 if (parts[1] === undefined) {
168 alert('Usage: /connect servername [port]');
169 break;
170 }
171
172 if (parts[2] === undefined) {
173 parts[2] = 6667;
174 }
175 front.cur_channel.addMsg(null, ' ', '=== Connecting to ' + parts[1] + '...', 'status');
176 gateway.connect(parts[1], parts[2], 0);
177 break;
178
179 case '/nick':
180 console.log("/nick");
181 if (parts[1] === undefined) {
182 console.log("calling show nick");
183 front.showChangeNick();
184 } else {
185 console.log("sending raw");
186 gateway.raw(msg.substring(1));
187 }
188 break;
189
190 case '/part':
191 if (typeof parts[1] === "undefined") {
192 gateway.raw(msg.substring(1) + ' ' + front.cur_channel.name);
193 } else {
194 gateway.raw(msg.substring(1));
195 }
196 break;
197
198 case '/names':
199 if (typeof parts[1] !== "undefined") {
200 gateway.raw(msg.substring(1));
201 }
202 break;
203
204 case '/debug':
205 gateway.debug();
206 break;
207
208 case '/q':
209 case '/query':
210 if (typeof parts[1] !== "undefined") {
211 front.tabviewAdd(parts[1]);
212 }
213 break;
214
215 case '/quote':
216 gateway.raw(msg.replace(/^\/quote /i, ''));
217 break;
218
219 case '/me':
220 gateway.action(front.cur_channel.name, msg.substring(4));
221 //front.tabviews[destination.toLowerCase()].addMsg(null, ' ', '* '+data.nick+' '+data.msg, 'color:green;');
222 front.cur_channel.addMsg(null, ' ', '* ' + gateway.nick + ' ' + msg.substring(4), 'action', 'color:#555;');
223 break;
224 case '/quit':
225 gateway.quit(msg.split(" ",2)[1]);
226 break;
227
228 default:
229 //front.cur_channel.addMsg(null, ' ', '--> Invalid command: '+parts[0].substring(1));
230 gateway.raw(msg.substring(1));
231 }
232
233 } else {
234 //alert('Sending message: '+msg);
235 if (msg.trim() === '') {
236 return;
237 }
238 gateway.msg(front.cur_channel.name, msg);
239 var d = new Date();
240 d = d.getHours() + ":" + d.getMinutes();
241 //front.addMsg(d, gateway.nick, msg);
242 front.cur_channel.addMsg(null, gateway.nick, msg);
243 }
244 },
245
246
247 onMsg: function (e, data) {
248 var destination;
249 // Is this message from a user?
250 if (data.channel === gateway.nick) {
251 destination = data.nick.toLowerCase();
252 } else {
253 destination = data.channel.toLowerCase();
254 }
255
256 if (!front.tabviewExists(destination)) {
257 front.tabviewAdd(destination);
258 }
259 front.tabviews[destination].addMsg(null, data.nick, data.msg);
260 },
261
262 onDebug: function (e, data) {
263 if (!front.tabviewExists('kiwi_debug')) {
264 front.tabviewAdd('kiwi_debug');
265 }
266 front.tabviews.kiwi_debug.addMsg(null, ' ', data.msg);
267 },
268
269 onAction: function (e, data) {
270 var destination;
271 // Is this message from a user?
272 if (data.channel === gateway.nick) {
273 destination = data.nick;
274 } else {
275 destination = data.channel;
276 }
277
278 if (!front.tabviewExists(destination)) {
279 front.tabviewAdd(destination);
280 }
281 front.tabviews[destination.toLowerCase()].addMsg(null, ' ', '* ' + data.nick + ' ' + data.msg, 'action', 'color:#555;');
282 },
283
284 onTopic: function (e, data) {
285 if (front.tabviewExists(data.channel)) {
286 front.tabviews[data.channel.toLowerCase()].changeTopic(data.topic);
287 }
288 },
289
290 onNotice: function (e, data) {
291 var nick = (data.nick === "") ? "" : '[' + data.nick + ']';
292 if (data.channel !== undefined) {
293 //alert('notice for '+data.channel);
294 if (front.tabviewExists(data.channel)) {
295 front.tabviews[data.channel.toLowerCase()].addMsg(null, nick, data.msg, 'notice');
296 }
297 } else {
298 //alert('direct notice');
299 front.tabviews.server.addMsg(null, nick, data.msg, 'notice');
300 }
301 },
302 onConnect: function (e, data) {
303 if (data.connected) {
304 front.tabviews.server.addMsg(null, ' ', '=== Connected OK :)', 'status');
305 if (typeof init_data.channel === "string") {
306 front.joinChannel(init_data.channel);
307 }
308 } else {
309 front.tabviews.server.addMsg(null, ' ', '=== Failed to connect :(', 'status');
310 }
311 },
312 onDisconnect: function(e, data){
313 var tab;
314 for(tab in front.tabviews){
315 front.tabviews[tab].addMsg(null, '', 'Disconnected from server!', 'error')
316 }
317 },
318 onOptions: function (e, data) {
319 if (typeof gateway.network_name === "string" && gateway.network_name !== "") {
320 front.tabviews.server.tab.text(gateway.network_name);
321 }
322 },
323 onMOTD: function (e, data) {
324 front.tabviews.server.addMsg(null, data.server, data.msg, 'motd');
325 },
326 onWhois: function (e, data) {
327 front.cur_channel.addMsg(null, data.nick, data.msg, 'whois');
328 },
329 onUserList: function (e, data) {
330 if (front.tabviews[data.channel.toLowerCase()] === undefined) {
331 return;
332 }
333 var ul = front.tabviews[data.channel.toLowerCase()].userlist;
334
335 if (!document.userlist_updating) {
336 document.userlist_updating = true;
337 ul.empty();
338 }
339
340 $.each(data.users, function (i, item) {
341 var nick = i; //i.match(/^.+!/g);
342 var mode = item;
343 $('<li><a class="nick" onclick="front.userClick(this);">' + mode + nick + '</a></li>').appendTo(ul);
344 });
345
346 front.tabviews[data.channel.toLowerCase()].userlistSort();
347 },
348 onUserListEnd: function (e, data) {
349 document.userlist_updating = false;
350 },
351
352 onJoin: function (e, data) {
353 if (!front.tabviewExists(data.channel)) {
354 front.tabviewAdd(data.channel.toLowerCase());
355 }
356
357 if (data.nick === gateway.nick) {
358 return; // Not needed as it's already in nicklist
359 }
360 front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '--> ' + data.nick + ' has joined', 'action', 'color:#009900;');
361 $('<li><a class="nick" onclick="front.userClick(this);">' + data.nick + '</a></li>').appendTo(front.tabviews[data.channel.toLowerCase()].userlist);
362 front.tabviews[data.channel.toLowerCase()].userlistSort();
363 },
364 onPart: function (e, data) {
365 if (front.tabviewExists(data.channel)) {
366 // If this is us, close the tabview
367 if (data.nick === gateway.nick) {
368 front.tabviews[data.channel.toLowerCase()].close();
369 front.tabviews.server.show();
370 return;
371 }
372
373 front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '<-- ' + data.nick + ' has left (' + data.message + ')', 'action', 'color:#990000;');
374 front.tabviews[data.channel.toLowerCase()].userlist.children().each(function () {
375 if ($(this).text() === data.nick) {
376 $(this).remove();
377 }
378 });
379 }
380 },
381 onKick: function (e, data) {
382 if (front.tabviewExists(data.channel)) {
383 // If this is us, close the tabvi ew
384 if (data.kicked === gateway.nick) {
385 front.tabviews[data.channel.toLowerCase()].close();
386 return;
387 }
388
389 front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '<-- ' + data.kicked + ' kicked by ' + data.nick + '(' + data.message + ')', 'action', 'color:#990000;');
390 front.tabviews[data.channel.toLowerCase()].userlist.children().each(function () {
391 if ($(this).text() === data.nick) {
392 $(this).remove();
393 }
394 });
395 }
396 },
397 onNick: function (e, data) {
398 if (data.nick === gateway.nick) {
399 gateway.nick = data.newnick;
400 front.doLayout();
401 }
402
403 $.each(front.tabviews, function (i, item) {
404 $.each(front.tabviews, function (i, item) {
405 item.changeNick(data.newnick, data.nick);
406 });
407 });
408 },
409 onQuit: function (e, data) {
410 $.each(front.tabviews, function (i, item) {
411 $.each(front.tabviews, function (i, item) {
412 item.userlist.children().each(function () {
413 if ($(this).text() === data.nick) {
414 $(this).remove();
415 item.addMsg(null, ' ', '<-- ' + data.nick + ' has quit (' + data.message + ')', 'action', 'color:#990000;');
416 }
417 });
418 });
419 });
420 },
421 onChannelRedirect: function (e, data) {
422 front.tabviews[data.from.toLowerCase()].close();
423 front.tabviewAdd(data.to.toLowerCase());
424 front.tabviews[data.to.toLowerCase()].addMsg(null, ' ', '=== Redirected from ' + data.from, 'action');
425 },
426
427 registerKeys: function () {
428 $('#kiwi_msginput').bind('keydown', function (e) {
429 //$('input').keypress(function(e){
430 switch (e.which) {
431 case 27: // escape
432 return false;
433 case 13: // return
434 var msg = $('#kiwi_msginput').val();
435 msg = msg.trim();
436
437 front.buffer.push(msg);
438 front.buffer_pos = front.buffer.length;
439
440 front.run(msg);
441 $('#kiwi_msginput').val('');
442
443 break;
444
445 case 38: // up
446 if (front.buffer_pos > 0) {
447 front.buffer_pos--;
448 $('#kiwi_msginput').val(front.buffer[front.buffer_pos]);
449 }
450 break;
451 case 40: // down
452 if (front.buffer_pos < front.buffer.length) {
453 front.buffer_pos++;
454 $('#kiwi_msginput').val(front.buffer[front.buffer_pos]);
455 }
456 break;
457
458 case 9: // tab
459 // Get possible autocompletions
460 var data = [];
461 front.cur_channel.userlist.children().each(function () {
462 nick = front.nickStripPrefix($('a.nick', this).text());
463 data.push(nick);
464 });
465
466 // Do the autocomplete
467 if (this.value.length === this.selectionStart && this.value.length === this.selectionEnd) {
468 var candidates = [];
469
470 var word_pos = this.value.lastIndexOf(' ');
471 var word = "";
472 if (word_pos === -1) {
473 word = this.value;
474 } else {
475 word = this.value.substr(word_pos);
476 }
477 word = word.trim();
478
479 // filter data to find only strings that start with existing value
480 for (i = 0; i < data.length; i++) {
481 if (data[i].indexOf(word) === 0 && data[i].length > word.length) {
482 candidates.push(data[i]);
483 }
484 }
485
486 if (candidates.length > 0) {
487 // some candidates for autocompletion are found
488 this.value = this.value.substring(0, word_pos) + ' ' + candidates[0] + ': ';
489 this.selectionStart = this.value.length;
490 }
491 }
492 return false;
493 }
494 });
495
496
497 $('#kiwi .control .msginput .nick').click(function () {
498 front.showChangeNick();
499 });
500
501
502
503
504
505 $('#kiwi .plugins .load_plugin_file').click(function () {
506 if (typeof front.boxes.plugins !== "undefined") {
507 return;
508 }
509
510 front.boxes.plugins = new box("plugin_file");
511 $('#tmpl_plugins').tmpl({}).appendTo(front.boxes.plugins.content);
512 front.boxes.plugins.box.css('top', -(front.boxes.plugins.height + 40));
513
514 // Populate the plugin list..
515 var lst = $('#plugin_list');
516 lst.find('option').remove();
517 var j;
518 for (j in plugins.privmsg) {
519 var txt = plugins.privmsg[j].name;
520 lst.append('<option value="' + txt + '">' + txt + '</option>');
521 }
522
523 // Event bindings
524 $('#kiwi .plugin_file').submit(function () {
525 $.getJSON($('.txtpluginfile').val(), function (data) {
526 var plg = {};
527 plg.name = data.name;
528 eval("plg.onprivmsg = " + data.onprivmsg);
529 eval("plg.onload = " + data.onload);
530 eval("plg.onunload = " + data.onunload);
531 plugins.privmsg.push(plg);
532
533 if (plg.onload instanceof Function) {
534 plg.onload();
535 }
536 });
537 return false;
538 });
539 $('#kiwi .cancelpluginfile').click(function () {
540 front.boxes.plugins.destroy();
541 });
542
543 $('#kiwi #plugins_list_unload').click(function () {
544 var selected_plugin = $('#plugin_list').val();
545 console.log("removing plugin: "+selected_plugin);
546 for (var i in plugins.privmsg) {
547 if (plugins.privmsg[i].name === selected_plugin) {
548 if (plugins.privmsg[i].onunload instanceof Function)
549 plugins.privmsg[i].onunload();
550
551 delete plugins.privmsg[i];
552 }
553 }
554 });
555
556 $('#kiwi .txtpluginfile').focus();
557
558 });
559
560 $('#kiwi .plugins .reload_css').click(function () {
561 var links = document.getElementsByTagName("link");
562 for (var i=0; i < links.length; i++) {
563 if (links[i].rel === "stylesheet") {
564 if (links[i].href.indexOf("?")===-1) {
565 links[i].href += "?";
566 }
567 links[i].href += "x";
568 }
569 }
570 });
571
572
573 $('#kiwi .about .about_close').click(function () {
574 $('#kiwi .about').css('display', 'none');
575 });
576
577
578 $('#kiwi .poweredby').click(function () {
579 $('#kiwi .about').css('display', 'block');
580 });
581
582 },
583
584
585 showChangeNick: function(){
586 $('#kiwi').append($('#tmpl_change_nick').tmpl({}));
587
588 $('#kiwi .form_newnick').submit(function () {
589 front.run('/NICK ' + $('#kiwi .txtnewnick').val());
590 $('#kiwi .newnick').remove();
591 return false;
592 });
593
594 $('#kiwi .txtnewnick').keypress(function(ev){
595 if(!this.first_press) {
596 this.first_press=true;
597 return false;
598 }
599
600 if(ev.keyCode === 27){ // ESC
601 $('#kiwi_msginput').focus();
602 $('#kiwi .newnick').remove();
603 }
604 });
605
606 $('#kiwi .cancelnewnick').click(function () {
607 $('#kiwi .newnick').remove();
608 });
609
610 $('#kiwi .txtnewnick').focus();
611 },
612
613
614 tabviewExists: function (name) {
615 return !(front.tabviews[name.toLowerCase()] == undefined);
616 },
617
618 tabviewAdd: function (v_name) {
619 if (v_name.charAt(0) == gateway.channel_prefix) {
620 var re = new RegExp(gateway.channel_prefix,"g");
621 var htmlsafe_name = v_name.replace(re, 'pre');
622 htmlsafe_name = "chan_" + htmlsafe_name;
623 } else {
624 var htmlsafe_name = 'query_' + v_name;
625 }
626
627 var tmp_divname = 'kiwi_window_' + htmlsafe_name;
628 var tmp_userlistname = 'kiwi_userlist_' + htmlsafe_name;
629 var tmp_tabname = 'kiwi_tab_' + htmlsafe_name
630
631 $('#kiwi .windows .scroller').append('<div id="' + tmp_divname + '" class="messages"></div>');
632 $('#kiwi .userlist').append('<ul id="' + tmp_userlistname + '"></ul>');
633 $('#kiwi .windowlist ul').append('<li id="' + tmp_tabname + '" onclick="front.tabviews[\'' + v_name.toLowerCase() + '\'].show();">' + v_name + '</li>');
634 //$('#kiwi .windowlist ul .window_'+v_name).click(function(){ front.windowShow(v_name); });
635 //front.windowShow(v_name);
636
637 front.tabviews[v_name.toLowerCase()] = new tabview();
638 front.tabviews[v_name.toLowerCase()].name = v_name;
639 front.tabviews[v_name.toLowerCase()].div = $('#'+tmp_divname);
640 front.tabviews[v_name.toLowerCase()].userlist = $('#'+tmp_userlistname);
641 front.tabviews[v_name.toLowerCase()].tab = $('#'+tmp_tabname);
642 front.tabviews[v_name.toLowerCase()].show();
643
644 if (typeof registerTouches === "function") {
645 //alert("Registering touch interface");
646 //registerTouches($('#'+tmp_divname));
647 registerTouches(document.getElementById(tmp_divname));
648 }
649 /*
650 front.tabviews[v_name.toLowerCase()].userlist.click(function(){
651 alert($(this).attr('id'));
652 });
653 */
654
655 front.doLayoutSize();
656 },
657
658
659 userClick: function (item) {
660 // Remove any existing userboxes
661 $('#kiwi .userbox').remove();
662
663 var li = $(item).parent();
664 /*var html = '<div class="userbox">\
665 <input type="hidden" class="userbox_nick" value="' + front.nickStripPrefix($(item).text()) + '" />\
666 <a href="#" class="userbox_query">Message</a>\
667 <a href="#" class="userbox_whois">Info</a>\
668 </div>';
669 li.append(html);*/
670 $('#tmpl_user_box').tmpl({nick: front.nickStripPrefix($(item).text())}).appendTo(li);
671
672 $('#kiwi .userbox .userbox_query').click(function (ev) {
673 var nick = $('#kiwi .userbox_nick').val();
674 front.run('/query ' + nick);
675 });
676
677 $('#kiwi .userbox .userbox_whois').click(function (ev) {
678 var nick = $('#kiwi .userbox_nick').val();
679 front.run('/whois ' + nick);
680 });
681 },
682
683
684 sync: function () {
685 gateway.sync();
686 },
687
688 onSync: function (e, data) {
689 // Set any settings
690 if (data.nick != undefined) gateway.nick = data.nick;
691
692 // Add the tabviews
693 if (data.tabviews != undefined) {
694 $.each(data.tabviews, function (i, tab) {
695 if(!front.tabviewExists(tab.name)){
696 front.tabviewAdd(gateway.channel_prefix + tab.name);
697
698 if (tab.userlist !== undefined)
699 front.onUserList({'channel':gateway.channel_prefix + tab.name, 'users':tab.userlist});
700 }
701 });
702 }
703
704 front.doLayout();
705 },
706
707
708 setTopicText: function (new_topic) {
709 $('#kiwi .cur_topic').text(new_topic);
710 },
711
712
713
714
715
716
717
718 nickStripPrefix: function (nick) {
719 var tmp = nick;
720
721 prefix = tmp.charAt(0);
722 if (typeof gateway.user_prefixes[prefix] != "undefined") tmp = tmp.substring(1);
723
724 return tmp;
725 },
726
727 nickGetPrefix: function (nick) {
728 var tmp = nick;
729
730 prefix = tmp.charAt(0);
731 if (typeof gateway.user_prefixes[prefix] == "undefined") {
732 prefix = "";
733 }
734
735 return prefix;
736 },
737
738 isChannel: function (name) {
739 prefix = name.charAt(0);
740 if (gateway.channel_prefix.indexOf(prefix) > -1) {
741 is_chan = true;
742 } else {
743 is_chan = false;
744 }
745
746 return is_chan;
747 },
748
749 tabviewsNext: function(){
750 var wl = $('#kiwi .windowlist ul');
751 var next_left = parseInt(wl.css('text-indent').replace('px', ''))+170;
752 wl.css('text-indent', next_left);
753 },
754
755 tabviewsPrevious: function(){
756 var wl = $('#kiwi .windowlist ul');
757 var next_left = parseInt(wl.css('text-indent').replace('px', ''))-170;
758 wl.css('text-indent', next_left);
759 },
760
761 windowsNext: function(){
762 var tab, next;
763 next = false;
764 for(tab in front.tabviews){
765 if(!next){
766 if(front.tabviews[tab] == front.cur_channel){
767 next = true;
768 continue;
769 }
770 } else {
771 front.tabviews[tab].show();
772 }
773 };
774 },
775
776 windowsPrevious: function(){
777 var tab, prev_tab, next;
778 next = false;
779 for(tab in front.tabviews){
780 if(front.tabviews[tab] == front.cur_channel){
781 prev_tab.show();
782 return;
783 }
784 prev_tab = front.tabviews[tab];
785 };
786 }
787 }
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805 /*
806 *
807 * TABVIEWS
808 *
809 */
810
811
812 var tabview = function(){}
813 tabview.prototype.name = null;
814 tabview.prototype.div = null;
815 tabview.prototype.userlist = null;
816 tabview.prototype.tab = null;
817 tabview.prototype.topic = "";
818
819 tabview.prototype.show = function(){
820 $('#kiwi .messages').removeClass("active");
821 $('#kiwi .userlist ul').removeClass("active");
822 $('#kiwi .windowlist ul li').removeClass("active");
823
824 // Activate this tab!
825 this.div.addClass('active');
826 this.userlist.addClass('active');
827 this.tab.addClass('active');
828
829 document.tmp = this.div;
830 // Add the part image to the tab
831 this.addPartImage();
832
833 this.clearHighlight();
834 front.setTopicText(this.topic);
835 front.cur_channel = this;
836
837 // If we're using fancy scrolling, refresh it
838 if(touch_scroll) touch_scroll.refresh();
839
840 this.scrollBottom();
841 if(!touchscreen) $('#kiwi_msginput').focus();
842 }
843
844 tabview.prototype.close = function(){
845 this.div.remove();
846 this.userlist.remove();
847 this.tab.remove();
848
849 front.tabviews['server'].show();
850 delete front.tabviews[this.name.toLowerCase()];
851 }
852
853 tabview.prototype.addPartImage = function(){
854 this.clearPartImage();
855
856 var del_html = '<img src="img/redcross.png" class="tab_part" />';
857 this.tab.append(del_html);
858
859 $('.tab_part', this.tab).click(function(){
860 if(front.isChannel($(this).parent().text())){
861 front.run("/part");
862 } else {
863 // Make sure we don't close the server tab
864 if(front.cur_channel.name != "server") front.cur_channel.close();
865 }
866 });
867 }
868
869 tabview.prototype.clearPartImage = function(){
870 $('#kiwi .windowlist .tab_part').remove();
871 }
872
873 tabview.prototype.addMsg = function(time, nick, msg, type, style){
874 //if(nick.charAt(0) != "[" && nick != ""){
875 // var html_nick = $('<div/>').text('<'+nick+'>').html();
876 //} else {
877 var html_nick = $('<div/>').text(nick).html();
878 //}
879
880 var self = this;
881
882 var tmp = msg;
883 var plugin_ret = '';
884 for(var i in plugins.privmsg){
885 if ((plugins.privmsg[i].onprivmsg instanceof Function)) {
886 plugin_ret = '';
887 try {
888 plugin_ret = plugins.privmsg[i].onprivmsg(tmp, this.name);
889
890 // If this plugin has returned false, do not add this message
891 if(plugin_ret === false) return;
892 } catch (e){}
893
894 // If we actually have a string from the plugin, use it
895 if(typeof plugin_ret == "string") tmp = plugin_ret;
896 }
897 }
898 msg = tmp;
899
900 //var html_msg = $('<div/>').text(msg).html()+' '; // Add the space so the styling always has at least 1 character to go from
901 if(time == null){
902 var d = new Date();
903 time = d.getHours().toString().lpad(2, "0") + ":" + d.getMinutes().toString().lpad(2, "0") + ":" + d.getSeconds().toString().lpad(2, "0");
904 }
905
906 // The CSS class (action, topic, notice, etc)
907 if(typeof type != "string") type = '';
908
909 // Make sure we don't have NaN or something
910 if(typeof msg != "string") msg = '';
911
912 // Text formatting
913 // bold
914 if(msg.indexOf(String.fromCharCode(2))){
915 next = '<b>';
916 while(msg.indexOf(String.fromCharCode(2)) != -1){
917 msg = msg.replace(String.fromCharCode(2), next);
918 next = (next=='<b>') ? '</b>' : '<b>';
919 }
920 if(next == '</b>') msg =+ '</b>';
921 }
922
923 // Wierd thing noticed by Dux0r on the irc.esper.net server
924 if(typeof msg != "string") msg = '';
925
926 // underline
927 if(msg.indexOf(String.fromCharCode(31))){
928 next = '<u>';
929 while(msg.indexOf(String.fromCharCode(31)) != -1){
930 msg = msg.replace(String.fromCharCode(31), next);
931 next = (next=='<u>') ? '</u>' : '<u>';
932 }
933 if(next == '</u>') msg =+ '</u>';
934 }
935
936
937 var line_msg = $('<div class="msg '+type+'"><div class="time">'+time+'</div><div class="nick">'+html_nick+'</div><div class="text" style="'+style+'">'+msg+' </div></div>');
938 this.div.append(line_msg);
939
940 if(!touchscreen){
941 this.scrollBottom();
942 } else {
943 touch_scroll.refresh();
944 //console.log(this.div.attr("scrollHeight") +" - "+ $('#windows').height());
945 this.scrollBottom();
946 //if(this.div.attr("scrollHeight") > $('#windows').height()){
947 // touch_scroll.scrollTo(0, this.div.height());
948 //}
949 }
950 }
951
952 tabview.prototype.scrollBottom = function(){
953 var w = $('#windows');
954 w.attr({ scrollTop: w.attr("scrollHeight") });
955 }
956
957 tabview.prototype.changeNick = function(newNick, oldNick){
958 this.userlist.children().each(function(){
959 var item = $('a.nick', this);
960 if(front.nickStripPrefix(item.text()) == oldNick){
961 item.text(front.nickGetPrefix(item.text())+newNick);
962 document.temp_chan = 1;
963 }
964 });
965
966 if(typeof document.temp_chan != "undefined"){
967 this.addMsg(null, ' ', '=== '+oldNick+' is now known as '+newNick, 'action');
968 delete document.temp_chan;
969 this.userlistSort();
970 }
971 }
972
973 tabview.prototype.userlistSort = function(){
974 var ul = this.userlist;
975 var listitems = ul.children('li').get();
976 listitems.sort(function(a, b) {
977 var compA = $(a).text().toUpperCase();
978 var compB = $(b).text().toUpperCase();
979
980 // Sort by prefixes first
981 for (var i in gateway.user_prefixes) {
982 prefix = gateway.user_prefixes[i];
983
984 if(compA.charAt(0) == prefix && compB.charAt(0) == prefix){
985 // Both have the same prefix, string compare time
986 return 0;
987 }
988
989 if(compA.charAt(0) == prefix && compB.charAt(0) != prefix){
990 return -1;
991 }
992
993 if(compA.charAt(0) != prefix && compB.charAt(0) == prefix){
994 return 1;
995 }
996 }
997
998 // No prefixes, compare by string
999 return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
1000 })
1001 $.each(listitems, function(idx, itm) { ul.append(itm); });
1002 }
1003
1004 tabview.prototype.highlight = function(){
1005 this.tab.addClass('highlight');
1006 }
1007 tabview.prototype.activity = function(){
1008 this.tab.addClass('activity');
1009 }
1010 tabview.prototype.clearHighlight = function(){
1011 this.tab.removeClass('highlight');
1012 this.tab.removeClass('activity');
1013 }
1014 tabview.prototype.changeTopic = function(new_topic){
1015 this.topic = new_topic;
1016 this.addMsg(null, ' ', '=== Topic for '+this.name+' is: '+new_topic, 'topic');
1017 if(front.cur_channel.name == this.name) front.setTopicText(new_topic);
1018 }
1019
1020
1021
1022
1023
1024 var box = function(classname){
1025 this.id = randomString(10);
1026 var tmp = $('<div id="'+this.id+'" class="box '+classname+'"><div class="boxarea"></div></div>');
1027 $('#kiwi').append(tmp);
1028 this.box = $('#'+this.id);
1029 this.content = $('#'+this.id+' .boxarea');
1030
1031 this.box.draggable({ stack: ".box" });
1032 this.content.click(function(){});
1033 //this.box.click(function(){ $(this)..css });
1034 }
1035 box.prototype.create = function(name, classname){
1036
1037 }
1038 box.prototype.id = null;
1039 box.prototype.box = null;
1040 box.prototype.content = null;
1041 box.prototype.destroy = function(){
1042 this.box.remove();
1043 for (var name in front.boxes) if(front.boxes[name].id = this.id) delete front.boxes[name];
1044 }
1045 box.prototype.height = function(){ return this.box.height(); }