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