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