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