Merge pull request #2 from M2Ys4U/master
[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
225 case '/notice':
226 var dest, msg;
227 dest = parts[1];
228 msg = parts.slice(2).join(' ');
229
230 gateway.notice(dest, msg);
231 this.onNotice({}, {nick:gateway.nick, channel:dest, msg:msg});
232 break;
233
234 case '/quit':
235 gateway.quit(msg.split(" ",2)[1]);
236 break;
237
238 default:
239 //front.cur_channel.addMsg(null, ' ', '--> Invalid command: '+parts[0].substring(1));
240 gateway.raw(msg.substring(1));
241 }
242
243 } else {
244 //alert('Sending message: '+msg);
245 if (msg.trim() === '') {
246 return;
247 }
248 gateway.msg(front.cur_channel.name, msg);
249 var d = new Date();
250 d = d.getHours() + ":" + d.getMinutes();
251 //front.addMsg(d, gateway.nick, msg);
252 front.cur_channel.addMsg(null, gateway.nick, msg);
253 }
254 },
255
256
257 onMsg: function (e, data) {
258 var destination;
259 // Is this message from a user?
260 if (data.channel === gateway.nick) {
261 destination = data.nick.toLowerCase();
262 } else {
263 destination = data.channel.toLowerCase();
264 }
265
266 if (!front.tabviewExists(destination)) {
267 front.tabviewAdd(destination);
268 }
269 front.tabviews[destination].addMsg(null, data.nick, data.msg);
270 },
271
272 onDebug: function (e, data) {
273 if (!front.tabviewExists('kiwi_debug')) {
274 front.tabviewAdd('kiwi_debug');
275 }
276 front.tabviews.kiwi_debug.addMsg(null, ' ', data.msg);
277 },
278
279 onAction: function (e, data) {
280 var destination;
281 // Is this message from a user?
282 if (data.channel === gateway.nick) {
283 destination = data.nick;
284 } else {
285 destination = data.channel;
286 }
287
288 if (!front.tabviewExists(destination)) {
289 front.tabviewAdd(destination);
290 }
291 front.tabviews[destination.toLowerCase()].addMsg(null, ' ', '* ' + data.nick + ' ' + data.msg, 'action', 'color:#555;');
292 },
293
294 onTopic: function (e, data) {
295 if (front.tabviewExists(data.channel)) {
296 front.tabviews[data.channel.toLowerCase()].changeTopic(data.topic);
297 }
298 },
299
300 onNotice: function (e, data) {
301 var nick = (data.nick === "") ? "" : '[' + data.nick + ']';
302 if (data.channel !== undefined) {
303 //alert('notice for '+data.channel);
304 if (front.tabviewExists(data.channel)) {
305 front.tabviews[data.channel.toLowerCase()].addMsg(null, nick, data.msg, 'notice');
306 }
307 } else {
308 //alert('direct notice');
309 front.tabviews.server.addMsg(null, nick, data.msg, 'notice');
310 }
311 },
312 onConnect: function (e, data) {
313 if (data.connected) {
314 front.tabviews.server.addMsg(null, ' ', '=== Connected OK :)', 'status');
315 if (typeof init_data.channel === "string") {
316 front.joinChannel(init_data.channel);
317 }
318 } else {
319 front.tabviews.server.addMsg(null, ' ', '=== Failed to connect :(', 'status');
320 }
321 },
322 onDisconnect: function(e, data){
323 var tab;
324 for(tab in front.tabviews){
325 front.tabviews[tab].addMsg(null, '', 'Disconnected from server!', 'error')
326 }
327 },
328 onOptions: function (e, data) {
329 if (typeof gateway.network_name === "string" && gateway.network_name !== "") {
330 front.tabviews.server.tab.text(gateway.network_name);
331 }
332 },
333 onMOTD: function (e, data) {
334 front.tabviews.server.addMsg(null, data.server, data.msg, 'motd');
335 },
336 onWhois: function (e, data) {
337 front.cur_channel.addMsg(null, data.nick, data.msg, 'whois');
338 },
339 onUserList: function (e, data) {
340 if (front.tabviews[data.channel.toLowerCase()] === undefined) {
341 return;
342 }
343 var ul = front.tabviews[data.channel.toLowerCase()].userlist;
344
345 if (!document.userlist_updating) {
346 document.userlist_updating = true;
347 ul.empty();
348 }
349
350 $.each(data.users, function (i, item) {
351 var nick = i; //i.match(/^.+!/g);
352 var mode = item;
353 $('<li><a class="nick" onclick="front.userClick(this);">' + mode + nick + '</a></li>').appendTo(ul);
354 });
355
356 front.tabviews[data.channel.toLowerCase()].userlistSort();
357 },
358 onUserListEnd: function (e, data) {
359 document.userlist_updating = false;
360 },
361
362 onJoin: function (e, data) {
363 if (!front.tabviewExists(data.channel)) {
364 front.tabviewAdd(data.channel.toLowerCase());
365 }
366
367 if (data.nick === gateway.nick) {
368 return; // Not needed as it's already in nicklist
369 }
370 front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '--> ' + data.nick + ' has joined', 'action', 'color:#009900;');
371 $('<li><a class="nick" onclick="front.userClick(this);">' + data.nick + '</a></li>').appendTo(front.tabviews[data.channel.toLowerCase()].userlist);
372 front.tabviews[data.channel.toLowerCase()].userlistSort();
373 },
374 onPart: function (e, data) {
375 if (front.tabviewExists(data.channel)) {
376 // If this is us, close the tabview
377 if (data.nick === gateway.nick) {
378 front.tabviews[data.channel.toLowerCase()].close();
379 front.tabviews.server.show();
380 return;
381 }
382
383 front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '<-- ' + data.nick + ' has left (' + data.message + ')', 'action', 'color:#990000;');
384 front.tabviews[data.channel.toLowerCase()].userlist.children().each(function () {
385 if ($(this).text() === data.nick) {
386 $(this).remove();
387 }
388 });
389 }
390 },
391 onKick: function (e, data) {
392 if (front.tabviewExists(data.channel)) {
393 // If this is us, close the tabvi ew
394 if (data.kicked === gateway.nick) {
395 front.tabviews[data.channel.toLowerCase()].close();
396 return;
397 }
398
399 front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '<-- ' + data.kicked + ' kicked by ' + data.nick + '(' + data.message + ')', 'action', 'color:#990000;');
400 front.tabviews[data.channel.toLowerCase()].userlist.children().each(function () {
401 if ($(this).text() === data.nick) {
402 $(this).remove();
403 }
404 });
405 }
406 },
407 onNick: function (e, data) {
408 if (data.nick === gateway.nick) {
409 gateway.nick = data.newnick;
410 front.doLayout();
411 }
412
413 $.each(front.tabviews, function (i, item) {
414 $.each(front.tabviews, function (i, item) {
415 item.changeNick(data.newnick, data.nick);
416 });
417 });
418 },
419 onQuit: function (e, data) {
420 $.each(front.tabviews, function (i, item) {
421 $.each(front.tabviews, function (i, item) {
422 item.userlist.children().each(function () {
423 if ($(this).text() === data.nick) {
424 $(this).remove();
425 item.addMsg(null, ' ', '<-- ' + data.nick + ' has quit (' + data.message + ')', 'action', 'color:#990000;');
426 }
427 });
428 });
429 });
430 },
431 onChannelRedirect: function (e, data) {
432 front.tabviews[data.from.toLowerCase()].close();
433 front.tabviewAdd(data.to.toLowerCase());
434 front.tabviews[data.to.toLowerCase()].addMsg(null, ' ', '=== Redirected from ' + data.from, 'action');
435 },
436
437 registerKeys: function () {
438 $('#kiwi_msginput').bind('keydown', function (e) {
439 //$('input').keypress(function(e){
440 switch (e.which) {
441 case 27: // escape
442 return false;
443 case 13: // return
444 var msg = $('#kiwi_msginput').val();
445 msg = msg.trim();
446
447 front.buffer.push(msg);
448 front.buffer_pos = front.buffer.length;
449
450 front.run(msg);
451 $('#kiwi_msginput').val('');
452
453 break;
454
455 case 38: // up
456 if (front.buffer_pos > 0) {
457 front.buffer_pos--;
458 $('#kiwi_msginput').val(front.buffer[front.buffer_pos]);
459 }
460 break;
461 case 40: // down
462 if (front.buffer_pos < front.buffer.length) {
463 front.buffer_pos++;
464 $('#kiwi_msginput').val(front.buffer[front.buffer_pos]);
465 }
466 break;
467
468 case 9: // tab
469 // Get possible autocompletions
470 var data = [];
471 front.cur_channel.userlist.children().each(function () {
472 nick = front.nickStripPrefix($('a.nick', this).text());
473 data.push(nick);
474 });
475
476 // Do the autocomplete
477 if (this.value.length === this.selectionStart && this.value.length === this.selectionEnd) {
478 var candidates = [];
479
480 var word_pos = this.value.lastIndexOf(' ');
481 var word = "";
482 if (word_pos === -1) {
483 word = this.value;
484 } else {
485 word = this.value.substr(word_pos);
486 }
487 word = word.trim();
488
489 // filter data to find only strings that start with existing value
490 for (i = 0; i < data.length; i++) {
491 if (data[i].indexOf(word) === 0 && data[i].length > word.length) {
492 candidates.push(data[i]);
493 }
494 }
495
496 if (candidates.length > 0) {
497 // some candidates for autocompletion are found
498 this.value = this.value.substring(0, word_pos) + ' ' + candidates[0] + ': ';
499 this.selectionStart = this.value.length;
500 }
501 }
502 return false;
503 }
504 });
505
506
507 $('#kiwi .control .msginput .nick').click(function () {
508 front.showChangeNick();
509 });
510
511
512
513
514
515 $('#kiwi .plugins .load_plugin_file').click(function () {
516 if (typeof front.boxes.plugins !== "undefined") {
517 return;
518 }
519
520 front.boxes.plugins = new box("plugin_file");
521 $('#tmpl_plugins').tmpl({}).appendTo(front.boxes.plugins.content);
522 front.boxes.plugins.box.css('top', -(front.boxes.plugins.height + 40));
523
524 // Populate the plugin list..
525 var lst = $('#plugin_list');
526 lst.find('option').remove();
527 var j;
528 for (j in plugins.privmsg) {
529 var txt = plugins.privmsg[j].name;
530 lst.append('<option value="' + txt + '">' + txt + '</option>');
531 }
532
533 // Event bindings
534 $('#kiwi .plugin_file').submit(function () {
535 $.getJSON($('.txtpluginfile').val(), function (data) {
536 var plg = {};
537 plg.name = data.name;
538 eval("plg.onprivmsg = " + data.onprivmsg);
539 eval("plg.onload = " + data.onload);
540 eval("plg.onunload = " + data.onunload);
541 plugins.privmsg.push(plg);
542
543 if (plg.onload instanceof Function) {
544 plg.onload();
545 }
546 });
547 return false;
548 });
549 $('#kiwi .cancelpluginfile').click(function () {
550 front.boxes.plugins.destroy();
551 });
552
553 $('#kiwi #plugins_list_unload').click(function () {
554 var selected_plugin = $('#plugin_list').val();
555 console.log("removing plugin: "+selected_plugin);
556 for (var i in plugins.privmsg) {
557 if (plugins.privmsg[i].name === selected_plugin) {
558 if (plugins.privmsg[i].onunload instanceof Function)
559 plugins.privmsg[i].onunload();
560
561 delete plugins.privmsg[i];
562 }
563 }
564 });
565
566 $('#kiwi .txtpluginfile').focus();
567
568 });
569
570 $('#kiwi .plugins .reload_css').click(function () {
571 var links = document.getElementsByTagName("link");
572 for (var i=0; i < links.length; i++) {
573 if (links[i].rel === "stylesheet") {
574 if (links[i].href.indexOf("?")===-1) {
575 links[i].href += "?";
576 }
577 links[i].href += "x";
578 }
579 }
580 });
581
582
583 $('#kiwi .about .about_close').click(function () {
584 $('#kiwi .about').css('display', 'none');
585 });
586
587
588 $('#kiwi .poweredby').click(function () {
589 $('#kiwi .about').css('display', 'block');
590 });
591
592 },
593
594
595 showChangeNick: function(){
596 $('#kiwi').append($('#tmpl_change_nick').tmpl({}));
597
598 $('#kiwi .form_newnick').submit(function () {
599 front.run('/NICK ' + $('#kiwi .txtnewnick').val());
600 $('#kiwi .newnick').remove();
601 return false;
602 });
603
604 $('#kiwi .txtnewnick').keypress(function(ev){
605 if(!this.first_press) {
606 this.first_press=true;
607 return false;
608 }
609
610 if(ev.keyCode === 27){ // ESC
611 $('#kiwi_msginput').focus();
612 $('#kiwi .newnick').remove();
613 }
614 });
615
616 $('#kiwi .cancelnewnick').click(function () {
617 $('#kiwi .newnick').remove();
618 });
619
620 $('#kiwi .txtnewnick').focus();
621 },
622
623
624 tabviewExists: function (name) {
625 return !(front.tabviews[name.toLowerCase()] == undefined);
626 },
627
628 tabviewAdd: function (v_name) {
629 if (v_name.charAt(0) == gateway.channel_prefix) {
630 var re = new RegExp(gateway.channel_prefix,"g");
631 var htmlsafe_name = v_name.replace(re, 'pre');
632 htmlsafe_name = "chan_" + htmlsafe_name;
633 } else {
634 var htmlsafe_name = 'query_' + v_name;
635 }
636
637 var tmp_divname = 'kiwi_window_' + htmlsafe_name;
638 var tmp_userlistname = 'kiwi_userlist_' + htmlsafe_name;
639 var tmp_tabname = 'kiwi_tab_' + htmlsafe_name
640
641 $('#kiwi .windows .scroller').append('<div id="' + tmp_divname + '" class="messages"></div>');
642 $('#kiwi .userlist').append('<ul id="' + tmp_userlistname + '"></ul>');
643 $('#kiwi .windowlist ul').append('<li id="' + tmp_tabname + '" onclick="front.tabviews[\'' + v_name.toLowerCase() + '\'].show();">' + v_name + '</li>');
644 //$('#kiwi .windowlist ul .window_'+v_name).click(function(){ front.windowShow(v_name); });
645 //front.windowShow(v_name);
646
647 front.tabviews[v_name.toLowerCase()] = new tabview();
648 front.tabviews[v_name.toLowerCase()].name = v_name;
649 front.tabviews[v_name.toLowerCase()].div = $('#'+tmp_divname);
650 front.tabviews[v_name.toLowerCase()].userlist = $('#'+tmp_userlistname);
651 front.tabviews[v_name.toLowerCase()].tab = $('#'+tmp_tabname);
652 front.tabviews[v_name.toLowerCase()].show();
653
654 if (typeof registerTouches === "function") {
655 //alert("Registering touch interface");
656 //registerTouches($('#'+tmp_divname));
657 registerTouches(document.getElementById(tmp_divname));
658 }
659 /*
660 front.tabviews[v_name.toLowerCase()].userlist.click(function(){
661 alert($(this).attr('id'));
662 });
663 */
664
665 front.doLayoutSize();
666 },
667
668
669 userClick: function (item) {
670 // Remove any existing userboxes
671 $('#kiwi .userbox').remove();
672
673 var li = $(item).parent();
674 /*var html = '<div class="userbox">\
675 <input type="hidden" class="userbox_nick" value="' + front.nickStripPrefix($(item).text()) + '" />\
676 <a href="#" class="userbox_query">Message</a>\
677 <a href="#" class="userbox_whois">Info</a>\
678 </div>';
679 li.append(html);*/
680 $('#tmpl_user_box').tmpl({nick: front.nickStripPrefix($(item).text())}).appendTo(li);
681
682 $('#kiwi .userbox .userbox_query').click(function (ev) {
683 var nick = $('#kiwi .userbox_nick').val();
684 front.run('/query ' + nick);
685 });
686
687 $('#kiwi .userbox .userbox_whois').click(function (ev) {
688 var nick = $('#kiwi .userbox_nick').val();
689 front.run('/whois ' + nick);
690 });
691 },
692
693
694 sync: function () {
695 gateway.sync();
696 },
697
698 onSync: function (e, data) {
699 // Set any settings
700 if (data.nick != undefined) gateway.nick = data.nick;
701
702 // Add the tabviews
703 if (data.tabviews != undefined) {
704 $.each(data.tabviews, function (i, tab) {
705 if(!front.tabviewExists(tab.name)){
706 front.tabviewAdd(gateway.channel_prefix + tab.name);
707
708 if (tab.userlist !== undefined)
709 front.onUserList({'channel':gateway.channel_prefix + tab.name, 'users':tab.userlist});
710 }
711 });
712 }
713
714 front.doLayout();
715 },
716
717
718 setTopicText: function (new_topic) {
719 $('#kiwi .cur_topic').text(new_topic);
720 },
721
722
723
724
725
726
727
728 nickStripPrefix: function (nick) {
729 var tmp = nick;
730
731 prefix = tmp.charAt(0);
732 if (typeof gateway.user_prefixes[prefix] != "undefined") tmp = tmp.substring(1);
733
734 return tmp;
735 },
736
737 nickGetPrefix: function (nick) {
738 var tmp = nick;
739
740 prefix = tmp.charAt(0);
741 if (typeof gateway.user_prefixes[prefix] == "undefined") {
742 prefix = "";
743 }
744
745 return prefix;
746 },
747
748 isChannel: function (name) {
749 prefix = name.charAt(0);
750 if (gateway.channel_prefix.indexOf(prefix) > -1) {
751 is_chan = true;
752 } else {
753 is_chan = false;
754 }
755
756 return is_chan;
757 },
758
759 tabviewsNext: function(){
760 var wl = $('#kiwi .windowlist ul');
761 var next_left = parseInt(wl.css('text-indent').replace('px', ''))+170;
762 wl.css('text-indent', next_left);
763 },
764
765 tabviewsPrevious: function(){
766 var wl = $('#kiwi .windowlist ul');
767 var next_left = parseInt(wl.css('text-indent').replace('px', ''))-170;
768 wl.css('text-indent', next_left);
769 },
770
771 windowsNext: function(){
772 var tab, next;
773 next = false;
774 for(tab in front.tabviews){
775 if(!next){
776 if(front.tabviews[tab] == front.cur_channel){
777 next = true;
778 continue;
779 }
780 } else {
781 front.tabviews[tab].show();
782 }
783 };
784 },
785
786 windowsPrevious: function(){
787 var tab, prev_tab, next;
788 next = false;
789 for(tab in front.tabviews){
790 if(front.tabviews[tab] == front.cur_channel){
791 prev_tab.show();
792 return;
793 }
794 prev_tab = front.tabviews[tab];
795 };
796 }
797 }
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815 /*
816 *
817 * TABVIEWS
818 *
819 */
820
821
822 var tabview = function(){}
823 tabview.prototype.name = null;
824 tabview.prototype.div = null;
825 tabview.prototype.userlist = null;
826 tabview.prototype.tab = null;
827 tabview.prototype.topic = "";
828
829 tabview.prototype.show = function(){
830 $('#kiwi .messages').removeClass("active");
831 $('#kiwi .userlist ul').removeClass("active");
832 $('#kiwi .windowlist ul li').removeClass("active");
833
834 // Activate this tab!
835 this.div.addClass('active');
836 this.userlist.addClass('active');
837 this.tab.addClass('active');
838
839 document.tmp = this.div;
840 // Add the part image to the tab
841 this.addPartImage();
842
843 this.clearHighlight();
844 front.setTopicText(this.topic);
845 front.cur_channel = this;
846
847 // If we're using fancy scrolling, refresh it
848 if(touch_scroll) touch_scroll.refresh();
849
850 this.scrollBottom();
851 if(!touchscreen) $('#kiwi_msginput').focus();
852 }
853
854 tabview.prototype.close = function(){
855 this.div.remove();
856 this.userlist.remove();
857 this.tab.remove();
858
859 front.tabviews['server'].show();
860 delete front.tabviews[this.name.toLowerCase()];
861 }
862
863 tabview.prototype.addPartImage = function(){
864 this.clearPartImage();
865
866 var del_html = '<img src="img/redcross.png" class="tab_part" />';
867 this.tab.append(del_html);
868
869 $('.tab_part', this.tab).click(function(){
870 if(front.isChannel($(this).parent().text())){
871 front.run("/part");
872 } else {
873 // Make sure we don't close the server tab
874 if(front.cur_channel.name != "server") front.cur_channel.close();
875 }
876 });
877 }
878
879 tabview.prototype.clearPartImage = function(){
880 $('#kiwi .windowlist .tab_part').remove();
881 }
882
883 tabview.prototype.addMsg = function(time, nick, msg, type, style){
884 //if(nick.charAt(0) != "[" && nick != ""){
885 // var html_nick = $('<div/>').text('<'+nick+'>').html();
886 //} else {
887 var html_nick = $('<div/>').text(nick).html();
888 //}
889
890 var self = this;
891
892 var tmp = msg;
893 var plugin_ret = '';
894 for(var i in plugins.privmsg){
895 if ((plugins.privmsg[i].onprivmsg instanceof Function)) {
896 plugin_ret = '';
897 try {
898 plugin_ret = plugins.privmsg[i].onprivmsg(tmp, this.name);
899
900 // If this plugin has returned false, do not add this message
901 if(plugin_ret === false) return;
902 } catch (e){}
903
904 // If we actually have a string from the plugin, use it
905 if(typeof plugin_ret == "string") tmp = plugin_ret;
906 }
907 }
908 msg = tmp;
909
910 //var html_msg = $('<div/>').text(msg).html()+' '; // Add the space so the styling always has at least 1 character to go from
911 if(time == null){
912 var d = new Date();
913 time = d.getHours().toString().lpad(2, "0") + ":" + d.getMinutes().toString().lpad(2, "0") + ":" + d.getSeconds().toString().lpad(2, "0");
914 }
915
916 // The CSS class (action, topic, notice, etc)
917 if(typeof type != "string") type = '';
918
919 // Make sure we don't have NaN or something
920 if(typeof msg != "string") msg = '';
921
922 // Text formatting
923 // bold
924 if(msg.indexOf(String.fromCharCode(2))){
925 next = '<b>';
926 while(msg.indexOf(String.fromCharCode(2)) != -1){
927 msg = msg.replace(String.fromCharCode(2), next);
928 next = (next=='<b>') ? '</b>' : '<b>';
929 }
930 if(next == '</b>') msg =+ '</b>';
931 }
932
933 // Wierd thing noticed by Dux0r on the irc.esper.net server
934 if(typeof msg != "string") msg = '';
935
936 // underline
937 if(msg.indexOf(String.fromCharCode(31))){
938 next = '<u>';
939 while(msg.indexOf(String.fromCharCode(31)) != -1){
940 msg = msg.replace(String.fromCharCode(31), next);
941 next = (next=='<u>') ? '</u>' : '<u>';
942 }
943 if(next == '</u>') msg =+ '</u>';
944 }
945
946
947 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>');
948 this.div.append(line_msg);
949
950 if(!touchscreen){
951 this.scrollBottom();
952 } else {
953 touch_scroll.refresh();
954 //console.log(this.div.attr("scrollHeight") +" - "+ $('#windows').height());
955 this.scrollBottom();
956 //if(this.div.attr("scrollHeight") > $('#windows').height()){
957 // touch_scroll.scrollTo(0, this.div.height());
958 //}
959 }
960 }
961
962 tabview.prototype.scrollBottom = function(){
963 var w = $('#windows');
964 w.attr({ scrollTop: w.attr("scrollHeight") });
965 }
966
967 tabview.prototype.changeNick = function(newNick, oldNick){
968 this.userlist.children().each(function(){
969 var item = $('a.nick', this);
970 if(front.nickStripPrefix(item.text()) == oldNick){
971 item.text(front.nickGetPrefix(item.text())+newNick);
972 document.temp_chan = 1;
973 }
974 });
975
976 if(typeof document.temp_chan != "undefined"){
977 this.addMsg(null, ' ', '=== '+oldNick+' is now known as '+newNick, 'action');
978 delete document.temp_chan;
979 this.userlistSort();
980 }
981 }
982
983 tabview.prototype.userlistSort = function(){
984 var ul = this.userlist;
985 var listitems = ul.children('li').get();
986 listitems.sort(function(a, b) {
987 var compA = $(a).text().toUpperCase();
988 var compB = $(b).text().toUpperCase();
989
990 // Sort by prefixes first
991 for (var i in gateway.user_prefixes) {
992 prefix = gateway.user_prefixes[i];
993
994 if(compA.charAt(0) == prefix && compB.charAt(0) == prefix){
995 // Both have the same prefix, string compare time
996 return 0;
997 }
998
999 if(compA.charAt(0) == prefix && compB.charAt(0) != prefix){
1000 return -1;
1001 }
1002
1003 if(compA.charAt(0) != prefix && compB.charAt(0) == prefix){
1004 return 1;
1005 }
1006 }
1007
1008 // No prefixes, compare by string
1009 return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
1010 })
1011 $.each(listitems, function(idx, itm) { ul.append(itm); });
1012 }
1013
1014 tabview.prototype.highlight = function(){
1015 this.tab.addClass('highlight');
1016 }
1017 tabview.prototype.activity = function(){
1018 this.tab.addClass('activity');
1019 }
1020 tabview.prototype.clearHighlight = function(){
1021 this.tab.removeClass('highlight');
1022 this.tab.removeClass('activity');
1023 }
1024 tabview.prototype.changeTopic = function(new_topic){
1025 this.topic = new_topic;
1026 this.addMsg(null, ' ', '=== Topic for '+this.name+' is: '+new_topic, 'topic');
1027 if(front.cur_channel.name == this.name) front.setTopicText(new_topic);
1028 }
1029
1030
1031
1032
1033
1034 var box = function(classname){
1035 this.id = randomString(10);
1036 var tmp = $('<div id="'+this.id+'" class="box '+classname+'"><div class="boxarea"></div></div>');
1037 $('#kiwi').append(tmp);
1038 this.box = $('#'+this.id);
1039 this.content = $('#'+this.id+' .boxarea');
1040
1041 this.box.draggable({ stack: ".box" });
1042 this.content.click(function(){});
1043 //this.box.click(function(){ $(this)..css });
1044 }
1045 box.prototype.create = function(name, classname){
1046
1047 }
1048 box.prototype.id = null;
1049 box.prototype.box = null;
1050 box.prototype.content = null;
1051 box.prototype.destroy = function(){
1052 this.box.remove();
1053 for (var name in front.boxes) if(front.boxes[name].id = this.id) delete front.boxes[name];
1054 }
1055 box.prototype.height = function(){ return this.box.height(); }