Timestamp toggling
[KiwiIRC.git] / client / assets / dev / model_application.js
1 _kiwi.model.Application = function () {
2 // Set to a reference to this object within initialize()
3 var that = null;
4
5 // The auto connect details entered into the server select box
6 var auto_connect_details = {};
7
8
9 var model = function () {
10 /** Instance of _kiwi.model.PanelList */
11 this.panels = null;
12
13 /** _kiwi.view.Application */
14 this.view = null;
15
16 /** _kiwi.view.StatusMessage */
17 this.message = null;
18
19 /* Address for the kiwi server */
20 this.kiwi_server = null;
21
22 this.initialize = function (options) {
23 that = this;
24
25 if (options[0].container) {
26 this.set('container', options[0].container);
27 }
28
29 // The base url to the kiwi server
30 this.set('base_path', options[0].base_path ? options[0].base_path : '/kiwi');
31
32 // Any options sent down from the server
33 this.server_settings = options[0].server_settings || {};
34
35 // Best guess at where the kiwi server is
36 this.detectKiwiServer();
37 };
38
39 this.start = function () {
40 // Only debug if set in the querystring
41 if (!getQueryVariable('debug')) {
42 manageDebug(false);
43 } else {
44 //manageDebug(true);
45 }
46
47 // Set the gateway up
48 _kiwi.gateway = new _kiwi.model.Gateway();
49 this.bindGatewayCommands(_kiwi.gateway);
50
51 this.initializeClient();
52 this.initializeGlobals();
53
54 this.view.barsHide(true);
55
56 this.panels.server.server_login.bind('server_connect', function (event) {
57 var server_login = this,
58 transport_path = '';
59 auto_connect_details = event;
60
61 server_login.networkConnecting();
62
63 // Path to get the socket.io transport code
64 transport_path = that.kiwi_server + that.get('base_path') + '/transport/socket.io.js?ts='+(new Date().getTime());
65
66 $script(transport_path, function () {
67 if (!window.io) {
68 kiwiServerNotFound();
69 return;
70 }
71 _kiwi.gateway.set('kiwi_server', that.kiwi_server + '/kiwi');
72 _kiwi.gateway.set('nick', event.nick);
73
74 _kiwi.gateway.connect(event.server, event.port, event.ssl, event.password, function (error) {
75 if (error) {
76 kiwiServerNotFound();
77 }
78 });
79 });
80 });
81
82 // TODO: Shouldn't really be here but it's not working in the view.. :/
83 // Hack for firefox browers: Focus is not given on this event loop iteration
84 setTimeout(function(){
85 _kiwi.app.panels.server.server_login.$el.find('.nick').select();
86 }, 0);
87 };
88
89
90 function kiwiServerNotFound (e) {
91 that.panels.server.server_login.showError();
92 }
93
94
95 this.detectKiwiServer = function () {
96 // If running from file, default to localhost:7777 by default
97 if (window.location.protocol === 'file:') {
98 this.kiwi_server = 'http://localhost:7778';
99 } else {
100 // Assume the kiwi server is on the same server
101 this.kiwi_server = window.location.protocol + '//' + window.location.host;
102 }
103 };
104
105
106 this.initializeClient = function () {
107 this.view = new _kiwi.view.Application({model: this, el: this.get('container')});
108
109 /**
110 * Set the UI components up
111 */
112 this.panels = new _kiwi.model.PanelList();
113
114 this.controlbox = new _kiwi.view.ControlBox({el: $('#controlbox')[0]});
115 this.bindControllboxCommands(this.controlbox);
116
117 this.topicbar = new _kiwi.view.TopicBar({el: $('#topic')[0]});
118
119 new _kiwi.view.AppToolbar({el: $('#toolbar .app_tools')[0]});
120
121 this.message = new _kiwi.view.StatusMessage({el: $('#status_message')[0]});
122
123 this.resize_handle = new _kiwi.view.ResizeHandler({el: $('#memberlists_resize_handle')[0]});
124
125 this.panels.server.view.show();
126
127 // Rejigg the UI sizes
128 this.view.doLayout();
129
130 this.populateDefaultServerSettings();
131 };
132
133
134 this.initializeGlobals = function () {
135 _kiwi.global.panels = this.panels;
136
137 _kiwi.global.components.Applet = _kiwi.model.Applet;
138 _kiwi.global.components.Panel =_kiwi.model.Panel;
139 };
140
141
142 this.populateDefaultServerSettings = function () {
143 var parts;
144 var defaults = {
145 nick: getQueryVariable('nick') || '',
146 server: '',
147 port: 6667,
148 ssl: false,
149 channel: window.location.hash || '#chat',
150 channel_key: ''
151 };
152 var uricheck;
153
154
155 /**
156 * Get any settings set by the server
157 * These settings may be changed in the server selection dialog
158 */
159 if (this.server_settings.client) {
160 if (this.server_settings.client.nick)
161 defaults.nick = this.server_settings.client.nick;
162
163 if (this.server_settings.client.server)
164 defaults.server = this.server_settings.client.server;
165
166 if (this.server_settings.client.port)
167 defaults.port = this.server_settings.client.port;
168
169 if (this.server_settings.client.ssl)
170 defaults.ssl = this.server_settings.client.ssl;
171
172 if (this.server_settings.client.channel)
173 defaults.channel = this.server_settings.client.channel;
174 }
175
176
177
178 /**
179 * Get any settings passed in the URL
180 * These settings may be changed in the server selection dialog
181 */
182
183 // Process the URL part by part, extracting as we go
184 parts = window.location.pathname.toString().replace(this.get('base_path'), '').split('/');
185
186 if (parts.length > 0) {
187 parts.shift();
188
189 if (parts.length > 0 && parts[0]) {
190 // Check to see if we're dealing with an irc: uri, or whether we need to extract the server/channel info from the HTTP URL path.
191 uricheck = parts[0].substr(0, 7).toLowerCase();
192 if ((uricheck === 'ircs%3a') || (uricheck.substr(0,6) === 'irc%3a')) {
193 parts[0] = decodeURIComponent(parts[0]);
194 // irc[s]://<host>[:<port>]/[<channel>[?<password>]]
195 uricheck = /^irc(s)?:(?:\/\/?)?([^:\/]+)(?::([0-9]+))?(?:(?:\/)([^\?]*)(?:(?:\?)(.*))?)?$/.exec(parts[0]);
196 /*
197 uricheck[1] = ssl (optional)
198 uricheck[2] = host
199 uricheck[3] = port (optional)
200 uricheck[4] = channel (optional)
201 uricheck[5] = channel key (optional, channel must also be set)
202 */
203 if (uricheck) {
204 if (typeof uricheck[1] !== 'undefined') {
205 defaults.ssl = true;
206 if (defaults.port === 6667) {
207 defaults.port = 6697;
208 }
209 }
210 defaults.server = uricheck[2];
211 if (typeof uricheck[3] !== 'undefined') {
212 defaults.port = uricheck[3];
213 }
214 if (typeof uricheck[4] !== 'undefined') {
215 defaults.channel = '#' + uricheck[4];
216 if (typeof uricheck[5] !== 'undefined') {
217 defaults.channel_key = uricheck[5];
218 }
219 }
220 }
221 parts = [];
222 } else {
223 // Extract the port+ssl if we find one
224 if (parts[0].search(/:/) > 0) {
225 defaults.port = parts[0].substring(parts[0].search(/:/) + 1);
226 defaults.server = parts[0].substring(0, parts[0].search(/:/));
227 if (defaults.port[0] === '+') {
228 defaults.port = parseInt(defaults.port.substring(1), 10);
229 defaults.ssl = true;
230 } else {
231 defaults.ssl = false;
232 }
233
234 } else {
235 defaults.server = parts[0];
236 }
237
238 parts.shift();
239 }
240 }
241
242 if (parts.length > 0 && parts[0]) {
243 defaults.channel = '#' + parts[0];
244 parts.shift();
245 }
246 }
247
248 // If any settings have been given by the server.. override any auto detected settings
249 /**
250 * Get any server restrictions as set in the server config
251 * These settings can not be changed in the server selection dialog
252 */
253 if (this.server_settings && this.server_settings.connection) {
254 if (this.server_settings.connection.server) {
255 defaults.server = this.server_settings.connection.server;
256 }
257
258 if (this.server_settings.connection.port) {
259 defaults.port = this.server_settings.connection.port;
260 }
261
262 if (this.server_settings.connection.ssl) {
263 defaults.ssl = this.server_settings.connection.ssl;
264 }
265
266 if (this.server_settings.connection.channel) {
267 defaults.channel = this.server_settings.connection.channel;
268 }
269
270 if (this.server_settings.connection.nick) {
271 defaults.nick = this.server_settings.connection.nick;
272 }
273 }
274
275 // Set any random numbers if needed
276 defaults.nick = defaults.nick.replace('?', Math.floor(Math.random() * 100000).toString());
277
278 // Populate the server select box with defaults
279 this.panels.server.server_login.populateFields(defaults);
280 };
281
282
283 this.bindGatewayCommands = function (gw) {
284 gw.on('onmotd', function (event) {
285 that.panels.server.addMsg(_kiwi.gateway.get('name'), event.msg, 'motd');
286 });
287
288
289 gw.on('onconnect', function (event) {
290 that.view.barsShow();
291
292 if (auto_connect_details.channel) {
293 that.controlbox.processInput('/JOIN ' + auto_connect_details.channel + ' ' + auto_connect_details.channel_key);
294 }
295 });
296
297
298 (function () {
299 var gw_stat = 0;
300
301 gw.on('disconnect', function (event) {
302 var msg = 'You have been disconnected. Attempting to reconnect for you..';
303 that.message.text(msg, {timeout: 10000});
304
305 // Mention the disconnection on every channel
306 $.each(_kiwi.app.panels.models, function (idx, panel) {
307 if (!panel || !panel.isChannel()) return;
308 panel.addMsg('', msg, 'action quit');
309 });
310 _kiwi.app.panels.server.addMsg('', msg, 'action quit');
311
312 gw_stat = 1;
313 });
314 gw.on('reconnecting', function (event) {
315 msg = 'You have been disconnected. Attempting to reconnect again in ' + (event.delay/1000) + ' seconds..';
316 _kiwi.app.panels.server.addMsg('', msg, 'action quit');
317 });
318 gw.on('connect', function (event) {
319 if (gw_stat !== 1) return;
320
321 var msg = 'It\'s OK, you\'re connected again :)';
322 that.message.text(msg, {timeout: 5000});
323
324 // Mention the disconnection on every channel
325 $.each(_kiwi.app.panels.models, function (idx, panel) {
326 if (!panel || !panel.isChannel()) return;
327 panel.addMsg('', msg, 'action join');
328 });
329 _kiwi.app.panels.server.addMsg('', msg, 'action join');
330
331 gw_stat = 0;
332 });
333 })();
334
335
336 gw.on('onjoin', function (event) {
337 var c, members, user;
338 c = that.panels.getByName(event.channel);
339 if (!c) {
340 c = new _kiwi.model.Channel({name: event.channel});
341 that.panels.add(c);
342 }
343
344 members = c.get('members');
345 if (!members) return;
346
347 user = new _kiwi.model.Member({nick: event.nick, ident: event.ident, hostname: event.hostname});
348 members.add(user);
349 // TODO: highlight the new channel in some way
350 });
351
352
353 gw.on('onpart', function (event) {
354 var channel, members, user,
355 part_options = {};
356
357 part_options.type = 'part';
358 part_options.message = event.message || '';
359
360 channel = that.panels.getByName(event.channel);
361 if (!channel) return;
362
363 // If this is us, close the panel
364 if (event.nick === _kiwi.gateway.get('nick')) {
365 channel.close();
366 return;
367 }
368
369 members = channel.get('members');
370 if (!members) return;
371
372 user = members.getByNick(event.nick);
373 if (!user) return;
374
375 members.remove(user, part_options);
376 });
377
378
379 gw.on('onquit', function (event) {
380 var member, members,
381 quit_options = {};
382
383 quit_options.type = 'quit';
384 quit_options.message = event.message || '';
385
386 $.each(that.panels.models, function (index, panel) {
387 if (!panel.isChannel()) return;
388
389 member = panel.get('members').getByNick(event.nick);
390 if (member) {
391 panel.get('members').remove(member, quit_options);
392 }
393 });
394 });
395
396
397 gw.on('onkick', function (event) {
398 var channel, members, user,
399 part_options = {};
400
401 part_options.type = 'kick';
402 part_options.by = event.nick;
403 part_options.message = event.message || '';
404
405 channel = that.panels.getByName(event.channel);
406 if (!channel) return;
407
408 members = channel.get('members');
409 if (!members) return;
410
411 user = members.getByNick(event.kicked);
412 if (!user) return;
413
414 members.remove(user, part_options);
415
416 if (event.kicked === _kiwi.gateway.get('nick')) {
417 members.reset([]);
418 }
419
420 });
421
422
423 gw.on('onmsg', function (event) {
424 var panel,
425 is_pm = (event.channel == _kiwi.gateway.get('nick'));
426
427 // An ignored user? don't do anything with it
428 if (gw.isNickIgnored(event.nick)) {
429 return;
430 }
431
432 if (is_pm) {
433 // If a panel isn't found for this PM, create one
434 panel = that.panels.getByName(event.nick);
435 if (!panel) {
436 panel = new _kiwi.model.Query({name: event.nick});
437 that.panels.add(panel);
438 }
439
440 } else {
441 // If a panel isn't found for this channel, reroute to the
442 // server panel
443 panel = that.panels.getByName(event.channel);
444 if (!panel) {
445 panel = that.panels.server;
446 }
447 }
448
449 panel.addMsg(event.nick, event.msg);
450 });
451
452
453 gw.on('onctcp_request', function (event) {
454 // An ignored user? don't do anything with it
455 if (gw.isNickIgnored(event.nick)) {
456 return;
457 }
458
459 // Reply to a TIME ctcp
460 if (event.msg.toUpperCase() === 'TIME') {
461 gw.ctcp(false, event.type, event.nick, (new Date()).toString());
462 }
463 });
464
465
466 gw.on('onctcp_response', function (event) {
467 // An ignored user? don't do anything with it
468 if (gw.isNickIgnored(event.nick)) {
469 return;
470 }
471
472 that.panels.server.addMsg('[' + event.nick + ']', 'CTCP ' + event.msg);
473 });
474
475
476 gw.on('onnotice', function (event) {
477 var panel;
478
479 // An ignored user? don't do anything with it
480 if (event.nick && gw.isNickIgnored(event.nick)) {
481 return;
482 }
483
484 // Find a panel for the destination(channel) or who its from
485 panel = that.panels.getByName(event.target) || that.panels.getByName(event.nick);
486 if (!panel) {
487 panel = that.panels.server;
488 }
489
490 panel.addMsg('[' + (event.nick||'') + ']', event.msg);
491 });
492
493
494 gw.on('onaction', function (event) {
495 var panel,
496 is_pm = (event.channel == _kiwi.gateway.get('nick'));
497
498 // An ignored user? don't do anything with it
499 if (gw.isNickIgnored(event.nick)) {
500 return;
501 }
502
503 if (is_pm) {
504 // If a panel isn't found for this PM, create one
505 panel = that.panels.getByName(event.nick);
506 if (!panel) {
507 panel = new _kiwi.model.Channel({name: event.nick});
508 that.panels.add(panel);
509 }
510
511 } else {
512 // If a panel isn't found for this channel, reroute to the
513 // server panel
514 panel = that.panels.getByName(event.channel);
515 if (!panel) {
516 panel = that.panels.server;
517 }
518 }
519
520 panel.addMsg('', '* ' + event.nick + ' ' + event.msg, 'action');
521 });
522
523
524 gw.on('ontopic', function (event) {
525 var c;
526 c = that.panels.getByName(event.channel);
527 if (!c) return;
528
529 // Set the channels topic
530 c.set('topic', event.topic);
531
532 // If this is the active channel, update the topic bar too
533 if (c.get('name') === _kiwi.app.panels.active.get('name')) {
534 that.topicbar.setCurrentTopic(event.topic);
535 }
536 });
537
538
539 gw.on('ontopicsetby', function (event) {
540 var c, when;
541 c = that.panels.getByName(event.channel);
542 if (!c) return;
543
544 when = formatDate(new Date(event.when * 1000));
545 c.addMsg('', 'Topic set by ' + event.nick + ' at ' + when, 'topic');
546 });
547
548
549 gw.on('onuserlist', function (event) {
550 var channel;
551 channel = that.panels.getByName(event.channel);
552
553 // If we didn't find a channel for this, may aswell leave
554 if (!channel) return;
555
556 channel.temp_userlist = channel.temp_userlist || [];
557 _.each(event.users, function (item) {
558 var user = new _kiwi.model.Member({nick: item.nick, modes: item.modes});
559 channel.temp_userlist.push(user);
560 });
561 });
562
563
564 gw.on('onuserlist_end', function (event) {
565 var channel;
566 channel = that.panels.getByName(event.channel);
567
568 // If we didn't find a channel for this, may aswell leave
569 if (!channel) return;
570
571 // Update the members list with the new list
572 channel.get('members').reset(channel.temp_userlist || []);
573
574 // Clear the temporary userlist
575 delete channel.temp_userlist;
576 });
577
578
579 gw.on('onmode', function (event) {
580 var channel, i, prefixes, members, member, find_prefix;
581
582 // Build a nicely formatted string to be displayed to a regular human
583 function friendlyModeString (event_modes, alt_target) {
584 var modes = {}, return_string;
585
586 // If no default given, use the main event info
587 if (!event_modes) {
588 event_modes = event.modes;
589 alt_target = event.target;
590 }
591
592 // Reformat the mode object to make it easier to work with
593 _.each(event_modes, function (mode){
594 var param = mode.param || alt_target || '';
595
596 // Make sure we have some modes for this param
597 if (!modes[param]) {
598 modes[param] = {'+':'', '-':''};
599 }
600
601 modes[param][mode.mode[0]] += mode.mode.substr(1);
602 });
603
604 // Put the string together from each mode
605 return_string = [];
606 _.each(modes, function (modeset, param) {
607 var str = '';
608 if (modeset['+']) str += '+' + modeset['+'];
609 if (modeset['-']) str += '-' + modeset['-'];
610 return_string.push(str + ' ' + param);
611 });
612 return_string = return_string.join(', ');
613
614 return return_string;
615 }
616
617
618 channel = that.panels.getByName(event.target);
619 if (channel) {
620 prefixes = _kiwi.gateway.get('user_prefixes');
621 find_prefix = function (p) {
622 return event.modes[i].mode[1] === p.mode;
623 };
624 for (i = 0; i < event.modes.length; i++) {
625 if (_.any(prefixes, find_prefix)) {
626 if (!members) {
627 members = channel.get('members');
628 }
629 member = members.getByNick(event.modes[i].param);
630 if (!member) {
631 console.log('MODE command recieved for unknown member %s on channel %s', event.modes[i].param, event.target);
632 return;
633 } else {
634 if (event.modes[i].mode[0] === '+') {
635 member.addMode(event.modes[i].mode[1]);
636 } else if (event.modes[i].mode[0] === '-') {
637 member.removeMode(event.modes[i].mode[1]);
638 }
639 members.sort();
640 //channel.addMsg('', '== ' + event.nick + ' set mode ' + event.modes[i].mode + ' ' + event.modes[i].param, 'action mode');
641 }
642 } else {
643 // Channel mode being set
644 // TODO: Store this somewhere?
645 //channel.addMsg('', 'CHANNEL === ' + event.nick + ' set mode ' + event.modes[i].mode + ' on ' + event.target, 'action mode');
646 }
647 }
648
649 channel.addMsg('', '== ' + event.nick + ' sets mode ' + friendlyModeString(), 'action mode');
650 } else {
651 // This is probably a mode being set on us.
652 if (event.target.toLowerCase() === _kiwi.gateway.get("nick").toLowerCase()) {
653 that.panels.server.addMsg('', '== ' + event.nick + ' set mode ' + friendlyModeString(), 'action mode');
654 } else {
655 console.log('MODE command recieved for unknown target %s: ', event.target, event);
656 }
657 }
658 });
659
660
661 gw.on('onnick', function (event) {
662 var member;
663
664 $.each(that.panels.models, function (index, panel) {
665 if (!panel.isChannel()) return;
666
667 member = panel.get('members').getByNick(event.nick);
668 if (member) {
669 member.set('nick', event.newnick);
670 panel.addMsg('', '== ' + event.nick + ' is now known as ' + event.newnick, 'action nick');
671 }
672 });
673 });
674
675
676 gw.on('onwhois', function (event) {
677 /*globals secondsToTime */
678 var logon_date, idle_time = '', panel;
679
680 if (event.end) {
681 return;
682 }
683
684 if (typeof event.idle !== 'undefined') {
685 idle_time = secondsToTime(parseInt(event.idle, 10));
686 idle_time = idle_time.h.toString().lpad(2, "0") + ':' + idle_time.m.toString().lpad(2, "0") + ':' + idle_time.s.toString().lpad(2, "0");
687 }
688
689 panel = _kiwi.app.panels.active;
690 if (event.ident) {
691 panel.addMsg(event.nick, event.nick + ' [' + event.nick + '!' + event.ident + '@' + event.host + '] * ' + event.msg, 'whois');
692 } else if (event.chans) {
693 panel.addMsg(event.nick, 'Channels: ' + event.chans, 'whois');
694 } else if (event.irc_server) {
695 panel.addMsg(event.nick, 'Connected to server: ' + event.irc_server, 'whois');
696 } else if (event.msg) {
697 panel.addMsg(event.nick, event.msg, 'whois');
698 } else if (event.logon) {
699 logon_date = new Date();
700 logon_date.setTime(event.logon * 1000);
701 logon_date = formatDate(logon_date);
702
703 panel.addMsg(event.nick, 'idle for ' + idle_time + ', signed on ' + logon_date, 'whois');
704 } else {
705 panel.addMsg(event.nick, 'idle for ' + idle_time, 'whois');
706 }
707 });
708
709 gw.on('onaway', function (event) {
710 $.each(that.panels.models, function (index, panel) {
711 if (!panel.isChannel()) return;
712
713 member = panel.get('members').getByNick(event.nick);
714 if (member) {
715 member.set('away', !(!event.trailing));
716 }
717 });
718 });
719
720
721 gw.on('onlist_start', function (data) {
722 if (_kiwi.app.channel_list) {
723 _kiwi.app.channel_list.close();
724 delete _kiwi.app.channel_list;
725 }
726
727 var panel = new _kiwi.model.Applet(),
728 applet = new _kiwi.applets.Chanlist();
729
730 panel.load(applet);
731
732 _kiwi.app.panels.add(panel);
733 panel.view.show();
734
735 _kiwi.app.channel_list = applet;
736 });
737
738
739 gw.on('onlist_channel', function (data) {
740 // TODO: Put this listener within the applet itself
741 _kiwi.app.channel_list.addChannel(data.chans);
742 });
743
744
745 gw.on('onlist_end', function (data) {
746 // TODO: Put this listener within the applet itself
747 delete _kiwi.app.channel_list;
748 });
749
750
751 gw.on('onirc_error', function (data) {
752 var panel, tmp;
753
754 if (data.channel !== undefined && !(panel = _kiwi.app.panels.getByName(data.channel))) {
755 panel = _kiwi.app.panels.server;
756 }
757
758 switch (data.error) {
759 case 'banned_from_channel':
760 panel.addMsg(' ', '== You are banned from ' + data.channel + '. ' + data.reason, 'status');
761 _kiwi.app.message.text('You are banned from ' + data.channel + '. ' + data.reason);
762 break;
763 case 'bad_channel_key':
764 panel.addMsg(' ', '== Bad channel key for ' + data.channel, 'status');
765 _kiwi.app.message.text('Bad channel key or password for ' + data.channel);
766 break;
767 case 'invite_only_channel':
768 panel.addMsg(' ', '== ' + data.channel + ' is invite only.', 'status');
769 _kiwi.app.message.text(data.channel + ' is invite only');
770 break;
771 case 'channel_is_full':
772 panel.addMsg(' ', '== ' + data.channel + ' is full.', 'status');
773 _kiwi.app.message.text(data.channel + ' is full');
774 break;
775 case 'chanop_privs_needed':
776 panel.addMsg(' ', '== ' + data.reason, 'status');
777 _kiwi.app.message.text(data.reason + ' (' + data.channel + ')');
778 break;
779 case 'no_such_nick':
780 tmp = _kiwi.app.panels.getByName(data.nick);
781 if (tmp) {
782 tmp.addMsg(' ', '== ' + data.nick + ': ' + data.reason, 'status');
783 } else {
784 _kiwi.app.panels.server.addMsg(' ', '== ' + data.nick + ': ' + data.reason, 'status');
785 }
786 break;
787 case 'nickname_in_use':
788 _kiwi.app.panels.server.addMsg(' ', '== The nickname ' + data.nick + ' is already in use. Please select a new nickname', 'status');
789 if (_kiwi.app.panels.server !== _kiwi.app.panels.active) {
790 _kiwi.app.message.text('The nickname "' + data.nick + '" is already in use. Please select a new nickname');
791 }
792
793 // Only show the nickchange component if the controlbox is open
794 if (that.controlbox.$el.css('display') !== 'none') {
795 (new _kiwi.view.NickChangeBox()).render();
796 }
797
798 case 'password_mismatch':
799 _kiwi.app.panels.server.addMsg(' ', '== Incorrect password given', 'status');
800 break;
801 default:
802 // We don't know what data contains, so don't do anything with it.
803 //_kiwi.front.tabviews.server.addMsg(null, ' ', '== ' + data, 'status');
804 }
805 });
806 };
807
808
809
810 /**
811 * Bind to certain commands that may be typed into the control box
812 */
813 this.bindControllboxCommands = function (controlbox) {
814 // Default aliases
815 $.extend(controlbox.preprocessor.aliases, {
816 // General aliases
817 '/p': '/part $1+',
818 '/me': '/action $1+',
819 '/j': '/join $1+',
820 '/q': '/query $1+',
821
822 // Op related aliases
823 '/op': '/quote mode $channel +o $1+',
824 '/deop': '/quote mode $channel -o $1+',
825 '/hop': '/quote mode $channel +h $1+',
826 '/dehop': '/quote mode $channel -h $1+',
827 '/voice': '/quote mode $channel +v $1+',
828 '/devoice': '/quote mode $channel -v $1+',
829 '/k': '/kick $channel $1+',
830
831 // Misc aliases
832 '/slap': '/me slaps $1 around a bit with a large trout'
833 });
834
835 controlbox.on('unknown_command', unknownCommand);
836
837 controlbox.on('command', allCommands);
838 controlbox.on('command:msg', msgCommand);
839
840 controlbox.on('command:action', actionCommand);
841
842 controlbox.on('command:join', joinCommand);
843
844 controlbox.on('command:part', partCommand);
845
846 controlbox.on('command:nick', function (ev) {
847 _kiwi.gateway.changeNick(ev.params[0]);
848 });
849
850 controlbox.on('command:query', queryCommand);
851
852 controlbox.on('command:topic', topicCommand);
853
854 controlbox.on('command:notice', noticeCommand);
855
856 controlbox.on('command:quote', quoteCommand);
857
858 controlbox.on('command:kick', kickCommand);
859
860 controlbox.on('command:clear', clearCommand);
861
862 controlbox.on('command:ctcp', ctcpCommand);
863
864
865 controlbox.on('command:css', function (ev) {
866 var queryString = '?reload=' + new Date().getTime();
867 $('link[rel="stylesheet"]').each(function () {
868 this.href = this.href.replace(/\?.*|$/, queryString);
869 });
870 });
871
872 controlbox.on('command:js', function (ev) {
873 if (!ev.params[0]) return;
874 $script(ev.params[0] + '?' + (new Date().getTime()));
875 });
876
877
878 controlbox.on('command:set', function (ev) {
879 if (!ev.params[0]) return;
880
881 var setting = ev.params[0],
882 value;
883
884 // Do we have a second param to set a value?
885 if (ev.params[1]) {
886 ev.params.shift();
887
888 value = ev.params.join(' ');
889 _kiwi.global.settings.set(setting, value);
890 }
891
892 // Read the value to the user
893 _kiwi.app.panels.active.addMsg('', setting + ' = ' + _kiwi.global.settings.get(setting));
894 });
895
896
897 controlbox.on('command:save', function (ev) {
898 _kiwi.global.settings.save();
899 _kiwi.app.panels.active.addMsg('', 'Settings have been saved');
900 });
901
902
903 controlbox.on('command:alias', function (ev) {
904 var name, rule;
905
906 // No parameters passed so list them
907 if (!ev.params[1]) {
908 $.each(controlbox.preprocessor.aliases, function (name, rule) {
909 _kiwi.app.panels.server.addMsg(' ', name + ' => ' + rule);
910 });
911 return;
912 }
913
914 // Deleting an alias?
915 if (ev.params[0] === 'del' || ev.params[0] === 'delete') {
916 name = ev.params[1];
917 if (name[0] !== '/') name = '/' + name;
918 delete controlbox.preprocessor.aliases[name];
919 return;
920 }
921
922 // Add the alias
923 name = ev.params[0];
924 ev.params.shift();
925 rule = ev.params.join(' ');
926
927 // Make sure the name starts with a slash
928 if (name[0] !== '/') name = '/' + name;
929
930 // Now actually add the alias
931 controlbox.preprocessor.aliases[name] = rule;
932 });
933
934
935 controlbox.on('command:ignore', function (ev) {
936 var list = _kiwi.gateway.get('ignore_list');
937
938 // No parameters passed so list them
939 if (!ev.params[0]) {
940 if (list.length > 0) {
941 _kiwi.app.panels.active.addMsg(' ', 'Ignored nicks:');
942 $.each(list, function (idx, ignored_pattern) {
943 _kiwi.app.panels.active.addMsg(' ', ignored_pattern);
944 });
945 } else {
946 _kiwi.app.panels.active.addMsg(' ', 'Not ignoring anybody');
947 }
948 return;
949 }
950
951 // We have a parameter, so add it
952 list.push(ev.params[0]);
953 _kiwi.gateway.set('ignore_list', list);
954 _kiwi.app.panels.active.addMsg(' ', 'Ignoring ' + ev.params[0]);
955 });
956
957
958 controlbox.on('command:unignore', function (ev) {
959 var list = _kiwi.gateway.get('ignore_list');
960
961 if (!ev.params[0]) {
962 _kiwi.app.panels.active.addMsg(' ', 'Specifiy which nick you wish to stop ignoring');
963 return;
964 }
965
966 list = _.reject(list, function(pattern) {
967 return pattern === ev.params[0];
968 });
969
970 _kiwi.gateway.set('ignore_list', list);
971
972 _kiwi.app.panels.active.addMsg(' ', 'Stopped ignoring ' + ev.params[0]);
973 });
974
975
976 controlbox.on('command:applet', appletCommand);
977 controlbox.on('command:settings', settingsCommand);
978 controlbox.on('command:script', scriptCommand);
979 };
980
981 // A fallback action. Send a raw command to the server
982 function unknownCommand (ev) {
983 var raw_cmd = ev.command + ' ' + ev.params.join(' ');
984 console.log('RAW: ' + raw_cmd);
985 _kiwi.gateway.raw(raw_cmd);
986 }
987
988 function allCommands (ev) {}
989
990 function joinCommand (ev) {
991 var channel, channel_names;
992
993 channel_names = ev.params.join(' ').split(',');
994
995 $.each(channel_names, function (index, channel_name_key) {
996 // We may have a channel key so split it off
997 var spli = channel_name_key.split(' '),
998 channel_name = spli[0],
999 channel_key = spli[1] || '';
1000
1001 // Trim any whitespace off the name
1002 channel_name = channel_name.trim();
1003
1004 // If not a valid channel name, display a warning
1005 if (!that.isChannelName(channel_name)) {
1006 _kiwi.app.panels.server.addMsg('', channel_name + ' is not a valid channel name');
1007 _kiwi.app.message.text(channel_name + ' is not a valid channel name', {timeout: 5000});
1008 return;
1009 }
1010
1011 // Check if we have the panel already. If not, create it
1012 channel = that.panels.getByName(channel_name);
1013 if (!channel) {
1014 channel = new _kiwi.model.Channel({name: channel_name});
1015 _kiwi.app.panels.add(channel);
1016 }
1017
1018 _kiwi.gateway.join(channel_name, channel_key);
1019 });
1020
1021 if (channel) channel.view.show();
1022
1023 }
1024
1025 function queryCommand (ev) {
1026 var destination, panel;
1027
1028 destination = ev.params[0];
1029
1030 // Check if we have the panel already. If not, create it
1031 panel = that.panels.getByName(destination);
1032 if (!panel) {
1033 panel = new _kiwi.model.Query({name: destination});
1034 _kiwi.app.panels.add(panel);
1035 }
1036
1037 if (panel) panel.view.show();
1038
1039 }
1040
1041 function msgCommand (ev) {
1042 var destination = ev.params[0],
1043 panel = that.panels.getByName(destination) || that.panels.server;
1044
1045 ev.params.shift();
1046
1047 panel.addMsg(_kiwi.gateway.get('nick'), ev.params.join(' '));
1048 _kiwi.gateway.privmsg(destination, ev.params.join(' '));
1049 }
1050
1051 function actionCommand (ev) {
1052 if (_kiwi.app.panels.active === _kiwi.app.panels.server) {
1053 return;
1054 }
1055
1056 var panel = _kiwi.app.panels.active;
1057 panel.addMsg('', '* ' + _kiwi.gateway.get('nick') + ' ' + ev.params.join(' '), 'action');
1058 _kiwi.gateway.action(panel.get('name'), ev.params.join(' '));
1059 }
1060
1061 function partCommand (ev) {
1062 if (ev.params.length === 0) {
1063 _kiwi.gateway.part(_kiwi.app.panels.active.get('name'));
1064 } else {
1065 _.each(ev.params, function (channel) {
1066 _kiwi.gateway.part(channel);
1067 });
1068 }
1069 // TODO: More responsive = close tab now, more accurate = leave until part event
1070 //_kiwi.app.panels.remove(_kiwi.app.panels.active);
1071 }
1072
1073 function topicCommand (ev) {
1074 var channel_name;
1075
1076 if (ev.params.length === 0) return;
1077
1078 if (that.isChannelName(ev.params[0])) {
1079 channel_name = ev.params[0];
1080 ev.params.shift();
1081 } else {
1082 channel_name = _kiwi.app.panels.active.get('name');
1083 }
1084
1085 _kiwi.gateway.topic(channel_name, ev.params.join(' '));
1086 }
1087
1088 function noticeCommand (ev) {
1089 var destination;
1090
1091 // Make sure we have a destination and some sort of message
1092 if (ev.params.length <= 1) return;
1093
1094 destination = ev.params[0];
1095 ev.params.shift();
1096
1097 _kiwi.gateway.notice(destination, ev.params.join(' '));
1098 }
1099
1100 function quoteCommand (ev) {
1101 var raw = ev.params.join(' ');
1102 _kiwi.gateway.raw(raw);
1103 }
1104
1105 function kickCommand (ev) {
1106 var nick, panel = _kiwi.app.panels.active;
1107
1108 if (!panel.isChannel()) return;
1109
1110 // Make sure we have a nick
1111 if (ev.params.length === 0) return;
1112
1113 nick = ev.params[0];
1114 ev.params.shift();
1115
1116 _kiwi.gateway.kick(panel.get('name'), nick, ev.params.join(' '));
1117 }
1118
1119 function clearCommand (ev) {
1120 // Can't clear a server or applet panel
1121 if (_kiwi.app.panels.active.isServer() || _kiwi.app.panels.active.isApplet()) {
1122 return;
1123 }
1124
1125 if (_kiwi.app.panels.active.clearMessages) {
1126 _kiwi.app.panels.active.clearMessages();
1127 }
1128 }
1129
1130 function ctcpCommand(ev) {
1131 var target, type;
1132
1133 // Make sure we have a target and a ctcp type (eg. version, time)
1134 if (ev.params.length < 2) return;
1135
1136 target = ev.params[0];
1137 ev.params.shift();
1138
1139 type = ev.params[0];
1140 ev.params.shift();
1141
1142 _kiwi.gateway.ctcp(true, type, target, ev.params.join(' '));
1143 }
1144
1145 function settingsCommand (ev) {
1146 var settings = _kiwi.model.Applet.loadOnce('kiwi_settings');
1147 settings.view.show();
1148 }
1149
1150 function scriptCommand (ev) {
1151 var editor = _kiwi.model.Applet.loadOnce('kiwi_script_editor');
1152 editor.view.show();
1153 }
1154
1155 function appletCommand (ev) {
1156 if (!ev.params[0]) return;
1157
1158 var panel = new _kiwi.model.Applet();
1159
1160 if (ev.params[1]) {
1161 // Url and name given
1162 panel.load(ev.params[0], ev.params[1]);
1163 } else {
1164 // Load a pre-loaded applet
1165 if (_kiwi.applets[ev.params[0]]) {
1166 panel.load(new _kiwi.applets[ev.params[0]]());
1167 } else {
1168 _kiwi.app.panels.server.addMsg('', 'Applet "' + ev.params[0] + '" does not exist');
1169 return;
1170 }
1171 }
1172
1173 _kiwi.app.panels.add(panel);
1174 panel.view.show();
1175 }
1176
1177
1178
1179
1180
1181 this.isChannelName = function (channel_name) {
1182 var channel_prefix = _kiwi.gateway.get('channel_prefix');
1183
1184 if (!channel_name || !channel_name.length) return false;
1185 return (channel_prefix.indexOf(channel_name[0]) > -1);
1186 };
1187
1188 };
1189
1190
1191 model = Backbone.Model.extend(new model());
1192
1193 return new model(arguments);
1194 };