Removed default nick + server
[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 if (is_pm) {
428 // If a panel isn't found for this PM, create one
429 panel = that.panels.getByName(event.nick);
430 if (!panel) {
431 panel = new _kiwi.model.Query({name: event.nick});
432 that.panels.add(panel);
433 }
434
435 } else {
436 // If a panel isn't found for this channel, reroute to the
437 // server panel
438 panel = that.panels.getByName(event.channel);
439 if (!panel) {
440 panel = that.panels.server;
441 }
442 }
443
444 panel.addMsg(event.nick, event.msg);
445 });
446
447
448 gw.on('onctcp_request', function (event) {
449 // Reply to a TIME ctcp
450 if (event.msg.toUpperCase() === 'TIME') {
451 gw.ctcp(false, event.type, event.nick, (new Date()).toString());
452 }
453 });
454
455
456 gw.on('onctcp_response', function (event) {
457 that.panels.server.addMsg('[' + event.nick + ']', 'CTCP ' + event.msg);
458 });
459
460
461 gw.on('onnotice', function (event) {
462 var panel;
463
464 // Find a panel for the destination(channel) or who its from
465 panel = that.panels.getByName(event.target) || that.panels.getByName(event.nick);
466 if (!panel) {
467 panel = that.panels.server;
468 }
469
470 panel.addMsg('[' + (event.nick||'') + ']', event.msg);
471 });
472
473
474 gw.on('onaction', function (event) {
475 var panel,
476 is_pm = (event.channel == _kiwi.gateway.get('nick'));
477
478 if (is_pm) {
479 // If a panel isn't found for this PM, create one
480 panel = that.panels.getByName(event.nick);
481 if (!panel) {
482 panel = new _kiwi.model.Channel({name: event.nick});
483 that.panels.add(panel);
484 }
485
486 } else {
487 // If a panel isn't found for this channel, reroute to the
488 // server panel
489 panel = that.panels.getByName(event.channel);
490 if (!panel) {
491 panel = that.panels.server;
492 }
493 }
494
495 panel.addMsg('', '* ' + event.nick + ' ' + event.msg, 'action');
496 });
497
498
499 gw.on('ontopic', function (event) {
500 var c;
501 c = that.panels.getByName(event.channel);
502 if (!c) return;
503
504 // Set the channels topic
505 c.set('topic', event.topic);
506
507 // If this is the active channel, update the topic bar too
508 if (c.get('name') === _kiwi.app.panels.active.get('name')) {
509 that.topicbar.setCurrentTopic(event.topic);
510 }
511 });
512
513
514 gw.on('ontopicsetby', function (event) {
515 var c, when;
516 c = that.panels.getByName(event.channel);
517 if (!c) return;
518
519 when = formatDate(new Date(event.when * 1000));
520 c.addMsg('', 'Topic set by ' + event.nick + ' at ' + when, 'topic');
521 });
522
523
524 gw.on('onuserlist', function (event) {
525 var channel;
526 channel = that.panels.getByName(event.channel);
527
528 // If we didn't find a channel for this, may aswell leave
529 if (!channel) return;
530
531 channel.temp_userlist = channel.temp_userlist || [];
532 _.each(event.users, function (item) {
533 var user = new _kiwi.model.Member({nick: item.nick, modes: item.modes});
534 channel.temp_userlist.push(user);
535 });
536 });
537
538
539 gw.on('onuserlist_end', function (event) {
540 var channel;
541 channel = that.panels.getByName(event.channel);
542
543 // If we didn't find a channel for this, may aswell leave
544 if (!channel) return;
545
546 // Update the members list with the new list
547 channel.get('members').reset(channel.temp_userlist || []);
548
549 // Clear the temporary userlist
550 delete channel.temp_userlist;
551 });
552
553
554 gw.on('onmode', function (event) {
555 var channel, i, prefixes, members, member, find_prefix;
556
557 // Build a nicely formatted string to be displayed to a regular human
558 function friendlyModeString (event_modes, alt_target) {
559 var modes = {}, return_string;
560
561 // If no default given, use the main event info
562 if (!event_modes) {
563 event_modes = event.modes;
564 alt_target = event.target;
565 }
566
567 // Reformat the mode object to make it easier to work with
568 _.each(event_modes, function (mode){
569 var param = mode.param || alt_target || '';
570
571 // Make sure we have some modes for this param
572 if (!modes[param]) {
573 modes[param] = {'+':'', '-':''};
574 }
575
576 modes[param][mode.mode[0]] += mode.mode.substr(1);
577 });
578
579 // Put the string together from each mode
580 return_string = [];
581 _.each(modes, function (modeset, param) {
582 var str = '';
583 if (modeset['+']) str += '+' + modeset['+'];
584 if (modeset['-']) str += '-' + modeset['-'];
585 return_string.push(str + ' ' + param);
586 });
587 return_string = return_string.join(', ');
588
589 return return_string;
590 }
591
592
593 channel = that.panels.getByName(event.target);
594 if (channel) {
595 prefixes = _kiwi.gateway.get('user_prefixes');
596 find_prefix = function (p) {
597 return event.modes[i].mode[1] === p.mode;
598 };
599 for (i = 0; i < event.modes.length; i++) {
600 if (_.any(prefixes, find_prefix)) {
601 if (!members) {
602 members = channel.get('members');
603 }
604 member = members.getByNick(event.modes[i].param);
605 if (!member) {
606 console.log('MODE command recieved for unknown member %s on channel %s', event.modes[i].param, event.target);
607 return;
608 } else {
609 if (event.modes[i].mode[0] === '+') {
610 member.addMode(event.modes[i].mode[1]);
611 } else if (event.modes[i].mode[0] === '-') {
612 member.removeMode(event.modes[i].mode[1]);
613 }
614 members.sort();
615 //channel.addMsg('', '== ' + event.nick + ' set mode ' + event.modes[i].mode + ' ' + event.modes[i].param, 'action mode');
616 }
617 } else {
618 // Channel mode being set
619 // TODO: Store this somewhere?
620 //channel.addMsg('', 'CHANNEL === ' + event.nick + ' set mode ' + event.modes[i].mode + ' on ' + event.target, 'action mode');
621 }
622 }
623
624 channel.addMsg('', '== ' + event.nick + ' sets mode ' + friendlyModeString(), 'action mode');
625 } else {
626 // This is probably a mode being set on us.
627 if (event.target.toLowerCase() === _kiwi.gateway.get("nick").toLowerCase()) {
628 that.panels.server.addMsg('', '== ' + event.nick + ' set mode ' + friendlyModeString(), 'action mode');
629 } else {
630 console.log('MODE command recieved for unknown target %s: ', event.target, event);
631 }
632 }
633 });
634
635
636 gw.on('onnick', function (event) {
637 var member;
638
639 $.each(that.panels.models, function (index, panel) {
640 if (!panel.isChannel()) return;
641
642 member = panel.get('members').getByNick(event.nick);
643 if (member) {
644 member.set('nick', event.newnick);
645 panel.addMsg('', '== ' + event.nick + ' is now known as ' + event.newnick, 'action nick');
646 }
647 });
648 });
649
650
651 gw.on('onwhois', function (event) {
652 /*globals secondsToTime */
653 var logon_date, idle_time = '', panel;
654
655 if (event.end) {
656 return;
657 }
658
659 if (typeof event.idle !== 'undefined') {
660 idle_time = secondsToTime(parseInt(event.idle, 10));
661 idle_time = idle_time.h.toString().lpad(2, "0") + ':' + idle_time.m.toString().lpad(2, "0") + ':' + idle_time.s.toString().lpad(2, "0");
662 }
663
664 panel = _kiwi.app.panels.active;
665 if (event.ident) {
666 panel.addMsg(event.nick, event.nick + ' [' + event.nick + '!' + event.ident + '@' + event.host + '] * ' + event.msg, 'whois');
667 } else if (event.chans) {
668 panel.addMsg(event.nick, 'Channels: ' + event.chans, 'whois');
669 } else if (event.irc_server) {
670 panel.addMsg(event.nick, 'Connected to server: ' + event.irc_server, 'whois');
671 } else if (event.msg) {
672 panel.addMsg(event.nick, event.msg, 'whois');
673 } else if (event.logon) {
674 logon_date = new Date();
675 logon_date.setTime(event.logon * 1000);
676 logon_date = formatDate(logon_date);
677
678 panel.addMsg(event.nick, 'idle for ' + idle_time + ', signed on ' + logon_date, 'whois');
679 } else {
680 panel.addMsg(event.nick, 'idle for ' + idle_time, 'whois');
681 }
682 });
683
684 gw.on('onaway', function (event) {
685 $.each(that.panels.models, function (index, panel) {
686 if (!panel.isChannel()) return;
687
688 member = panel.get('members').getByNick(event.nick);
689 if (member) {
690 member.set('away', !(!event.trailing));
691 }
692 });
693 });
694
695
696 gw.on('onlist_start', function (data) {
697 if (_kiwi.app.channel_list) {
698 _kiwi.app.channel_list.close();
699 delete _kiwi.app.channel_list;
700 }
701
702 var panel = new _kiwi.model.Applet(),
703 applet = new _kiwi.applets.Chanlist();
704
705 panel.load(applet);
706
707 _kiwi.app.panels.add(panel);
708 panel.view.show();
709
710 _kiwi.app.channel_list = applet;
711 });
712
713
714 gw.on('onlist_channel', function (data) {
715 // TODO: Put this listener within the applet itself
716 _kiwi.app.channel_list.addChannel(data.chans);
717 });
718
719
720 gw.on('onlist_end', function (data) {
721 // TODO: Put this listener within the applet itself
722 delete _kiwi.app.channel_list;
723 });
724
725
726 gw.on('onirc_error', function (data) {
727 var panel, tmp;
728
729 if (data.channel !== undefined && !(panel = _kiwi.app.panels.getByName(data.channel))) {
730 panel = _kiwi.app.panels.server;
731 }
732
733 switch (data.error) {
734 case 'banned_from_channel':
735 panel.addMsg(' ', '== You are banned from ' + data.channel + '. ' + data.reason, 'status');
736 _kiwi.app.message.text('You are banned from ' + data.channel + '. ' + data.reason);
737 break;
738 case 'bad_channel_key':
739 panel.addMsg(' ', '== Bad channel key for ' + data.channel, 'status');
740 _kiwi.app.message.text('Bad channel key or password for ' + data.channel);
741 break;
742 case 'invite_only_channel':
743 panel.addMsg(' ', '== ' + data.channel + ' is invite only.', 'status');
744 _kiwi.app.message.text(data.channel + ' is invite only');
745 break;
746 case 'channel_is_full':
747 panel.addMsg(' ', '== ' + data.channel + ' is full.', 'status');
748 _kiwi.app.message.text(data.channel + ' is full');
749 break;
750 case 'chanop_privs_needed':
751 panel.addMsg(' ', '== ' + data.reason, 'status');
752 _kiwi.app.message.text(data.reason + ' (' + data.channel + ')');
753 break;
754 case 'no_such_nick':
755 tmp = _kiwi.app.panels.getByName(data.nick);
756 if (tmp) {
757 tmp.addMsg(' ', '== ' + data.nick + ': ' + data.reason, 'status');
758 } else {
759 _kiwi.app.panels.server.addMsg(' ', '== ' + data.nick + ': ' + data.reason, 'status');
760 }
761 break;
762 case 'nickname_in_use':
763 _kiwi.app.panels.server.addMsg(' ', '== The nickname ' + data.nick + ' is already in use. Please select a new nickname', 'status');
764 if (_kiwi.app.panels.server !== _kiwi.app.panels.active) {
765 _kiwi.app.message.text('The nickname "' + data.nick + '" is already in use. Please select a new nickname');
766 }
767
768 // Only show the nickchange component if the controlbox is open
769 if (that.controlbox.$el.css('display') !== 'none') {
770 (new _kiwi.view.NickChangeBox()).render();
771 }
772
773 case 'password_mismatch':
774 _kiwi.app.panels.server.addMsg(' ', '== Incorrect password given', 'status');
775 break;
776 default:
777 // We don't know what data contains, so don't do anything with it.
778 //_kiwi.front.tabviews.server.addMsg(null, ' ', '== ' + data, 'status');
779 }
780 });
781 };
782
783
784
785 /**
786 * Bind to certain commands that may be typed into the control box
787 */
788 this.bindControllboxCommands = function (controlbox) {
789 // Default aliases
790 $.extend(controlbox.preprocessor.aliases, {
791 // General aliases
792 '/p': '/part $1+',
793 '/me': '/action $1+',
794 '/j': '/join $1+',
795 '/q': '/query $1+',
796
797 // Op related aliases
798 '/op': '/quote mode $channel +o $1+',
799 '/deop': '/quote mode $channel -o $1+',
800 '/hop': '/quote mode $channel +h $1+',
801 '/dehop': '/quote mode $channel -h $1+',
802 '/voice': '/quote mode $channel +v $1+',
803 '/devoice': '/quote mode $channel -v $1+',
804 '/k': '/kick $channel $1+',
805
806 // Misc aliases
807 '/slap': '/me slaps $1 around a bit with a large trout'
808 });
809
810 controlbox.on('unknown_command', unknownCommand);
811
812 controlbox.on('command', allCommands);
813 controlbox.on('command:msg', msgCommand);
814
815 controlbox.on('command:action', actionCommand);
816
817 controlbox.on('command:join', joinCommand);
818
819 controlbox.on('command:part', partCommand);
820
821 controlbox.on('command:nick', function (ev) {
822 _kiwi.gateway.changeNick(ev.params[0]);
823 });
824
825 controlbox.on('command:query', queryCommand);
826
827 controlbox.on('command:topic', topicCommand);
828
829 controlbox.on('command:notice', noticeCommand);
830
831 controlbox.on('command:quote', quoteCommand);
832
833 controlbox.on('command:kick', kickCommand);
834
835 controlbox.on('command:clear', clearCommand);
836
837 controlbox.on('command_ctcp', ctcpCommand);
838
839
840 controlbox.on('command:css', function (ev) {
841 var queryString = '?reload=' + new Date().getTime();
842 $('link[rel="stylesheet"]').each(function () {
843 this.href = this.href.replace(/\?.*|$/, queryString);
844 });
845 });
846
847 controlbox.on('command:js', function (ev) {
848 if (!ev.params[0]) return;
849 $script(ev.params[0] + '?' + (new Date().getTime()));
850 });
851
852
853 controlbox.on('command:set', function (ev) {
854 if (!ev.params[0]) return;
855
856 var setting = ev.params[0],
857 value;
858
859 // Do we have a second param to set a value?
860 if (ev.params[1]) {
861 ev.params.shift();
862
863 value = ev.params.join(' ');
864 _kiwi.global.settings.set(setting, value);
865 }
866
867 // Read the value to the user
868 _kiwi.app.panels.active.addMsg('', setting + ' = ' + _kiwi.global.settings.get(setting));
869 });
870
871
872 controlbox.on('command:save', function (ev) {
873 _kiwi.global.settings.save();
874 _kiwi.app.panels.active.addMsg('', 'Settings have been saved');
875 });
876
877
878 controlbox.on('command:alias', function (ev) {
879 var name, rule;
880
881 // No parameters passed so list them
882 if (!ev.params[1]) {
883 $.each(controlbox.preprocessor.aliases, function (name, rule) {
884 _kiwi.app.panels.server.addMsg(' ', name + ' => ' + rule);
885 });
886 return;
887 }
888
889 // Deleting an alias?
890 if (ev.params[0] === 'del' || ev.params[0] === 'delete') {
891 name = ev.params[1];
892 if (name[0] !== '/') name = '/' + name;
893 delete controlbox.preprocessor.aliases[name];
894 return;
895 }
896
897 // Add the alias
898 name = ev.params[0];
899 ev.params.shift();
900 rule = ev.params.join(' ');
901
902 // Make sure the name starts with a slash
903 if (name[0] !== '/') name = '/' + name;
904
905 // Now actually add the alias
906 controlbox.preprocessor.aliases[name] = rule;
907 });
908
909 controlbox.on('command:applet', appletCommand);
910 controlbox.on('command:settings', settingsCommand);
911 controlbox.on('command:script', scriptCommand);
912 };
913
914 // A fallback action. Send a raw command to the server
915 function unknownCommand (ev) {
916 var raw_cmd = ev.command + ' ' + ev.params.join(' ');
917 console.log('RAW: ' + raw_cmd);
918 _kiwi.gateway.raw(raw_cmd);
919 }
920
921 function allCommands (ev) {}
922
923 function joinCommand (ev) {
924 var channel, channel_names;
925
926 channel_names = ev.params.join(' ').split(',');
927
928 $.each(channel_names, function (index, channel_name) {
929 // Trim any whitespace off the name
930 channel_name = channel_name.trim();
931
932 // Check if we have the panel already. If not, create it
933 channel = that.panels.getByName(channel_name);
934 if (!channel) {
935 channel = new _kiwi.model.Channel({name: channel_name});
936 _kiwi.app.panels.add(channel);
937 }
938
939 _kiwi.gateway.join(channel_name);
940 });
941
942 if (channel) channel.view.show();
943
944 }
945
946 function queryCommand (ev) {
947 var destination, panel;
948
949 destination = ev.params[0];
950
951 // Check if we have the panel already. If not, create it
952 panel = that.panels.getByName(destination);
953 if (!panel) {
954 panel = new _kiwi.model.Query({name: destination});
955 _kiwi.app.panels.add(panel);
956 }
957
958 if (panel) panel.view.show();
959
960 }
961
962 function msgCommand (ev) {
963 var destination = ev.params[0],
964 panel = that.panels.getByName(destination) || that.panels.server;
965
966 ev.params.shift();
967
968 panel.addMsg(_kiwi.gateway.get('nick'), ev.params.join(' '));
969 _kiwi.gateway.privmsg(destination, ev.params.join(' '));
970 }
971
972 function actionCommand (ev) {
973 if (_kiwi.app.panels.active === _kiwi.app.panels.server) {
974 return;
975 }
976
977 var panel = _kiwi.app.panels.active;
978 panel.addMsg('', '* ' + _kiwi.gateway.get('nick') + ' ' + ev.params.join(' '), 'action');
979 _kiwi.gateway.action(panel.get('name'), ev.params.join(' '));
980 }
981
982 function partCommand (ev) {
983 if (ev.params.length === 0) {
984 _kiwi.gateway.part(_kiwi.app.panels.active.get('name'));
985 } else {
986 _.each(ev.params, function (channel) {
987 _kiwi.gateway.part(channel);
988 });
989 }
990 // TODO: More responsive = close tab now, more accurate = leave until part event
991 //_kiwi.app.panels.remove(_kiwi.app.panels.active);
992 }
993
994 function topicCommand (ev) {
995 var channel_name;
996
997 if (ev.params.length === 0) return;
998
999 if (that.isChannelName(ev.params[0])) {
1000 channel_name = ev.params[0];
1001 ev.params.shift();
1002 } else {
1003 channel_name = _kiwi.app.panels.active.get('name');
1004 }
1005
1006 _kiwi.gateway.topic(channel_name, ev.params.join(' '));
1007 }
1008
1009 function noticeCommand (ev) {
1010 var destination;
1011
1012 // Make sure we have a destination and some sort of message
1013 if (ev.params.length <= 1) return;
1014
1015 destination = ev.params[0];
1016 ev.params.shift();
1017
1018 _kiwi.gateway.notice(destination, ev.params.join(' '));
1019 }
1020
1021 function quoteCommand (ev) {
1022 var raw = ev.params.join(' ');
1023 _kiwi.gateway.raw(raw);
1024 }
1025
1026 function kickCommand (ev) {
1027 var nick, panel = _kiwi.app.panels.active;
1028
1029 if (!panel.isChannel()) return;
1030
1031 // Make sure we have a nick
1032 if (ev.params.length === 0) return;
1033
1034 nick = ev.params[0];
1035 ev.params.shift();
1036
1037 _kiwi.gateway.kick(panel.get('name'), nick, ev.params.join(' '));
1038 }
1039
1040 function clearCommand (ev) {
1041 // Can't clear a server or applet panel
1042 if (_kiwi.app.panels.active.isServer() || _kiwi.app.panels.active.isApplet()) {
1043 return;
1044 }
1045
1046 if (_kiwi.app.panels.active.clearMessages) {
1047 _kiwi.app.panels.active.clearMessages();
1048 }
1049 }
1050
1051 function ctcpCommand(ev) {
1052 var target, type;
1053
1054 // Make sure we have a target and a ctcp type (eg. version, time)
1055 if (ev.params.length < 2) return;
1056
1057 target = ev.params[0];
1058 ev.params.shift();
1059
1060 type = ev.params[0];
1061 ev.params.shift();
1062
1063 _kiwi.gateway.ctcp(true, type, target, ev.params.join(' '));
1064 }
1065
1066 function settingsCommand (ev) {
1067 var settings = _kiwi.model.Applet.loadOnce('kiwi_settings');
1068 settings.view.show();
1069 }
1070
1071 function scriptCommand (ev) {
1072 var editor = _kiwi.model.Applet.loadOnce('kiwi_script_editor');
1073 editor.view.show();
1074 }
1075
1076 function appletCommand (ev) {
1077 if (!ev.params[0]) return;
1078
1079 var panel = new _kiwi.model.Applet();
1080
1081 if (ev.params[1]) {
1082 // Url and name given
1083 panel.load(ev.params[0], ev.params[1]);
1084 } else {
1085 // Load a pre-loaded applet
1086 if (_kiwi.applets[ev.params[0]]) {
1087 panel.load(new _kiwi.applets[ev.params[0]]());
1088 } else {
1089 _kiwi.app.panels.server.addMsg('', 'Applet "' + ev.params[0] + '" does not exist');
1090 return;
1091 }
1092 }
1093
1094 _kiwi.app.panels.add(panel);
1095 panel.view.show();
1096 }
1097
1098
1099
1100
1101
1102 this.isChannelName = function (channel_name) {
1103 var channel_prefix = _kiwi.gateway.get('channel_prefix');
1104
1105 if (!channel_name || !channel_name.length) return false;
1106 return (channel_prefix.indexOf(channel_name[0]) > -1);
1107 };
1108
1109 };
1110
1111
1112 model = Backbone.Model.extend(new model());
1113
1114 return new model(arguments);
1115 };