Merge pull request #421 from CoryChaplin/development
[KiwiIRC.git] / client / src / models / application.js
1 _kiwi.model.Application = function () {
2 // Set to a reference to this object within initialize()
3 var that = null;
4
5
6 var model = function () {
7 /** _kiwi.view.Application */
8 this.view = null;
9
10 /** _kiwi.view.StatusMessage */
11 this.message = null;
12
13 /* Address for the kiwi server */
14 this.kiwi_server = null;
15
16 this.initialize = function (options) {
17 that = this;
18
19 if (options[0].container) {
20 this.set('container', options[0].container);
21 }
22
23 // The base url to the kiwi server
24 this.set('base_path', options[0].base_path ? options[0].base_path : '/kiwi');
25
26 // Path for the settings.json file
27 this.set('settings_path', options[0].settings_path ?
28 options[0].settings_path :
29 this.get('base_path') + '/assets/settings.json'
30 );
31
32 // Any options sent down from the server
33 this.server_settings = options[0].server_settings || {};
34 this.translations = options[0].translations || {};
35
36 // Best guess at where the kiwi server is
37 this.detectKiwiServer();
38
39 // Set any default settings before anything else is applied
40 if (this.server_settings && this.server_settings.client && this.server_settings.client.settings) {
41 this.applyDefaultClientSettings(this.server_settings.client.settings);
42 }
43 };
44
45
46 this.start = function () {
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.showIntialConenctionDialog();
57 };
58
59
60 this.detectKiwiServer = function () {
61 // If running from file, default to localhost:7777 by default
62 if (window.location.protocol === 'file:') {
63 this.kiwi_server = 'http://localhost:7778';
64 } else {
65 // Assume the kiwi server is on the same server
66 this.kiwi_server = window.location.protocol + '//' + window.location.host;
67 }
68 };
69
70
71 this.showIntialConenctionDialog = function() {
72 var connection_dialog = new _kiwi.model.NewConnection();
73 this.populateDefaultServerSettings(connection_dialog);
74
75 connection_dialog.view.$el.addClass('initial');
76 this.view.$el.find('.panel_container:first').append(connection_dialog.view.$el);
77
78 var $info = $($('#tmpl_new_connection_info').html().trim());
79
80 if ($info.html()) {
81 connection_dialog.view.infoBoxSet($info);
82 connection_dialog.view.infoBoxShow();
83 }
84
85 // TODO: Shouldn't really be here but it's not working in the view.. :/
86 // Hack for firefox browers: Focus is not given on this event loop iteration
87 setTimeout(function(){
88 connection_dialog.view.$el.find('.nick').select();
89 }, 0);
90
91 // Once connected, close this dialog and remove its own event
92 var fn = function() {
93 connection_dialog.view.$el.slideUp(function() {
94 connection_dialog.view.dispose();
95 connection_dialog = null;
96
97 _kiwi.gateway.off('onconnect', fn);
98 });
99
100 };
101 _kiwi.gateway.on('onconnect', fn);
102 };
103
104
105 this.initializeClient = function () {
106 this.view = new _kiwi.view.Application({model: this, el: this.get('container')});
107
108 // Takes instances of model_network
109 this.connections = new _kiwi.model.NetworkPanelList();
110
111 // Applets panel list
112 this.applet_panels = new _kiwi.model.PanelList();
113 this.applet_panels.view.$el.addClass('panellist applets');
114 this.view.$el.find('.tabs').append(this.applet_panels.view.$el);
115
116 /**
117 * Set the UI components up
118 */
119 this.controlbox = new _kiwi.view.ControlBox({el: $('#kiwi .controlbox')[0]});
120 this.bindControllboxCommands(this.controlbox);
121
122 this.topicbar = new _kiwi.view.TopicBar({el: this.view.$el.find('.topic')[0]});
123
124 new _kiwi.view.AppToolbar({el: _kiwi.app.view.$el.find('.toolbar .app_tools')[0]});
125
126 this.message = new _kiwi.view.StatusMessage({el: this.view.$el.find('.status_message')[0]});
127
128 this.resize_handle = new _kiwi.view.ResizeHandler({el: this.view.$el.find('.memberlists_resize_handle')[0]});
129
130 // Rejigg the UI sizes
131 this.view.doLayout();
132 };
133
134
135 this.initializeGlobals = function () {
136 _kiwi.global.connections = this.connections;
137
138 _kiwi.global.panels = this.panels;
139 _kiwi.global.panels.applets = this.applet_panels;
140
141 _kiwi.global.components.Applet = _kiwi.model.Applet;
142 _kiwi.global.components.Panel =_kiwi.model.Panel;
143 };
144
145
146 this.applyDefaultClientSettings = function (settings) {
147 _.each(settings, function (value, setting) {
148 if (typeof _kiwi.global.settings.get(setting) === 'undefined') {
149 _kiwi.global.settings.set(setting, value);
150 }
151 });
152 };
153
154
155 this.populateDefaultServerSettings = function (new_connection_dialog) {
156 var parts;
157 var defaults = {
158 nick: '',
159 server: '',
160 port: 6667,
161 ssl: false,
162 channel: '#chat',
163 channel_key: ''
164 };
165 var uricheck;
166
167
168 /**
169 * Get any settings set by the server
170 * These settings may be changed in the server selection dialog or via URL parameters
171 */
172 if (this.server_settings.client) {
173 if (this.server_settings.client.nick)
174 defaults.nick = this.server_settings.client.nick;
175
176 if (this.server_settings.client.server)
177 defaults.server = this.server_settings.client.server;
178
179 if (this.server_settings.client.port)
180 defaults.port = this.server_settings.client.port;
181
182 if (this.server_settings.client.ssl)
183 defaults.ssl = this.server_settings.client.ssl;
184
185 if (this.server_settings.client.channel)
186 defaults.channel = this.server_settings.client.channel;
187
188 if (this.server_settings.client.channel_key)
189 defaults.channel_key = this.server_settings.client.channel_key;
190 }
191
192
193
194 /**
195 * Get any settings passed in the URL
196 * These settings may be changed in the server selection dialog
197 */
198
199 // Any query parameters first
200 if (getQueryVariable('nick'))
201 defaults.nick = getQueryVariable('nick');
202
203 if (window.location.hash)
204 defaults.channel = window.location.hash;
205
206
207 // Process the URL part by part, extracting as we go
208 parts = window.location.pathname.toString().replace(this.get('base_path'), '').split('/');
209
210 if (parts.length > 0) {
211 parts.shift();
212
213 if (parts.length > 0 && parts[0]) {
214 // 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.
215 uricheck = parts[0].substr(0, 7).toLowerCase();
216 if ((uricheck === 'ircs%3a') || (uricheck.substr(0,6) === 'irc%3a')) {
217 parts[0] = decodeURIComponent(parts[0]);
218 // irc[s]://<host>[:<port>]/[<channel>[?<password>]]
219 uricheck = /^irc(s)?:(?:\/\/?)?([^:\/]+)(?::([0-9]+))?(?:(?:\/)([^\?]*)(?:(?:\?)(.*))?)?$/.exec(parts[0]);
220 /*
221 uricheck[1] = ssl (optional)
222 uricheck[2] = host
223 uricheck[3] = port (optional)
224 uricheck[4] = channel (optional)
225 uricheck[5] = channel key (optional, channel must also be set)
226 */
227 if (uricheck) {
228 if (typeof uricheck[1] !== 'undefined') {
229 defaults.ssl = true;
230 if (defaults.port === 6667) {
231 defaults.port = 6697;
232 }
233 }
234 defaults.server = uricheck[2];
235 if (typeof uricheck[3] !== 'undefined') {
236 defaults.port = uricheck[3];
237 }
238 if (typeof uricheck[4] !== 'undefined') {
239 defaults.channel = '#' + uricheck[4];
240 if (typeof uricheck[5] !== 'undefined') {
241 defaults.channel_key = uricheck[5];
242 }
243 }
244 }
245 parts = [];
246 } else {
247 // Extract the port+ssl if we find one
248 if (parts[0].search(/:/) > 0) {
249 defaults.port = parts[0].substring(parts[0].search(/:/) + 1);
250 defaults.server = parts[0].substring(0, parts[0].search(/:/));
251 if (defaults.port[0] === '+') {
252 defaults.port = parseInt(defaults.port.substring(1), 10);
253 defaults.ssl = true;
254 } else {
255 defaults.ssl = false;
256 }
257
258 } else {
259 defaults.server = parts[0];
260 }
261
262 parts.shift();
263 }
264 }
265
266 if (parts.length > 0 && parts[0]) {
267 defaults.channel = '#' + parts[0];
268 parts.shift();
269 }
270 }
271
272 // If any settings have been given by the server.. override any auto detected settings
273 /**
274 * Get any server restrictions as set in the server config
275 * These settings can not be changed in the server selection dialog
276 */
277 if (this.server_settings && this.server_settings.connection) {
278 if (this.server_settings.connection.server) {
279 defaults.server = this.server_settings.connection.server;
280 }
281
282 if (this.server_settings.connection.port) {
283 defaults.port = this.server_settings.connection.port;
284 }
285
286 if (this.server_settings.connection.ssl) {
287 defaults.ssl = this.server_settings.connection.ssl;
288 }
289
290 if (this.server_settings.connection.channel) {
291 defaults.channel = this.server_settings.connection.channel;
292 }
293
294 if (this.server_settings.connection.channel_key) {
295 defaults.channel_key = this.server_settings.connection.channel_key;
296 }
297
298 if (this.server_settings.connection.nick) {
299 defaults.nick = this.server_settings.connection.nick;
300 }
301 }
302
303 // Set any random numbers if needed
304 defaults.nick = defaults.nick.replace('?', Math.floor(Math.random() * 100000).toString());
305
306 if (getQueryVariable('encoding'))
307 defaults.encoding = getQueryVariable('encoding');
308
309 // Populate the server select box with defaults
310 new_connection_dialog.view.populateFields(defaults);
311 };
312
313
314 this.panels = (function() {
315 var fn = function(panel_type) {
316 var panels;
317
318 // Default panel type
319 panel_type = panel_type || 'connections';
320
321 switch (panel_type) {
322 case 'connections':
323 panels = this.connections.panels();
324 break;
325 case 'applets':
326 panels = this.applet_panels.models;
327 break;
328 }
329
330 // Active panels / server
331 panels.active = this.connections.active_panel;
332 panels.server = this.connections.active_connection ?
333 this.connections.active_connection.panels.server :
334 null;
335
336 return panels;
337 };
338
339 _.extend(fn, Backbone.Events);
340
341 return fn;
342 })();
343
344
345 this.bindGatewayCommands = function (gw) {
346 var that = this;
347
348 gw.on('onconnect', function (event) {
349 that.view.barsShow();
350 });
351
352
353 /**
354 * Handle the reconnections to the kiwi server
355 */
356 (function () {
357 // 0 = non-reconnecting state. 1 = reconnecting state.
358 var gw_stat = 0;
359
360 // If the current or upcoming disconnect was planned
361 var unplanned_disconnect = false;
362
363 gw.on('disconnect', function (event) {
364 unplanned_disconnect = !gw.disconnect_requested;
365
366 if (unplanned_disconnect) {
367 var msg = _kiwi.global.i18n.translate('client_models_application_reconnecting').fetch() + '...';
368 that.message.text(msg, {timeout: 10000});
369 }
370
371 that.view.$el.removeClass('connected');
372
373 // Mention the disconnection on every channel
374 _kiwi.app.connections.forEach(function(connection) {
375 connection.panels.server.addMsg('', msg, 'action quit');
376
377 connection.panels.forEach(function(panel) {
378 if (!panel.isChannel())
379 return;
380
381 panel.addMsg('', msg, 'action quit');
382 });
383 });
384
385 gw_stat = 1;
386 });
387
388
389 gw.on('reconnecting', function (event) {
390 var msg = _kiwi.global.i18n.translate('client_models_application_reconnect_in_x_seconds').fetch(event.delay/1000) + '...';
391
392 // Only need to mention the repeating re-connection messages on server panels
393 _kiwi.app.connections.forEach(function(connection) {
394 connection.panels.server.addMsg('', msg, 'action quit');
395 });
396 });
397
398
399 gw.on('onconnect', function (event) {
400 that.view.$el.addClass('connected');
401 if (gw_stat !== 1) return;
402
403 if (unplanned_disconnect) {
404 var msg = _kiwi.global.i18n.translate('client_models_application_reconnect_successfully').fetch() + ':)';
405 that.message.text(msg, {timeout: 5000});
406 }
407
408 // Mention the re-connection on every channel
409 _kiwi.app.connections.forEach(function(connection) {
410 connection.panels.server.addMsg('', msg, 'action join');
411
412 connection.panels.forEach(function(panel) {
413 if (!panel.isChannel())
414 return;
415
416 panel.addMsg('', msg, 'action join');
417 });
418 });
419
420 gw_stat = 0;
421 });
422 })();
423
424
425 gw.on('kiwi:reconfig', function () {
426 $.getJSON(that.get('settings_path'), function (data) {
427 that.server_settings = data.server_settings || {};
428 that.translations = data.translations || {};
429 });
430 });
431
432
433 gw.on('kiwi:jumpserver', function (data) {
434 var serv;
435 // No server set? Then nowhere to jump to.
436 if (typeof data.kiwi_server === 'undefined')
437 return;
438
439 serv = data.kiwi_server;
440
441 // Strip any trailing slash from the end
442 if (serv[serv.length-1] === '/')
443 serv = serv.substring(0, serv.length-1);
444
445 _kiwi.app.kiwi_server = serv;
446
447 // Force the jumpserver now?
448 if (data.force) {
449 // Get an interval between 5 and 6 minutes so everyone doesn't reconnect it all at once
450 var jump_server_interval = Math.random() * (360 - 300) + 300;
451
452 // Tell the user we are going to disconnect, wait 5 minutes then do the actual reconnect
453 var msg = _kiwi.global.i18n.translate('client_models_application_jumpserver_prepare').fetch();
454 that.message.text(msg, {timeout: 10000});
455
456 setTimeout(function forcedReconnect() {
457 var msg = _kiwi.global.i18n.translate('client_models_application_jumpserver_reconnect').fetch();
458 that.message.text(msg, {timeout: 8000});
459
460 setTimeout(function forcedReconnectPartTwo() {
461 _kiwi.gateway.reconnect(function() {
462 // Reconnect all the IRC connections
463 that.connections.forEach(function(con){ con.reconnect(); });
464 });
465 }, 5000);
466
467 }, jump_server_interval * 1000);
468 }
469 });
470 };
471
472
473
474 /**
475 * Bind to certain commands that may be typed into the control box
476 */
477 this.bindControllboxCommands = function (controlbox) {
478 // Default aliases
479 $.extend(controlbox.preprocessor.aliases, {
480 // General aliases
481 '/p': '/part $1+',
482 '/me': '/action $1+',
483 '/j': '/join $1+',
484 '/q': '/query $1+',
485 '/w': '/whois $1+',
486 '/raw': '/quote $1+',
487
488 // Op related aliases
489 '/op': '/quote mode $channel +o $1+',
490 '/deop': '/quote mode $channel -o $1+',
491 '/hop': '/quote mode $channel +h $1+',
492 '/dehop': '/quote mode $channel -h $1+',
493 '/voice': '/quote mode $channel +v $1+',
494 '/devoice': '/quote mode $channel -v $1+',
495 '/k': '/kick $channel $1+',
496
497 // Misc aliases
498 '/slap': '/me slaps $1 around a bit with a large trout'
499 });
500
501 controlbox.on('unknown_command', unknownCommand);
502
503 controlbox.on('command', allCommands);
504 controlbox.on('command:msg', msgCommand);
505
506 controlbox.on('command:action', actionCommand);
507
508 controlbox.on('command:join', joinCommand);
509
510 controlbox.on('command:part', partCommand);
511
512 controlbox.on('command:nick', function (ev) {
513 _kiwi.gateway.changeNick(null, ev.params[0]);
514 });
515
516 controlbox.on('command:query', queryCommand);
517
518 controlbox.on('command:invite', inviteCommand);
519
520 controlbox.on('command:topic', topicCommand);
521
522 controlbox.on('command:notice', noticeCommand);
523
524 controlbox.on('command:quote', quoteCommand);
525
526 controlbox.on('command:kick', kickCommand);
527
528 controlbox.on('command:clear', clearCommand);
529
530 controlbox.on('command:ctcp', ctcpCommand);
531
532 controlbox.on('command:server', serverCommand);
533
534 controlbox.on('command:whois', whoisCommand);
535
536 controlbox.on('command:whowas', whowasCommand);
537
538 controlbox.on('command:encoding', encodingCommand);
539
540 controlbox.on('command:css', function (ev) {
541 var queryString = '?reload=' + new Date().getTime();
542 $('link[rel="stylesheet"]').each(function () {
543 this.href = this.href.replace(/\?.*|$/, queryString);
544 });
545 });
546
547 controlbox.on('command:js', function (ev) {
548 if (!ev.params[0]) return;
549 $script(ev.params[0] + '?' + (new Date().getTime()));
550 });
551
552
553 controlbox.on('command:set', function (ev) {
554 if (!ev.params[0]) return;
555
556 var setting = ev.params[0],
557 value;
558
559 // Do we have a second param to set a value?
560 if (ev.params[1]) {
561 ev.params.shift();
562
563 value = ev.params.join(' ');
564
565 // If we're setting a true boolean value..
566 if (value === 'true')
567 value = true;
568
569 // If we're setting a false boolean value..
570 if (value === 'false')
571 value = false;
572
573 // If we're setting a number..
574 if (parseInt(value, 10).toString() === value)
575 value = parseInt(value, 10);
576
577 _kiwi.global.settings.set(setting, value);
578 }
579
580 // Read the value to the user
581 _kiwi.app.panels().active.addMsg('', setting + ' = ' + _kiwi.global.settings.get(setting).toString());
582 });
583
584
585 controlbox.on('command:save', function (ev) {
586 _kiwi.global.settings.save();
587 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_settings_saved').fetch());
588 });
589
590
591 controlbox.on('command:alias', function (ev) {
592 var name, rule;
593
594 // No parameters passed so list them
595 if (!ev.params[1]) {
596 $.each(controlbox.preprocessor.aliases, function (name, rule) {
597 _kiwi.app.panels().server.addMsg(' ', name + ' => ' + rule);
598 });
599 return;
600 }
601
602 // Deleting an alias?
603 if (ev.params[0] === 'del' || ev.params[0] === 'delete') {
604 name = ev.params[1];
605 if (name[0] !== '/') name = '/' + name;
606 delete controlbox.preprocessor.aliases[name];
607 return;
608 }
609
610 // Add the alias
611 name = ev.params[0];
612 ev.params.shift();
613 rule = ev.params.join(' ');
614
615 // Make sure the name starts with a slash
616 if (name[0] !== '/') name = '/' + name;
617
618 // Now actually add the alias
619 controlbox.preprocessor.aliases[name] = rule;
620 });
621
622
623 controlbox.on('command:ignore', function (ev) {
624 var list = _kiwi.gateway.get('ignore_list');
625
626 // No parameters passed so list them
627 if (!ev.params[0]) {
628 if (list.length > 0) {
629 _kiwi.app.panels().active.addMsg(' ', _kiwi.global.i18n.translate('client_models_application_ignore_title').fetch() + ':');
630 $.each(list, function (idx, ignored_pattern) {
631 _kiwi.app.panels().active.addMsg(' ', ignored_pattern);
632 });
633 } else {
634 _kiwi.app.panels().active.addMsg(' ', _kiwi.global.i18n.translate('client_models_application_ignore_none').fetch());
635 }
636 return;
637 }
638
639 // We have a parameter, so add it
640 list.push(ev.params[0]);
641 _kiwi.gateway.set('ignore_list', list);
642 _kiwi.app.panels().active.addMsg(' ', _kiwi.global.i18n.translate('client_models_application_ignore_nick').fetch(ev.params[0]));
643 });
644
645
646 controlbox.on('command:unignore', function (ev) {
647 var list = _kiwi.gateway.get('ignore_list');
648
649 if (!ev.params[0]) {
650 _kiwi.app.panels().active.addMsg(' ', _kiwi.global.i18n.translate('client_models_application_ignore_stop_notice').fetch());
651 return;
652 }
653
654 list = _.reject(list, function(pattern) {
655 return pattern === ev.params[0];
656 });
657
658 _kiwi.gateway.set('ignore_list', list);
659
660 _kiwi.app.panels().active.addMsg(' ', _kiwi.global.i18n.translate('client_models_application_ignore_stopped').fetch(ev.params[0]));
661 });
662
663
664 controlbox.on('command:applet', appletCommand);
665 controlbox.on('command:settings', settingsCommand);
666 controlbox.on('command:script', scriptCommand);
667 };
668
669 // A fallback action. Send a raw command to the server
670 function unknownCommand (ev) {
671 var raw_cmd = ev.command + ' ' + ev.params.join(' ');
672 console.log('RAW: ' + raw_cmd);
673 _kiwi.gateway.raw(null, raw_cmd);
674 }
675
676 function allCommands (ev) {}
677
678 function joinCommand (ev) {
679 var panels, channel_names;
680
681 channel_names = ev.params.join(' ').split(',');
682 panels = that.connections.active_connection.createAndJoinChannels(channel_names);
683
684 // Show the last channel if we have one
685 if (panels.length)
686 panels[panels.length - 1].view.show();
687 }
688
689 function queryCommand (ev) {
690 var destination, message, panel;
691
692 destination = ev.params[0];
693 ev.params.shift();
694
695 message = ev.params.join(' ');
696
697 // Check if we have the panel already. If not, create it
698 panel = that.connections.active_connection.panels.getByName(destination);
699 if (!panel) {
700 panel = new _kiwi.model.Query({name: destination});
701 that.connections.active_connection.panels.add(panel);
702 }
703
704 if (panel) panel.view.show();
705
706 if (message) {
707 that.connections.active_connection.gateway.msg(panel.get('name'), message);
708 panel.addMsg(_kiwi.app.connections.active_connection.get('nick'), message);
709 }
710
711 }
712
713 function msgCommand (ev) {
714 var destination = ev.params[0],
715 panel = that.connections.active_connection.panels.getByName(destination) || that.panels().server;
716
717 ev.params.shift();
718
719 panel.addMsg(_kiwi.app.connections.active_connection.get('nick'), ev.params.join(' '));
720 _kiwi.gateway.privmsg(null, destination, ev.params.join(' '));
721 }
722
723 function actionCommand (ev) {
724 if (_kiwi.app.panels().active.isServer()) {
725 return;
726 }
727
728 var panel = _kiwi.app.panels().active;
729 panel.addMsg('', '* ' + _kiwi.app.connections.active_connection.get('nick') + ' ' + ev.params.join(' '), 'action');
730 _kiwi.gateway.action(null, panel.get('name'), ev.params.join(' '));
731 }
732
733 function partCommand (ev) {
734 if (ev.params.length === 0) {
735 _kiwi.gateway.part(null, _kiwi.app.panels().active.get('name'));
736 } else {
737 _.each(ev.params, function (channel) {
738 _kiwi.gateway.part(null, channel);
739 });
740 }
741 }
742
743 function topicCommand (ev) {
744 var channel_name;
745
746 if (ev.params.length === 0) return;
747
748 if (that.isChannelName(ev.params[0])) {
749 channel_name = ev.params[0];
750 ev.params.shift();
751 } else {
752 channel_name = _kiwi.app.panels().active.get('name');
753 }
754
755 _kiwi.gateway.topic(null, channel_name, ev.params.join(' '));
756 }
757
758 function noticeCommand (ev) {
759 var destination;
760
761 // Make sure we have a destination and some sort of message
762 if (ev.params.length <= 1) return;
763
764 destination = ev.params[0];
765 ev.params.shift();
766
767 _kiwi.gateway.notice(null, destination, ev.params.join(' '));
768 }
769
770 function quoteCommand (ev) {
771 var raw = ev.params.join(' ');
772 _kiwi.gateway.raw(null, raw);
773 }
774
775 function kickCommand (ev) {
776 var nick, panel = _kiwi.app.panels().active;
777
778 if (!panel.isChannel()) return;
779
780 // Make sure we have a nick
781 if (ev.params.length === 0) return;
782
783 nick = ev.params[0];
784 ev.params.shift();
785
786 _kiwi.gateway.kick(null, panel.get('name'), nick, ev.params.join(' '));
787 }
788
789 function clearCommand (ev) {
790 // Can't clear a server or applet panel
791 if (_kiwi.app.panels().active.isServer() || _kiwi.app.panels().active.isApplet()) {
792 return;
793 }
794
795 if (_kiwi.app.panels().active.clearMessages) {
796 _kiwi.app.panels().active.clearMessages();
797 }
798 }
799
800 function ctcpCommand(ev) {
801 var target, type;
802
803 // Make sure we have a target and a ctcp type (eg. version, time)
804 if (ev.params.length < 2) return;
805
806 target = ev.params[0];
807 ev.params.shift();
808
809 type = ev.params[0];
810 ev.params.shift();
811
812 _kiwi.gateway.ctcp(null, true, type, target, ev.params.join(' '));
813 }
814
815 function settingsCommand (ev) {
816 var settings = _kiwi.model.Applet.loadOnce('kiwi_settings');
817 settings.view.show();
818 }
819
820 function scriptCommand (ev) {
821 var editor = _kiwi.model.Applet.loadOnce('kiwi_script_editor');
822 editor.view.show();
823 }
824
825 function appletCommand (ev) {
826 if (!ev.params[0]) return;
827
828 var panel = new _kiwi.model.Applet();
829
830 if (ev.params[1]) {
831 // Url and name given
832 panel.load(ev.params[0], ev.params[1]);
833 } else {
834 // Load a pre-loaded applet
835 if (_kiwi.applets[ev.params[0]]) {
836 panel.load(new _kiwi.applets[ev.params[0]]());
837 } else {
838 _kiwi.app.panels().server.addMsg('', _kiwi.global.i18n.translate('client_models_application_applet_notfound').fetch(ev.params[0]));
839 return;
840 }
841 }
842
843 _kiwi.app.connections.active_connection.panels.add(panel);
844 panel.view.show();
845 }
846
847
848
849 function inviteCommand (ev) {
850 var nick, channel;
851
852 // A nick must be specified
853 if (!ev.params[0])
854 return;
855
856 // Can only invite into channels
857 if (!_kiwi.app.panels().active.isChannel())
858 return;
859
860 nick = ev.params[0];
861 channel = _kiwi.app.panels().active.get('name');
862
863 _kiwi.app.connections.active_connection.gateway.raw('INVITE ' + nick + ' ' + channel);
864
865 _kiwi.app.panels().active.addMsg('', '== ' + nick + ' has been invited to ' + channel, 'action');
866 }
867
868
869 function whoisCommand (ev) {
870 var nick;
871
872 if (ev.params[0]) {
873 nick = ev.params[0];
874 } else if (_kiwi.app.panels().active.isQuery()) {
875 nick = _kiwi.app.panels().active.get('name');
876 }
877
878 if (nick)
879 _kiwi.app.connections.active_connection.gateway.raw('WHOIS ' + nick + ' ' + nick);
880 }
881
882
883 function whowasCommand (ev) {
884 var nick;
885
886 if (ev.params[0]) {
887 nick = ev.params[0];
888 } else if (_kiwi.app.panels().active.isQuery()) {
889 nick = _kiwi.app.panels().active.get('name');
890 }
891
892 if (nick)
893 _kiwi.app.connections.active_connection.gateway.raw('WHOWAS ' + nick);
894 }
895
896 function encodingCommand (ev) {
897 if (ev.params[0]) {
898 _kiwi.gateway.setEncoding(null, ev.params[0], function (success) {
899 if (success) {
900 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_encoding_changed').fetch(ev.params[0]));
901 } else {
902 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_encoding_invalid').fetch(ev.params[0]));
903 }
904 });
905 } else {
906 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_encoding_notspecified').fetch());
907 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_encoding_usage').fetch());
908 }
909 }
910
911 function serverCommand (ev) {
912 var server, port, ssl, password, nick,
913 tmp;
914
915 // If no server address given, show the new connection dialog
916 if (!ev.params[0]) {
917 tmp = new _kiwi.view.MenuBox(_kiwi.global.i18n.translate('client_models_application_connection_create').fetch());
918 tmp.addItem('new_connection', new _kiwi.model.NewConnection().view.$el);
919 tmp.show();
920
921 // Center screen the dialog
922 tmp.$el.offset({
923 top: (that.view.$el.height() / 2) - (tmp.$el.height() / 2),
924 left: (that.view.$el.width() / 2) - (tmp.$el.width() / 2)
925 });
926
927 return;
928 }
929
930 // Port given in 'host:port' format and no specific port given after a space
931 if (ev.params[0].indexOf(':') > 0) {
932 tmp = ev.params[0].split(':');
933 server = tmp[0];
934 port = tmp[1];
935
936 password = ev.params[1] || undefined;
937
938 } else {
939 // Server + port given as 'host port'
940 server = ev.params[0];
941 port = ev.params[1] || 6667;
942
943 password = ev.params[2] || undefined;
944 }
945
946 // + in the port means SSL
947 if (port.toString()[0] === '+') {
948 ssl = true;
949 port = parseInt(port.substring(1), 10);
950 } else {
951 ssl = false;
952 }
953
954 // Default port if one wasn't found
955 port = port || 6667;
956
957 // Use the same nick as we currently have
958 nick = _kiwi.app.connections.active_connection.get('nick');
959
960 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_connection_connecting').fetch(server, port.toString()));
961
962 _kiwi.gateway.newConnection({
963 nick: nick,
964 host: server,
965 port: port,
966 ssl: ssl,
967 password: password
968 }, function(err, new_connection) {
969 if (err)
970 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_connection_error').fetch(server, port.toString(), err.toString()));
971 });
972 }
973
974
975
976
977
978 this.isChannelName = function (channel_name) {
979 var channel_prefix = _kiwi.gateway.get('channel_prefix');
980
981 if (!channel_name || !channel_name.length) return false;
982 return (channel_prefix.indexOf(channel_name[0]) > -1);
983 };
984
985
986 };
987
988
989 model = Backbone.Model.extend(new model());
990
991 return new model(arguments);
992 };