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