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