Logo accreditation
[KiwiIRC.git] / js / front.js
1 /*jslint regexp: true, nomen: true, devel: true, undef: true, browser: true, continue: true, sloppy: true, forin: true, newcap: true, plusplus: true, maxerr: 50, indent: 4 */
2 /*global gateway, io, $, iScroll, agent, touchscreen, init_data, plugs, plugins, registerTouches, randomString */
3 kiwi.front = {
4 revision: 38,
5
6 cur_channel: '',
7 windows: {},
8 tabviews: {},
9 utilityviews: {},
10 boxes: {},
11
12 buffer: [],
13 buffer_pos: 0,
14
15 cache: {},
16
17 original_topic: '',
18
19 init: function () {
20 /*global Box, touch_scroll:true */
21 var about_info, supportsOrientationChange, orientationEvent, scroll_opts;
22 kiwi.gateway.nick = 'kiwi_' + Math.ceil(100 * Math.random()) + Math.ceil(100 * Math.random());
23 kiwi.gateway.session_id = null;
24
25 $(kiwi.gateway).bind("onmsg", kiwi.front.onMsg);
26 $(kiwi.gateway).bind("onnotice", kiwi.front.onNotice);
27 $(kiwi.gateway).bind("onaction", kiwi.front.onAction);
28 $(kiwi.gateway).bind("onmotd", kiwi.front.onMOTD);
29 $(kiwi.gateway).bind("onoptions", kiwi.front.onOptions);
30 $(kiwi.gateway).bind("onconnect", kiwi.front.onConnect);
31 $(kiwi.gateway).bind("onconnect_fail", kiwi.front.onConnectFail);
32 $(kiwi.gateway).bind("ondisconnect", kiwi.front.onDisconnect);
33 $(kiwi.gateway).bind("onnick", kiwi.front.onNick);
34 $(kiwi.gateway).bind("onuserlist", kiwi.front.onUserList);
35 $(kiwi.gateway).bind("onuserlist_end", kiwi.front.onUserListEnd);
36 $(kiwi.gateway).bind("onlist_start", kiwi.front.onChannelListStart);
37 $(kiwi.gateway).bind("onlist_channel", kiwi.front.onChannelList);
38 $(kiwi.gateway).bind("onlist_end", kiwi.front.onChannelListEnd);
39 $(kiwi.gateway).bind("onjoin", kiwi.front.onJoin);
40 $(kiwi.gateway).bind("ontopic", kiwi.front.onTopic);
41 $(kiwi.gateway).bind("onpart", kiwi.front.onPart);
42 $(kiwi.gateway).bind("onkick", kiwi.front.onKick);
43 $(kiwi.gateway).bind("onquit", kiwi.front.onQuit);
44 $(kiwi.gateway).bind("onmode", kiwi.front.onMode);
45 $(kiwi.gateway).bind("onwhois", kiwi.front.onWhois);
46 $(kiwi.gateway).bind("onsync", kiwi.front.onSync);
47 $(kiwi.gateway).bind("onchannel_redirect", kiwi.front.onChannelRedirect);
48 $(kiwi.gateway).bind("ondebug", kiwi.front.onDebug);
49 $(kiwi.gateway).bind("onctcp_request", kiwi.front.onCTCPRequest);
50 $(kiwi.gateway).bind("onctcp_response", kiwi.front.onCTCPResponse);
51 $(kiwi.gateway).bind("onirc_error", kiwi.front.onIRCError);
52 $(kiwi.gateway).bind("onkiwi", kiwi.front.onKiwi);
53
54 this.buffer = [];
55
56 // Build the about box
57 kiwi.front.boxes.about = new Box("about");
58 about_info = 'UI adapted for ' + agent;
59 if (touchscreen) {
60 about_info += ' touchscreen ';
61 }
62 about_info += 'usage';
63 $('#tmpl_about_box').tmpl({
64 about: about_info,
65 front_revision: kiwi.front.revision,
66 gateway_revision: kiwi.gateway.revision
67 }).appendTo(kiwi.front.boxes.about.content);
68
69 //$(window).bind("beforeunload", function(){ kiwi.gateway.quit(); });
70
71 if (touchscreen) {
72 $('#kiwi').addClass('touchscreen');
73
74 // Single touch scrolling through scrollback for touchscreens
75 scroll_opts = {};
76 touch_scroll = new iScroll('windows', scroll_opts);
77 }
78
79 kiwi.front.registerKeys();
80
81 $('#kiwi .toolbars').resize(kiwi.front.doLayoutSize);
82 $(window).resize(kiwi.front.doLayoutSize);
83
84 // Add the resizer for the userlist
85 $('<div id="nicklist_resize" style="position:absolute; cursor:w-resize; width:5px;"></div>').appendTo('#kiwi');
86 $('#nicklist_resize').draggable({axis: "x", drag: function () {
87 var t = $(this),
88 new_width = $(document).width() - parseInt(t.css('left'), 10);
89
90 new_width = new_width - parseInt($('#kiwi .userlist').css('margin-left'), 10);
91 new_width = new_width - parseInt($('#kiwi .userlist').css('margin-right'), 10);
92
93 // Make sure we don't remove the userlist alltogether
94 if (new_width < 20) {
95 $(this).data('draggable').offset.click.left = 10;
96 console.log('whoaa');
97 }
98
99 kiwi.front.cur_channel.setUserlistWidth(new_width);
100 }});
101
102
103 $('#kiwi .formconnectwindow').submit(function () {
104 var netsel = $('#kiwi .formconnectwindow .network'),
105 netport = $('#kiwi .formconnectwindow .port'),
106 netssl = $('#kiwi .formconnectwindow .ssl'),
107 nick = $('#kiwi .formconnectwindow .nick'),
108 tmp;
109
110 if (nick.val() === '') {
111 nick.val('Nick please!');
112 nick.focus();
113 return false;
114 }
115
116 tmp = nick.val().split(' ');
117 kiwi.gateway.nick = tmp[0];
118
119 init_data.channel = $('#channel').val();
120
121 kiwi.front.doLayout();
122 try {
123 kiwi.front.run('/connect ' + netsel.val() + ' ' + netport.val() + ' ' + (netssl.attr('checked') ? 'true' : ''));
124 } catch (e) {
125 console.log(e);
126 }
127
128 $('#kiwi .connectwindow').slideUp('', kiwi.front.barsShow);
129 $('#windows').click(function () { $('#kiwi_msginput').focus(); });
130
131 return false;
132 });
133
134 supportsOrientationChange = (typeof window.onorientationchange !== undefined);
135 orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
136 if (window.addEventListener) {
137 window.addEventListener(orientationEvent, kiwi.front.doLayoutSize, false);
138 } else {
139 // < IE9
140 window.attachEvent(orientationEvent, kiwi.front.doLayoutSize, false);
141 }
142 //$('#kiwi').bind("resize", kiwi.front.doLayoutSize, false);
143
144 kiwi.front.doLayout();
145 kiwi.front.barsHide();
146
147 kiwi.front.tabviewAdd('server');
148 kiwi.front.tabviews.server.userlist_width = 0; // Disable the userlist
149
150 // Any pre-defined nick?
151 if (typeof window.init_data.nick === "string") {
152 $('#kiwi .formconnectwindow .nick').val(init_data.nick);
153 }
154
155 // Any pre-defined channels?
156 if (typeof window.init_data.channel === 'string') {
157 $('#channel').val(init_data.channel);
158 }
159
160 // Fix for Opera inserting a spurious <br/>
161 $('#kiwi .cur_topic br').remove();
162
163 $('#kiwi .cur_topic').keydown(function (e) {
164 if (e.which === 13) {
165 // enter
166 e.preventDefault();
167 $(this).change();
168 $('#kiwi_msginput').focus();
169 } else if (e.which === 27) {
170 // escape
171 e.preventDefault();
172 $(this).text(kiwi.front.original_topic);
173 $('#kiwi_msginput').focus();
174 }
175 });
176 /*$('.cur_topic').live('keypress', function(e) {
177 if (e.keyCode === 13) {
178 // enter
179 e.preventDefault();
180 $(this).change();
181 $('#kiwi_msginput').focus();
182 } else if (e.keyCode === 27) {
183 // escape
184 e.preventDefault();
185 $(this).text(kiwi.front.original_topic);
186 }
187 });*/
188 $('.cur_topic').live('change', function () {
189 var chan, text;
190 text = $(this).text();
191 if (text !== kiwi.front.original_topic) {
192 chan = kiwi.front.cur_channel.name;
193 kiwi.gateway.setTopic(chan, text);
194 }
195 });
196
197
198 $('#windows a.chan').live('click', function () {
199 kiwi.front.joinChannel($(this).text());
200 return false;
201 });
202
203 kiwi.data.set('chanList', []);
204
205 (function () {
206 var i;
207 for (i in plugins) {
208 kiwi.plugs.loadPlugin(plugins[i]);
209 }
210 }());
211 },
212
213 doLayoutSize: function () {
214 var kiwi, toolbars, ul, n_top, n_bottom, nl;
215 kiwi = $('#kiwi');
216
217 if (kiwi.width() < 330 && !kiwi.hasClass('small_kiwi')) {
218 console.log("switching to small kiwi");
219 kiwi.removeClass('large_kiwi');
220 kiwi.addClass('small_kiwi');
221 } else if (kiwi.width() >= 330 && !kiwi.hasClass('large_kiwi')) {
222 kiwi.removeClass('small_kiwi');
223 kiwi.addClass('large_kiwi');
224 }
225
226 toolbars = $('#kiwi .cur_topic');
227 ul = $('#kiwi .userlist');
228
229 n_top = parseInt(toolbars.offset().top, 10) + parseInt(toolbars.outerHeight(true), 10);
230 n_bottom = $(document).height() - parseInt($('#kiwi .control').offset().top, 10);
231
232 $('#kiwi .windows').css({top: n_top + 'px', bottom: n_bottom + 'px'});
233 ul.css({top: n_top + 'px', bottom: n_bottom + 'px'});
234
235 nl = $('#nicklist_resize');
236 nl.css({top: n_top + 'px', bottom: n_bottom + 'px', left: $(document).width() - ul.outerWidth(true)});
237 },
238
239
240 doLayout: function () {
241 $('#kiwi .msginput .nick a').text(kiwi.gateway.nick);
242 $('#kiwi_msginput').val(' ');
243 $('#kiwi_msginput').focus();
244 },
245
246
247 joinChannel: function (chan_name) {
248 var chans = chan_name.split(','),
249 i,
250 chan;
251 for (i in chans) {
252 chan = chans[i];
253 if (kiwi.front.tabviews[chan.toLowerCase()] === undefined || (kiwi.front.tabviews[chan.toLowerCase()] !== undefined && kiwi.front.tabviews[chan.toLowerCase()].safe_to_close === true)) {
254 kiwi.gateway.join(chan);
255 kiwi.front.tabviewAdd(chan);
256 } else {
257 kiwi.front.tabviews[chan.toLowerCase()].show();
258 }
259 }
260 },
261
262
263 run: function (msg) {
264 var parts, dest, t, pos, textRange, d, plugin_event, msg_sliced;
265
266 // Run through any plugins
267 plugin_event = {command: msg};
268 plugin_event = kiwi.plugs.run('command_run', plugin_event);
269 if (!plugin_event || typeof plugin_event.command === 'undefined') {
270 return;
271 }
272
273 // Update msg if it's been changed by any plugins
274 msg = plugin_event.command.toString();
275
276 console.log("running " + msg);
277 if (msg.substring(0, 1) === '/') {
278 parts = msg.split(' ');
279 switch (parts[0].toLowerCase()) {
280 case '/j':
281 case '/join':
282 kiwi.front.joinChannel(parts[1]);
283 break;
284
285 case '/connect':
286 case '/server':
287 if (typeof parts[1] === 'undefined') {
288 alert('Usage: /connect servername [port] [ssl]');
289 break;
290 }
291
292 if (typeof parts[2] === 'undefined') {
293 parts[2] = 6667;
294 }
295
296 if ((typeof parts[3] === 'undefined') || !parts[3] || (parts[3] === 'false') || (parts[3] === 'no')) {
297 parts[3] = false;
298 } else {
299 parts[3] = true;
300 }
301
302 kiwi.front.cur_channel.addMsg(null, ' ', '=== Connecting to ' + parts[1] + ' on port ' + parts[2] + (parts[3] ? ' using SSL' : '') + '...', 'status');
303 kiwi.gateway.connect(parts[1], parts[2], parts[3]);
304 break;
305
306 case '/nick':
307 console.log("/nick");
308 if (parts[1] === undefined) {
309 console.log("calling show nick");
310 kiwi.front.showChangeNick();
311 } else {
312 console.log("sending raw");
313 kiwi.gateway.raw(msg.substring(1));
314 }
315 break;
316
317 case '/part':
318 if (typeof parts[1] === "undefined") {
319 if (kiwi.front.cur_channel.safe_to_close) {
320 kiwi.front.cur_channel.close();
321 } else {
322 kiwi.gateway.raw(msg.substring(1) + ' ' + kiwi.front.cur_channel.name);
323 }
324 } else {
325 kiwi.gateway.raw(msg.substring(1));
326 }
327 break;
328
329 case '/names':
330 if (typeof parts[1] !== "undefined") {
331 kiwi.gateway.raw(msg.substring(1));
332 }
333 break;
334
335 case '/debug':
336 kiwi.gateway.debug();
337 break;
338
339 case '/q':
340 case '/query':
341 if (typeof parts[1] !== "undefined") {
342 kiwi.front.tabviewAdd(parts[1]);
343 }
344 break;
345
346
347 case '/m':
348 case '/msg':
349 if (typeof parts[1] !== "undefined") {
350 msg_sliced = msg.split(' ').slice(2).join(' ');
351 kiwi.gateway.msg(parts[1], msg_sliced);
352
353 if (!kiwi.front.tabviewExists(parts[1])) {
354 kiwi.front.tabviewAdd(parts[1]);
355 }
356 kiwi.front.tabviews[parts[1].toLowerCase()].addMsg(null, kiwi.gateway.nick, msg_sliced);
357 }
358 break;
359
360 case '/k':
361 case '/kick':
362 if (typeof parts[1] === 'undefined') {
363 return;
364 }
365 kiwi.gateway.raw('KICK ' + kiwi.front.cur_channel.name + ' ' + msg.split(' ', 2)[1]);
366 break;
367
368 case '/quote':
369 kiwi.gateway.raw(msg.replace(/^\/quote /i, ''));
370 break;
371
372 case '/me':
373 kiwi.gateway.action(kiwi.front.cur_channel.name, msg.substring(4));
374 //kiwi.front.tabviews[destination.toLowerCase()].addMsg(null, ' ', '* '+data.nick+' '+data.msg, 'color:green;');
375 kiwi.front.cur_channel.addMsg(null, ' ', '* ' + kiwi.gateway.nick + ' ' + msg.substring(4), 'action', 'color:#555;');
376 break;
377
378 case '/notice':
379 dest = parts[1];
380 msg = parts.slice(2).join(' ');
381
382 kiwi.gateway.notice(dest, msg);
383 this.onNotice({}, {nick: kiwi.gateway.nick, channel: dest, msg: msg});
384 break;
385
386 case '/win':
387 if (parts[1] !== undefined) {
388 kiwi.front.windowsShow(parseInt(parts[1], 10));
389 }
390 break;
391
392 case '/quit':
393 kiwi.gateway.quit(parts.slice(1).join(' '));
394 break;
395
396 case '/topic':
397 if (parts[1] === undefined) {
398 t = $('.cur_topic');
399 if (t.createTextRange) {
400 pos = t.text().length();
401 textRange = t.createTextRange();
402 textRange.collapse(true);
403 textRange.moveEnd(pos);
404 textRange.moveStart(pos);
405 textRange.select();
406 } else if (t.setSelectionRange) {
407 t.setSelectionRange(pos, pos);
408 }
409 } else {
410 kiwi.gateway.setTopic(kiwi.front.cur_channel.name, msg.split(' ', 2)[1]);
411 //kiwi.gateway.raw('TOPIC ' + kiwi.front.cur_channel.name + ' :' + msg.split(' ', 2)[1]);
412 }
413 break;
414
415 case '/kiwi':
416 kiwi.gateway.kiwi(kiwi.front.cur_channel.name, msg.substring(6));
417 break;
418
419 default:
420 //kiwi.front.cur_channel.addMsg(null, ' ', '--> Invalid command: '+parts[0].substring(1));
421 kiwi.gateway.raw(msg.substring(1));
422 }
423
424 } else {
425 //alert('Sending message: '+msg);
426 if (msg.trim() === '') {
427 return;
428 }
429 if (kiwi.front.cur_channel.name !== 'server') {
430 kiwi.gateway.msg(kiwi.front.cur_channel.name, msg);
431 d = new Date();
432 d = d.getHours() + ":" + d.getMinutes();
433 //kiwi.front.addMsg(d, kiwi.gateway.nick, msg);
434 kiwi.front.cur_channel.addMsg(null, kiwi.gateway.nick, msg);
435 }
436 }
437 },
438
439
440 onMsg: function (e, data) {
441 var destination, plugin_event;
442 // Is this message from a user?
443 if (data.channel === kiwi.gateway.nick) {
444 destination = data.nick.toLowerCase();
445 } else {
446 destination = data.channel.toLowerCase();
447 }
448
449 plugin_event = {nick: data.nick, msg: data.msg, destination: destination};
450 plugin_event = kiwi.plugs.run('msg_recieved', plugin_event);
451 if (!plugin_event) {
452 return;
453 }
454
455 if (!kiwi.front.tabviewExists(plugin_event.destination)) {
456 kiwi.front.tabviewAdd(plugin_event.destination);
457 }
458 kiwi.front.tabviews[plugin_event.destination].addMsg(null, plugin_event.nick, plugin_event.msg);
459 },
460
461 onDebug: function (e, data) {
462 if (!kiwi.front.tabviewExists('kiwi_debug')) {
463 kiwi.front.tabviewAdd('kiwi_debug');
464 }
465 kiwi.front.tabviews.kiwi_debug.addMsg(null, ' ', data.msg);
466 },
467
468 onAction: function (e, data) {
469 var destination;
470 // Is this message from a user?
471 if (data.channel === kiwi.gateway.nick) {
472 destination = data.nick;
473 } else {
474 destination = data.channel;
475 }
476
477 if (!kiwi.front.tabviewExists(destination)) {
478 kiwi.front.tabviewAdd(destination);
479 }
480 kiwi.front.tabviews[destination.toLowerCase()].addMsg(null, ' ', '* ' + data.nick + ' ' + data.msg, 'action', 'color:#555;');
481 },
482
483 onTopic: function (e, data) {
484 if (kiwi.front.tabviewExists(data.channel)) {
485 kiwi.front.tabviews[data.channel.toLowerCase()].changeTopic(data.topic);
486 }
487 },
488
489 onNotice: function (e, data) {
490 var nick = (data.nick === undefined) ? '' : data.nick,
491 enick = '[' + nick + ']';
492
493 if (kiwi.front.tabviewExists(data.target)) {
494 kiwi.front.tabviews[data.target.toLowerCase()].addMsg(null, enick, data.msg, 'notice');
495 } else if (kiwi.front.tabviewExists(nick)) {
496 kiwi.front.tabviews[nick.toLowerCase()].addMsg(null, enick, data.msg, 'notice');
497 } else {
498 kiwi.front.tabviews.server.addMsg(null, enick, data.msg, 'notice');
499 }
500 },
501
502 onCTCPRequest: function (e, data) {
503 var msg = data.msg.split(" ", 2);
504 switch (msg[0]) {
505 case 'PING':
506 if (typeof msg[1] === 'undefined') {
507 msg[1] = '';
508 }
509 kiwi.gateway.notice(data.nick, String.fromCharCode(1) + 'PING ' + msg[1] + String.fromCharCode(1));
510 break;
511 case 'TIME':
512 kiwi.gateway.notice(data.nick, String.fromCharCode(1) + 'TIME ' + (new Date()).toLocaleString() + String.fromCharCode(1));
513 break;
514 }
515 kiwi.front.tabviews.server.addMsg(null, 'CTCP [' + data.nick + ']', data.msg, 'ctcp');
516 },
517
518 onCTCPResponse: function (e, data) {
519 },
520
521 onKiwi: function (e, data) {
522 //console.log(data);
523 },
524
525 onConnect: function (e, data) {
526 if (data.connected) {
527 if (kiwi.gateway.nick !== data.nick) {
528 kiwi.gateway.nick = data.nick;
529 kiwi.front.doLayout();
530 }
531
532 kiwi.front.tabviews.server.addMsg(null, ' ', '=== Connected OK :)', 'status');
533 if (typeof init_data.channel === "string") {
534 kiwi.front.joinChannel(init_data.channel);
535 }
536 kiwi.plugs.run('connect', {success: true});
537 } else {
538 kiwi.front.tabviews.server.addMsg(null, ' ', '=== Failed to connect :(', 'status');
539 kiwi.plugs.run('connect', {success: false});
540 }
541 },
542 onConnectFail: function (e, data) {
543 var reason = (typeof data.reason === 'string') ? data.reason : '';
544 kiwi.front.tabviews.server.addMsg(null, '', 'There\'s a problem connecting! (' + reason + ')', 'error');
545 kiwi.plugs.run('connect', {success: false});
546 },
547 onDisconnect: function (e, data) {
548 var tab;
549 for (tab in kiwi.front.tabviews) {
550 kiwi.front.tabviews[tab].addMsg(null, '', 'Disconnected from server!', 'error');
551 }
552 kiwi.plugs.run('disconnect', {success: false});
553 },
554 onOptions: function (e, data) {
555 if (typeof kiwi.gateway.network_name === "string" && kiwi.gateway.network_name !== "") {
556 kiwi.front.tabviews.server.tab.text(kiwi.gateway.network_name);
557 }
558 },
559 onMOTD: function (e, data) {
560 kiwi.front.tabviews.server.addMsg(null, data.server, data.msg, 'motd');
561 },
562 onWhois: function (e, data) {
563 var d;
564 if (data.msg) {
565 kiwi.front.cur_channel.addMsg(null, data.nick, data.msg, 'whois');
566 } else if (data.logon) {
567 d = new Date();
568 d.setTime(data.logon * 1000);
569 d = d.toLocaleString();
570 kiwi.front.cur_channel.addMsg(null, data.nick, 'idle for ' + data.idle + ' second' + ((data.idle !== 1) ? 's' : '') + ', signed on ' + d, 'whois');
571 } else {
572 kiwi.front.cur_channel.addMsg(null, data.nick, 'idle for ' + data.idle + ' seconds', 'whois');
573 }
574 },
575 onMode: function (e, data) {
576 var i, new_nick_text;
577
578 // TODO: Store the modes in the elements data, then work out the current
579 // mode symbol from the highest mode. Eg. -h may leave +o from previous modes; It
580 // doesn't simply clear it! ~Darren
581 if (typeof data.channel === 'string' && typeof data.effected_nick === 'string') {
582 kiwi.front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '[' + data.mode + '] ' + data.effected_nick + ' by ' + data.nick, 'mode', '');
583 kiwi.front.tabviews[data.channel.toLowerCase()].userlist.children().each(function () {
584 if (kiwi.front.nickStripPrefix($(this).text()) === data.effected_nick) {
585
586 if (data.mode.split('')[0] === '+') {
587 for (i = 0; i < kiwi.gateway.user_prefixes.length; i++) {
588 if (kiwi.gateway.user_prefixes[i].mode === data.mode.split('')[1]) {
589 new_nick_text = kiwi.gateway.user_prefixes[i].symbol + data.effected_nick;
590 break;
591 }
592 }
593 } else if (data.mode.split('')[0] === '-') {
594 new_nick_text = data.effected_nick;
595 }
596
597 if (new_nick_text !== '') {
598 $(this).text(new_nick_text);
599 return false;
600 }
601
602 }
603 });
604 }
605 },
606 onUserList: function (e, data) {
607 var ul, nick, mode;
608 if (kiwi.front.tabviews[data.channel.toLowerCase()] === undefined) {
609 return;
610 }
611 ul = kiwi.front.tabviews[data.channel.toLowerCase()].userlist;
612
613 if (!document.userlist_updating) {
614 document.userlist_updating = true;
615 ul.empty();
616 }
617
618 $.each(data.users, function (i, item) {
619 nick = i; //i.match(/^.+!/g);
620 mode = item;
621 $('<li><a class="nick" onclick="kiwi.front.userClick(this);">' + mode + nick + '</a></li>').appendTo(ul);
622 });
623
624 kiwi.front.tabviews[data.channel.toLowerCase()].userlistSort();
625 },
626 onUserListEnd: function (e, data) {
627 document.userlist_updating = false;
628 },
629
630 onChannelListStart: function (e, data) {
631 var tab, table;
632
633 tab = new Utilityview('Channel List');
634 tab.div.css('overflow-y', 'scroll');
635 table = $('<table style="margin:1em 2em;"><thead style="font-weight: bold;"><tr><td>Channel Name</td><td>Members</td><td style="padding-left: 2em;">Topic</td></tr></thead><tbody style="vertical-align: top;"></tbody>');
636 tab.div.append(table);
637
638 kiwi.front.cache.list = {chans: [], tab: tab, table: table,
639 update: function (newChans) {
640 var body = this.table.children('tbody:first').detach(),
641 chan,
642 html;
643
644 html = '';
645 for (chan in newChans) {
646 this.chans.push(newChans[chan]);
647 html += newChans[chan].html;
648 }
649 body.append(html);
650 this.table.append(body);
651
652 },
653 finalise: function () {
654 var body = this.table.children('tbody:first').detach(),
655 list,
656 chan;
657
658 list = $.makeArray($(body).children());
659
660 for (chan in list) {
661 list[chan] = $(list[chan]).detach();
662 }
663
664 list = _.sortBy(list, function (channel) {
665 return parseInt(channel.children('.num_users').first().text(), 10);
666 }).reverse();
667
668 for (chan in list) {
669 body.append(list[chan]);
670 }
671
672 this.table.append(body);
673
674 }};
675 },
676 onChannelList: function (e, data) {
677 var chans;
678 console.log(data);
679 data = data.chans;
680 //data = [data];
681 for (chans in data) {
682 data[chans] = {data: data[chans], html: '<tr><td><a class="chan">' + data[chans].channel + '</a></td><td class="num_users" style="text-align: center;">' + data[chans].num_users + '</td><td style="padding-left: 2em;">' + kiwi.front.format(data[chans].topic) + '</td></tr>'};
683 }
684 kiwi.front.cache.list.update(data);
685 },
686 onChannelListEnd: function (e, data) {
687 kiwi.front.cache.list.finalise();
688 kiwi.front.cache.list.tab.show();
689 },
690
691
692 onJoin: function (e, data) {
693 if (!kiwi.front.tabviewExists(data.channel)) {
694 kiwi.front.tabviewAdd(data.channel.toLowerCase());
695 }
696
697 if (data.nick === kiwi.gateway.nick) {
698 return; // Not needed as it's already in nicklist
699 }
700 kiwi.front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '--> ' + data.nick + ' has joined', 'action join', 'color:#009900;');
701 $('<li><a class="nick" onclick="kiwi.front.userClick(this);">' + data.nick + '</a></li>').appendTo(kiwi.front.tabviews[data.channel.toLowerCase()].userlist);
702 kiwi.front.tabviews[data.channel.toLowerCase()].userlistSort();
703 },
704 onPart: function (e, data) {
705 if (kiwi.front.tabviewExists(data.channel)) {
706 // If this is us, close the tabview
707 if (data.nick === kiwi.gateway.nick) {
708 kiwi.front.tabviews[data.channel.toLowerCase()].close();
709 kiwi.front.tabviews.server.show();
710 return;
711 }
712
713 kiwi.front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '<-- ' + data.nick + ' has left (' + data.message + ')', 'action part', 'color:#990000;');
714 kiwi.front.tabviews[data.channel.toLowerCase()].userlist.children().each(function () {
715 if ($(this).text() === data.nick) {
716 $(this).remove();
717 }
718 });
719 }
720 },
721 onKick: function (e, data) {
722 if (kiwi.front.tabviewExists(data.channel)) {
723 // If this is us, close the tabview
724 if (data.kicked === kiwi.gateway.nick) {
725 //kiwi.front.tabviews[data.channel.toLowerCase()].close();
726 kiwi.front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '=== You have been kicked from ' + data.channel + '. ' + data.message, 'status kick');
727 kiwi.front.tabviews[data.channel.toLowerCase()].safe_to_close = true;
728 $('li', kiwi.front.tabviews[data.channel.toLowerCase()].userlist).remove();
729 return;
730 }
731
732 kiwi.front.tabviews[data.channel.toLowerCase()].addMsg(null, ' ', '<-- ' + data.kicked + ' kicked by ' + data.nick + '(' + data.message + ')', 'action kick', 'color:#990000;');
733 kiwi.front.tabviews[data.channel.toLowerCase()].userlist.children().each(function () {
734 if ($(this).text() === data.nick) {
735 $(this).remove();
736 }
737 });
738 }
739 },
740 onNick: function (e, data) {
741 if (data.nick === kiwi.gateway.nick) {
742 kiwi.gateway.nick = data.newnick;
743 kiwi.front.doLayout();
744 }
745
746 $.each(kiwi.front.tabviews, function (i, item) {
747 $.each(kiwi.front.tabviews, function (i, item) {
748 item.changeNick(data.newnick, data.nick);
749 });
750 });
751 },
752 onQuit: function (e, data) {
753 $.each(kiwi.front.tabviews, function (i, item) {
754 $.each(kiwi.front.tabviews, function (i, item) {
755 item.userlist.children().each(function () {
756 if ($(this).text() === data.nick) {
757 $(this).remove();
758 item.addMsg(null, ' ', '<-- ' + data.nick + ' has quit (' + data.message + ')', 'action quit', 'color:#990000;');
759 }
760 });
761 });
762 });
763 },
764 onChannelRedirect: function (e, data) {
765 kiwi.front.tabviews[data.from.toLowerCase()].close();
766 kiwi.front.tabviewAdd(data.to.toLowerCase());
767 kiwi.front.tabviews[data.to.toLowerCase()].addMsg(null, ' ', '=== Redirected from ' + data.from, 'action');
768 },
769
770 onIRCError: function (e, data) {
771 var t_view;
772 if (data.channel !== undefined && kiwi.front.tabviewExists(data.channel)) {
773 t_view = data.channel;
774 } else {
775 t_view = 'server';
776 }
777
778 switch (data.error) {
779 case 'banned_from_channel':
780 kiwi.front.tabviews[t_view].addMsg(null, ' ', '=== You are banned from ' + data.channel + '. ' + data.reason, 'status');
781 if (t_view !== 'server') {
782 kiwi.front.tabviews[t_view].safe_to_close = true;
783 }
784 break;
785 case 'bad_channel_key':
786 kiwi.front.tabviews[t_view].addMsg(null, ' ', '=== Bad channel key for ' + data.channel, 'status');
787 if (t_view !== 'server') {
788 kiwi.front.tabviews[t_view].safe_to_close = true;
789 }
790 break;
791 case 'invite_only_channel':
792 kiwi.front.tabviews[t_view].addMsg(null, ' ', '=== ' + data.channel + ' is invite only.', 'status');
793 if (t_view !== 'server') {
794 kiwi.front.tabviews[t_view].safe_to_close = true;
795 }
796 break;
797 case 'channel_is_full':
798 kiwi.front.tabviews[t_view].addMsg(null, ' ', '=== ' + data.channel + ' is full.', 'status');
799 if (t_view !== 'server') {
800 kiwi.front.tabviews[t_view].safe_to_close = true;
801 }
802 break;
803 case 'chanop_privs_needed':
804 kiwi.front.tabviews[data.channel].addMsg(null, ' ', '=== ' + data.reason, 'status');
805 break;
806 case 'no_such_nick':
807 kiwi.front.tabviews.server.addMsg(null, ' ', '=== ' + data.nick + ': ' + data.reason, 'status');
808 break;
809 case 'nickname_in_use':
810 kiwi.front.tabviews.server.addMsg(null, ' ', '=== The nickname ' + data.nick + ' is already in use. Please select a new nickname', 'status');
811 kiwi.front.showChangeNick();
812 break;
813 default:
814 // We don't know what data contains, so don't do anything with it.
815 //kiwi.front.tabviews.server.addMsg(null, ' ', '=== ' + data, 'status');
816 }
817 },
818
819 registerKeys: function () {
820 var tabcomplete = {active: false, data: [], prefix: ''};
821 $('#kiwi_msginput').bind('keydown', function (e) {
822 var windows, meta, num, msg, data, candidates, word_pos, word, i, self;
823 windows = $('#windows');
824 //var meta = e.altKey;
825 meta = e.ctrlKey;
826
827 if (e.which !== 9) {
828 tabcomplete.active = false;
829 tabcomplete.data = [];
830 tabcomplete.prefix = '';
831 }
832
833 switch (true) {
834 case (e.which >= 48) && (e.which <= 57):
835 if (meta) {
836 num = e.which - 48;
837 if (num === 0) {
838 num = 10;
839 }
840 num = num - 1;
841 kiwi.front.windowsShow(num);
842 return false;
843 }
844 break;
845 case e.which === 27: // escape
846 return false;
847 case e.which === 13: // return
848 msg = $('#kiwi_msginput').val();
849 msg = msg.trim();
850
851 kiwi.front.buffer.push(msg);
852 kiwi.front.buffer_pos = kiwi.front.buffer.length;
853
854 kiwi.front.run(msg);
855 $('#kiwi_msginput').val('');
856
857 break;
858 case e.which === 33: // page up
859 console.log("page up");
860 windows[0].scrollTop = windows[0].scrollTop - windows.height();
861 return false;
862 case e.which === 34: // page down
863 windows[0].scrollTop = windows[0].scrollTop + windows.height();
864 return false;
865 case e.which === 37: // left
866 if (meta) {
867 kiwi.front.windowsPrevious();
868 return false;
869 }
870 break;
871 case e.which === 38: // up
872 if (kiwi.front.buffer_pos > 0) {
873 kiwi.front.buffer_pos--;
874 $('#kiwi_msginput').val(kiwi.front.buffer[kiwi.front.buffer_pos]);
875 }
876 break;
877 case e.which === 39: // right
878 if (meta) {
879 kiwi.front.windowsNext();
880 return false;
881 }
882 break;
883 case e.which === 40: // down
884 if (kiwi.front.buffer_pos < kiwi.front.buffer.length) {
885 kiwi.front.buffer_pos++;
886 $('#kiwi_msginput').val(kiwi.front.buffer[kiwi.front.buffer_pos]);
887 }
888 break;
889
890 case e.which === 9: // tab
891 tabcomplete.active = true;
892 if (_.isEqual(tabcomplete.data, [])) {
893 // Get possible autocompletions
894 data = [];
895 kiwi.front.cur_channel.userlist.children().each(function () {
896 var nick;
897 nick = kiwi.front.nickStripPrefix($('a.nick', this).text());
898 data.push(nick);
899 });
900 data = _.sortBy(data, function (nick) {
901 return nick;
902 });
903 tabcomplete.data = data;
904 }
905
906 if (this.value[this.selectionStart - 1] === ' ') {
907 return false;
908 }
909 self = this;
910 (function () {
911 var tokens = self.value.substring(0, self.selectionStart).split(" "),
912 val,
913 p1,
914 newnick,
915 range;
916 nick = tokens[tokens.length - 1];
917 if (tabcomplete.prefix === '') {
918 tabcomplete.prefix = nick;
919 }
920
921 tabcomplete.data = _.select(tabcomplete.data, function (n) {
922 return (n.toLowerCase().indexOf(tabcomplete.prefix.toLowerCase()) === 0);
923 });
924
925 if (tabcomplete.data.length > 0) {
926 p1 = self.selectionStart - (nick.length);
927 val = self.value.substr(0, p1);
928 newnick = tabcomplete.data.shift();
929 tabcomplete.data.push(newnick);
930 val += newnick;
931 val += self.value.substr(self.selectionStart);
932 self.value = val;
933 if (self.setSelectionRange) {
934 self.setSelectionRange(p1 + newnick.length, p1 + newnick.length);
935 } else if (self.createTextRange) { // not sure if this bit is actually needed....
936 range = self.createTextRange();
937 range.collapse(true);
938 range.moveEnd('character', p1 + newnick.length);
939 range.moveStart('character', p1 + newnick.length);
940 range.select();
941 }
942 }
943 }());
944 return false;
945 }
946 });
947
948
949 $('#kiwi .control .msginput .nick').click(function () {
950 kiwi.front.showChangeNick();
951 });
952
953
954
955
956
957 $('#kiwi .plugins .load_plugin_file').click(function () {
958 if (typeof kiwi.front.boxes.plugins !== "undefined") {
959 return;
960 }
961
962 kiwi.front.boxes.plugins = new Box("plugin_file");
963 $('#tmpl_plugins').tmpl({}).appendTo(kiwi.front.boxes.plugins.content);
964 kiwi.front.boxes.plugins.box.css('top', -(kiwi.front.boxes.plugins.height + 40));
965
966 // Populate the plugin list..
967 function enumPlugins() {
968 var lst, j, txt;
969 lst = $('#plugin_list');
970 lst.find('option').remove();
971 for (j in kiwi.plugs.loaded) {
972 txt = kiwi.plugs.loaded[j].name;
973 lst.append('<option value="' + txt + '">' + txt + '</option>');
974 }
975 }
976 enumPlugins();
977
978 // Event bindings
979 $('#kiwi .plugin_file').submit(function () {
980 $('<div></div>').load($('.txtpluginfile').val(), function (e) {
981 enumPlugins();
982 });
983 return false;
984 });
985 $('#kiwi .cancelpluginfile').click(function () {
986 kiwi.front.boxes.plugins.destroy();
987 });
988
989 $('#kiwi #plugins_list_unload').click(function () {
990 var selected_plugin;
991 selected_plugin = $('#plugin_list').val();
992 kiwi.plugs.unloadPlugin(selected_plugin);
993 enumPlugins();
994 });
995
996 $('#kiwi .txtpluginfile').focus();
997
998 });
999
1000 $('#kiwi .plugins .reload_css').click(function () {
1001 var links = document.getElementsByTagName("link"),
1002 i;
1003 for (i = 0; i < links.length; i++) {
1004 if (links[i].rel === "stylesheet") {
1005 if (links[i].href.indexOf("?") === -1) {
1006 links[i].href += "?";
1007 }
1008 links[i].href += "x";
1009 }
1010 }
1011 });
1012
1013
1014 $('#kiwi .about .about_close').click(function () {
1015 $('#kiwi .about').css('display', 'none');
1016 });
1017
1018
1019 $('#kiwi .poweredby').click(function () {
1020 $('#kiwi .about').css('display', 'block');
1021 });
1022
1023 },
1024
1025
1026 showChangeNick: function () {
1027 $('#kiwi').append($('#tmpl_change_nick').tmpl({}));
1028
1029 $('#kiwi .form_newnick').submit(function () {
1030 kiwi.front.run('/NICK ' + $('#kiwi .txtnewnick').val());
1031 $('#kiwi .newnick').remove();
1032 return false;
1033 });
1034
1035 $('#kiwi .txtnewnick').keypress(function (ev) {
1036 if (!this.first_press) {
1037 this.first_press = true;
1038 return false;
1039 }
1040 });
1041
1042 $('#kiwi .txtnewnick').keydown(function (ev) {
1043 if (ev.which === 27) { // ESC
1044 $('#kiwi_msginput').focus();
1045 $('#kiwi .newnick').remove();
1046 }
1047 });
1048
1049 $('#kiwi .cancelnewnick').click(function () {
1050 $('#kiwi .newnick').remove();
1051 });
1052
1053 $('#kiwi .txtnewnick').focus();
1054 },
1055
1056
1057 tabviewExists: function (name) {
1058 return (typeof kiwi.front.tabviews[name.toLowerCase()] !== 'undefined');
1059 },
1060
1061 tabviewAdd: function (v_name) {
1062 /*global Tabview */
1063 var re, htmlsafe_name, tmp_divname, tmp_userlistname, tmp_tabname, userlist_enabled = true;
1064
1065 if (v_name.charAt(0) === kiwi.gateway.channel_prefix) {
1066 re = new RegExp(kiwi.gateway.channel_prefix, "g");
1067 htmlsafe_name = v_name.replace(re, 'pre');
1068 htmlsafe_name = "chan_" + htmlsafe_name;
1069 } else {
1070 htmlsafe_name = 'query_' + v_name;
1071 userlist_enabled = false;
1072 }
1073
1074 tmp_divname = 'kiwi_window_' + htmlsafe_name;
1075 tmp_userlistname = 'kiwi_userlist_' + htmlsafe_name;
1076 tmp_tabname = 'kiwi_tab_' + htmlsafe_name;
1077
1078 if (!kiwi.front.tabviewExists(v_name)) {
1079 $('#kiwi .windows .scroller').append('<div id="' + tmp_divname + '" class="messages"></div>');
1080 $('#kiwi .userlist').append('<ul id="' + tmp_userlistname + '"></ul>');
1081 $('#kiwi .windowlist ul').append('<li id="' + tmp_tabname + '" onclick="kiwi.front.tabviews[\'' + v_name.toLowerCase() + '\'].show();">' + v_name + '</li>');
1082 }
1083 //$('#kiwi .windowlist ul .window_'+v_name).click(function(){ kiwi.front.windowShow(v_name); });
1084 //kiwi.front.windowShow(v_name);
1085
1086 kiwi.front.tabviews[v_name.toLowerCase()] = new Tabview();
1087 kiwi.front.tabviews[v_name.toLowerCase()].name = v_name;
1088 kiwi.front.tabviews[v_name.toLowerCase()].div = $('#' + tmp_divname);
1089 kiwi.front.tabviews[v_name.toLowerCase()].userlist = $('#' + tmp_userlistname);
1090 kiwi.front.tabviews[v_name.toLowerCase()].tab = $('#' + tmp_tabname);
1091 if (!userlist_enabled) {
1092 kiwi.front.tabviews[v_name.toLowerCase()].userlist_width = 0;
1093 }
1094 kiwi.front.tabviews[v_name.toLowerCase()].show();
1095
1096 if (typeof registerTouches === "function") {
1097 //alert("Registering touch interface");
1098 //registerTouches($('#'+tmp_divname));
1099 registerTouches(document.getElementById(tmp_divname));
1100 }
1101 /*
1102 kiwi.front.tabviews[v_name.toLowerCase()].userlist.click(function(){
1103 alert($(this).attr('id'));
1104 });
1105 */
1106
1107 kiwi.front.doLayoutSize();
1108 },
1109
1110
1111 userClick: function (item) {
1112 var li = $(item).parent();
1113
1114 // Remove any existing userboxes
1115 $('#kiwi .userbox').remove();
1116
1117 if ($(li).data('userbox') === item) {
1118 $(li).removeData('userbox');
1119 } else {
1120 $('#tmpl_user_box').tmpl({nick: kiwi.front.nickStripPrefix($(item).text())}).appendTo(li);
1121
1122 $('#kiwi .userbox .userbox_query').click(function (ev) {
1123 var nick = $('#kiwi .userbox_nick').val();
1124 kiwi.front.run('/query ' + nick);
1125 });
1126
1127 $('#kiwi .userbox .userbox_whois').click(function (ev) {
1128 var nick = $('#kiwi .userbox_nick').val();
1129 kiwi.front.run('/whois ' + nick);
1130 });
1131 $(li).data('userbox', item);
1132 }
1133 },
1134
1135
1136 sync: function () {
1137 kiwi.gateway.sync();
1138 },
1139
1140 onSync: function (e, data) {
1141 // Set any settings
1142 if (data.nick !== undefined) {
1143 kiwi.gateway.nick = data.nick;
1144 }
1145
1146 // Add the tabviews
1147 if (data.tabviews !== undefined) {
1148 $.each(data.tabviews, function (i, tab) {
1149 if (!kiwi.front.tabviewExists(tab.name)) {
1150 kiwi.front.tabviewAdd(kiwi.gateway.channel_prefix + tab.name);
1151
1152 if (tab.userlist !== undefined) {
1153 kiwi.front.onUserList({'channel': kiwi.gateway.channel_prefix + tab.name, 'users': tab.userlist});
1154 }
1155 }
1156 });
1157 }
1158
1159 kiwi.front.doLayout();
1160 },
1161
1162
1163 setTopicText: function (new_topic) {
1164 kiwi.front.original_topic = new_topic;
1165 $('#kiwi .cur_topic .topic').text(new_topic);
1166 kiwi.front.doLayoutSize();
1167 },
1168
1169 nickStripPrefix: function (nick) {
1170 var tmp = nick, i, prefix;
1171
1172 prefix = tmp.charAt(0);
1173 for (i in kiwi.gateway.user_prefixes) {
1174 if (kiwi.gateway.user_prefixes[i].symbol === prefix) {
1175 return tmp.substring(1);
1176 }
1177 }
1178
1179 return tmp;
1180 },
1181
1182 nickGetPrefix: function (nick) {
1183 var tmp = nick, i, prefix;
1184
1185 prefix = tmp.charAt(0);
1186 for (i in kiwi.gateway.user_prefixes) {
1187 if (kiwi.gateway.user_prefixes[i].symbol === prefix) {
1188 return prefix;
1189 }
1190 }
1191
1192 return '';
1193 },
1194
1195 isChannel: function (name) {
1196 var prefix, is_chan;
1197 prefix = name.charAt(0);
1198 if (kiwi.gateway.channel_prefix.indexOf(prefix) > -1) {
1199 is_chan = true;
1200 } else {
1201 is_chan = false;
1202 }
1203
1204 return is_chan;
1205 },
1206
1207 tabviewsNext: function () {
1208 var wl = $('#kiwi .windowlist ul'),
1209 next_left = parseInt(wl.css('text-indent').replace('px', ''), 10) + 170;
1210 wl.css('text-indent', next_left);
1211 },
1212
1213 tabviewsPrevious: function () {
1214 var wl = $('#kiwi .windowlist ul'),
1215 next_left = parseInt(wl.css('text-indent').replace('px', ''), 10) - 170;
1216 wl.css('text-indent', next_left);
1217 },
1218
1219 windowsNext: function () {
1220 var tab, next;
1221 next = false;
1222 for (tab in kiwi.front.tabviews) {
1223 if (!next) {
1224 if (kiwi.front.tabviews[tab] === kiwi.front.cur_channel) {
1225 next = true;
1226 continue;
1227 }
1228 } else {
1229 kiwi.front.tabviews[tab].show();
1230 return;
1231 }
1232 }
1233 },
1234
1235 windowsPrevious: function () {
1236 var tab, prev_tab, next;
1237 next = false;
1238 for (tab in kiwi.front.tabviews) {
1239 if (kiwi.front.tabviews[tab] === kiwi.front.cur_channel) {
1240 if (prev_tab) {
1241 prev_tab.show();
1242 }
1243 return;
1244 }
1245 prev_tab = kiwi.front.tabviews[tab];
1246 }
1247 },
1248
1249 windowsShow: function (num) {
1250 num = parseInt(num, 10);
1251 console.log('Showing window ' + num.toString());
1252 var i = 0, tab;
1253 for (tab in kiwi.front.tabviews) {
1254 if (i === num) {
1255 kiwi.front.tabviews[tab].show();
1256 return;
1257 }
1258 i++;
1259 }
1260 },
1261
1262
1263
1264 barsShow: function () {
1265 $('#kiwi .toolbars').slideDown();
1266 $('#kiwi .control').slideDown();
1267 },
1268
1269 barsHide: function () {
1270 $('#kiwi .toolbars').slideUp();
1271 $('#kiwi .control').slideUp();
1272 },
1273
1274 format: function (msg) {
1275 var re;
1276
1277 if ((!msg) || (typeof msg !== 'string')) {
1278 return;
1279 }
1280
1281 // bold
1282 if (msg.indexOf(String.fromCharCode(2)) !== -1) {
1283 next = '<b>';
1284 while (msg.indexOf(String.fromCharCode(2)) !== -1) {
1285 msg = msg.replace(String.fromCharCode(2), next);
1286 next = (next === '<b>') ? '</b>' : '<b>';
1287 }
1288 if (next === '</b>') {
1289 msg = msg + '</b>';
1290 }
1291 }
1292
1293 // underline
1294 if (msg.indexOf(String.fromCharCode(31)) !== -1) {
1295 next = '<u>';
1296 while (msg.indexOf(String.fromCharCode(31)) !== -1) {
1297 msg = msg.replace(String.fromCharCode(31), next);
1298 next = (next === '<u>') ? '</u>' : '<u>';
1299 }
1300 if (next === '</u>') {
1301 msg = msg + '</u>';
1302 }
1303 }
1304
1305 // colour
1306 re = /\x03([0-9][0-5]?)(,([0-9][0-5]?))?(.*?)\x03/g;
1307
1308 msg = msg.replace(re, function (str, p1, p2, p3, p4) {
1309 var fg, bg,
1310 col = function (num) {
1311 switch (parseInt(num, 10)) {
1312 case 0:
1313 return '#FFFFFF';
1314 case 1:
1315 return '#000000';
1316 case 2:
1317 return '#000080';
1318 case 3:
1319 return '#008000';
1320 case 4:
1321 return '#FF0000';
1322 case 5:
1323 return '#800040';
1324 case 6:
1325 return '#800080';
1326 case 7:
1327 return '#FF8040';
1328 case 8:
1329 return '#FFFF00';
1330 case 9:
1331 return '#80FF00';
1332 case 10:
1333 return '#008080';
1334 case 11:
1335 return '#00FFFF';
1336 case 12:
1337 return '#0000FF';
1338 case 13:
1339 return '#FF55FF';
1340 case 14:
1341 return '#808080';
1342 case 15:
1343 return '#C0C0C0';
1344 default:
1345 return null;
1346 }
1347 };
1348 fg = col(p1);
1349 bg = col(p3);
1350 return '<span style="' + ((fg !== null) ? 'color: ' + fg + '; ' : '') + ((bg !== null) ? 'background-color: ' + bg + ';' : '') + '">' + p4 + '</span>';
1351 });
1352 return msg;
1353 }
1354
1355 };
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372 /*
1373 * MISC VIEW
1374 */
1375
1376 var Utilityview = function (name) {
1377 var rand_name = randomString(15),
1378 tmp_divname = 'kiwi_window_' + rand_name,
1379 tmp_userlistname = 'kiwi_userlist_' + rand_name,
1380 tmp_tabname = 'kiwi_tab_' + rand_name;
1381
1382 this.name = rand_name;
1383 this.title = name;
1384 this.topic = ' ';
1385 this.panel = $('#panel1');
1386
1387 if (typeof $('.scroller', this.panel)[0] === 'undefined') {
1388 this.panel.append('<div id="' + tmp_divname + '" class="messages"></div>');
1389 } else {
1390 $('.scroller', this.panel).append('<div id="' + tmp_divname + '" class="messages"></div>');
1391 }
1392
1393 this.tab = $('<li id="' + tmp_tabname + '">' + this.title + '</li>');
1394 this.tab.click(function () {
1395 kiwi.front.utilityviews[rand_name.toLowerCase()].show();
1396 });
1397 $('#kiwi .utilityviewlist ul').append(this.tab);
1398 kiwi.front.doLayoutSize();
1399
1400 this.div = $('#' + tmp_divname);
1401 this.div.css('overflow', 'hidden');
1402
1403 kiwi.front.utilityviews[rand_name.toLowerCase()] = this;
1404 };
1405
1406 Utilityview.prototype.name = null;
1407 Utilityview.prototype.title = null;
1408 Utilityview.prototype.div = null;
1409 Utilityview.prototype.tab = null;
1410 Utilityview.prototype.topic = ' ';
1411 Utilityview.prototype.panel = null;
1412 Utilityview.prototype.show = function () {
1413 $('.messages', this.panel).removeClass("active");
1414 $('#kiwi .userlist ul').removeClass("active");
1415 $('#kiwi .toolbars ul li').removeClass("active");
1416
1417 this.panel.css('overflow-y', 'hidden');
1418 $('#windows').css('right', 0);
1419 // Activate this tab!
1420 this.div.addClass('active');
1421 this.tab.addClass('active');
1422
1423 this.addPartImage();
1424
1425 kiwi.front.setTopicText(this.topic);
1426 kiwi.front.cur_channel = this;
1427
1428 // If we're using fancy scrolling, refresh it
1429 if (touch_scroll) {
1430 touch_scroll.refresh();
1431 }
1432 };
1433
1434 Utilityview.prototype.setPanel = function (new_panel) {
1435 this.div.detach();
1436 this.panel = new_panel;
1437 this.panel.append(this.div);
1438 this.show();
1439 };
1440
1441 Utilityview.prototype.close = function () {
1442 this.div.remove();
1443 this.tab.remove();
1444
1445 if (kiwi.front.cur_channel === this) {
1446 kiwi.front.tabviews.server.show();
1447 }
1448 delete kiwi.front.utilityviews[this.name.toLowerCase()];
1449 };
1450
1451 Utilityview.prototype.addPartImage = function () {
1452 this.clearPartImage();
1453
1454 // We can't close this tab, so don't have the close image
1455 if (this.name === 'server') {
1456 return;
1457 }
1458
1459 var del_html = '<img src="/img/redcross.png" class="tab_part" />';
1460 this.tab.append(del_html);
1461
1462 $('.tab_part', this.tab).click(function () {
1463 if (kiwi.front.cur_channel.name !== 'server') {
1464 kiwi.front.cur_channel.close();
1465 }
1466 });
1467 };
1468
1469 Utilityview.prototype.clearPartImage = function () {
1470 $('#kiwi .toolbars .tab_part').remove();
1471 };
1472
1473
1474
1475
1476
1477 /*
1478 *
1479 * TABVIEWS
1480 *
1481 */
1482
1483
1484 var Tabview = function () {
1485 this.panel = $('#panel1');
1486 };
1487 Tabview.prototype.name = null;
1488 Tabview.prototype.div = null;
1489 Tabview.prototype.userlist = null;
1490 Tabview.prototype.userlist_width = 100; // 0 for disabled
1491 Tabview.prototype.tab = null;
1492 Tabview.prototype.topic = "";
1493 Tabview.prototype.safe_to_close = false; // If we have been kicked/banned/etc from this channel, don't wait for a part message
1494 Tabview.prototype.panel = null;
1495
1496 Tabview.prototype.show = function () {
1497 var w, u;
1498
1499 $('.messages', this.panel).removeClass("active");
1500 $('#kiwi .userlist ul').removeClass("active");
1501 $('#kiwi .toolbars ul li').removeClass("active");
1502
1503 w = $('#windows');
1504 u = $('#kiwi .userlist');
1505
1506 this.panel.css('overflow-y', 'scroll');
1507
1508 // Set the window size accordingly
1509 this.setUserlistWidth();
1510
1511 // Activate this tab!
1512 this.div.addClass('active');
1513 if (this.userlist_width > 0) {
1514 this.userlist.addClass('active');
1515 // Enable the userlist resizer
1516 $('#nicklist_resize').css('display', 'block');
1517 } else {
1518 // Disable the userlist resizer
1519 $('#nicklist_resize').css('display', 'none');
1520 }
1521 this.tab.addClass('active');
1522
1523 // Add the part image to the tab
1524 this.addPartImage();
1525
1526 this.clearHighlight();
1527 kiwi.front.setTopicText(this.topic);
1528 kiwi.front.cur_channel = this;
1529
1530 // If we're using fancy scrolling, refresh it
1531 if (touch_scroll) {
1532 touch_scroll.refresh();
1533 }
1534
1535 this.scrollBottom();
1536 if (!touchscreen) {
1537 $('#kiwi_msginput').focus();
1538 }
1539 };
1540
1541 Tabview.prototype.close = function () {
1542 this.div.remove();
1543 this.userlist.remove();
1544 this.tab.remove();
1545
1546 if (kiwi.front.cur_channel === this) {
1547 kiwi.front.tabviews.server.show();
1548 }
1549 delete kiwi.front.tabviews[this.name.toLowerCase()];
1550 };
1551
1552 Tabview.prototype.setUserlistWidth = function (new_width) {
1553 var w, u;
1554 if (typeof new_width === 'number') {
1555 this.userlist_width = new_width;
1556 }
1557
1558 w = $('#windows');
1559 u = $('#kiwi .userlist');
1560
1561 // Set the window size accordingly
1562 if (this.userlist_width > 0) {
1563 u.width(this.userlist_width);
1564 w.css('right', u.outerWidth(true));
1565 } else {
1566 w.css('right', 0);
1567 }
1568 };
1569
1570 Tabview.prototype.addPartImage = function () {
1571 this.clearPartImage();
1572
1573 // We can't close this tab, so don't have the close image
1574 if (this.name === 'server') {
1575 return;
1576 }
1577
1578 var del_html = '<img src="/img/redcross.png" class="tab_part" />';
1579 this.tab.append(del_html);
1580
1581 $('.tab_part', this.tab).click(function () {
1582 if (kiwi.front.isChannel($(this).parent().text())) {
1583 kiwi.front.run("/part");
1584 } else {
1585 // Make sure we don't close the server tab
1586 if (kiwi.front.cur_channel.name !== 'server') {
1587 kiwi.front.cur_channel.close();
1588 }
1589 }
1590 });
1591 };
1592
1593 Tabview.prototype.clearPartImage = function () {
1594 $('#kiwi .toolbars .tab_part').remove();
1595 };
1596
1597 Tabview.prototype.addMsg = function (time, nick, msg, type, style) {
1598 var self, tmp, plugin_ret, i, d, re, line_msg, next;
1599
1600 self = this;
1601
1602 tmp = {msg: msg, time: time, nick: nick, tabview: this.name};
1603 tmp = kiwi.plugs.run('addmsg', tmp);
1604 if (!tmp) {
1605 return;
1606 }
1607
1608
1609 msg = tmp.msg;
1610 time = tmp.time;
1611 nick = tmp.nick;
1612
1613 if (time === null) {
1614 d = new Date();
1615 time = d.getHours().toString().lpad(2, "0") + ":" + d.getMinutes().toString().lpad(2, "0") + ":" + d.getSeconds().toString().lpad(2, "0");
1616 }
1617
1618 // The CSS class (action, topic, notice, etc)
1619 if (typeof type !== "string") {
1620 type = '';
1621 }
1622
1623 // Make sure we don't have NaN or something
1624 if (typeof msg !== "string") {
1625 msg = '';
1626 }
1627
1628 // Make the channels clickable
1629 re = new RegExp('\\B(' + kiwi.gateway.channel_prefix + '[^ ,.\\007]+)', 'g');
1630 msg = msg.replace(re, function (match) {
1631 return '<a class="chan">' + match + '</a>';
1632 });
1633
1634 msg = kiwi.front.format(msg);
1635
1636 // Build up and add the line
1637 line_msg = $('<div class="msg ' + type + '"><div class="time">' + time + '</div><div class="nick">' + nick + '</div><div class="text" style="' + style + '">' + msg + ' </div></div>');
1638 this.div.append(line_msg);
1639
1640 if (!touchscreen) {
1641 this.scrollBottom();
1642 } else {
1643 touch_scroll.refresh();
1644 //console.log(this.div.attr("scrollHeight") +" - "+ $('#windows').height());
1645 this.scrollBottom();
1646 //if(this.div.attr("scrollHeight") > $('#windows').height()){
1647 // touch_scroll.scrollTo(0, this.div.height());
1648 //}
1649 }
1650 };
1651
1652 Tabview.prototype.scrollBottom = function () {
1653 var panel = this.panel;
1654 console.log(panel);
1655 panel[0].scrollTop = panel[0].scrollHeight;
1656 };
1657
1658 Tabview.prototype.changeNick = function (newNick, oldNick) {
1659 this.userlist.children().each(function () {
1660 var item = $('a.nick', this);
1661 if (kiwi.front.nickStripPrefix(item.text()) === oldNick) {
1662 item.text(kiwi.front.nickGetPrefix(item.text()) + newNick);
1663 document.temp_chan = 1;
1664 }
1665 });
1666
1667 if (typeof document.temp_chan !== "undefined") {
1668 this.addMsg(null, ' ', '=== ' + oldNick + ' is now known as ' + newNick, 'action changenick');
1669 delete document.temp_chan;
1670 this.userlistSort();
1671 }
1672 };
1673
1674 Tabview.prototype.userlistSort = function () {
1675 var ul = this.userlist,
1676 listitems = ul.children('li').get(),
1677 prefix;
1678 listitems.sort(function (a, b) {
1679 var compA = $(a).text().toUpperCase(),
1680 compB = $(b).text().toUpperCase(),
1681 i;
1682
1683 // Sort by prefixes first
1684 for (i in kiwi.gateway.user_prefixes) {
1685 prefix = kiwi.gateway.user_prefixes[i].symbol;
1686
1687 if (compA.charAt(0) === prefix && compB.charAt(0) === prefix) {
1688 // Both have the same prefix, string compare time
1689 return 0;
1690 }
1691
1692 if (compA.charAt(0) === prefix && compB.charAt(0) !== prefix) {
1693 return -1;
1694 }
1695
1696 if (compA.charAt(0) !== prefix && compB.charAt(0) === prefix) {
1697 return 1;
1698 }
1699 }
1700
1701 // No prefixes, compare by string
1702 return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
1703 });
1704 $.each(listitems, function (idx, itm) { ul.append(itm); });
1705 };
1706
1707 Tabview.prototype.highlight = function () {
1708 this.tab.addClass('highlight');
1709 };
1710 Tabview.prototype.activity = function () {
1711 this.tab.addClass('activity');
1712 };
1713 Tabview.prototype.clearHighlight = function () {
1714 this.tab.removeClass('highlight');
1715 this.tab.removeClass('activity');
1716 };
1717 Tabview.prototype.changeTopic = function (new_topic) {
1718 this.topic = new_topic;
1719 this.addMsg(null, ' ', '=== Topic for ' + this.name + ' is: ' + new_topic, 'topic');
1720 if (kiwi.front.cur_channel.name === this.name) {
1721 kiwi.front.setTopicText(new_topic);
1722 }
1723 };
1724
1725
1726
1727
1728
1729 var Box = function (classname) {
1730 this.id = randomString(10);
1731 var tmp = $('<div id="' + this.id + '" class="box ' + classname + '"><div class="boxarea"></div></div>');
1732 $('#kiwi').append(tmp);
1733 this.box = $('#' + this.id);
1734 this.content = $('#' + this.id + ' .boxarea');
1735
1736 this.box.draggable({ stack: ".box" });
1737 this.content.click(function () {});
1738 //this.box.click(function(){ $(this)..css });
1739 };
1740 Box.prototype.create = function (name, classname) {
1741
1742 };
1743 Box.prototype.id = null;
1744 Box.prototype.box = null;
1745 Box.prototype.content = null;
1746 Box.prototype.destroy = function () {
1747 var name;
1748 this.box.remove();
1749 for (name in kiwi.front.boxes) {
1750 if (kiwi.front.boxes[name].id === this.id) {
1751 delete kiwi.front.boxes[name];
1752 }
1753 }
1754 };
1755 Box.prototype.height = function () {
1756 return this.box.height();
1757 };