Channel Info+admin window; RPL_CHANNEL_URL; Ban list; CSS forms refactor
[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.set('kiwi_server', _kiwi.app.kiwi_server);
462
463 _kiwi.gateway.reconnect(function() {
464 // Reconnect all the IRC connections
465 that.connections.forEach(function(con){ con.reconnect(); });
466 });
467 }, 5000);
468
469 }, jump_server_interval * 1000);
470 }
471 });
472 };
473
474
475
476 /**
477 * Bind to certain commands that may be typed into the control box
478 */
479 this.bindControllboxCommands = function (controlbox) {
480 // Default aliases
481 $.extend(controlbox.preprocessor.aliases, {
482 // General aliases
483 '/p': '/part $1+',
484 '/me': '/action $1+',
485 '/j': '/join $1+',
486 '/q': '/query $1+',
487 '/w': '/whois $1+',
488 '/raw': '/quote $1+',
489
490 // Op related aliases
491 '/op': '/quote mode $channel +o $1+',
492 '/deop': '/quote mode $channel -o $1+',
493 '/hop': '/quote mode $channel +h $1+',
494 '/dehop': '/quote mode $channel -h $1+',
495 '/voice': '/quote mode $channel +v $1+',
496 '/devoice': '/quote mode $channel -v $1+',
497 '/k': '/kick $channel $1+',
498 '/ban': '/quote mode $channel +b $1+',
499 '/unban': '/quote mode $channel -b $1+',
500
501 // Misc aliases
502 '/slap': '/me slaps $1 around a bit with a large trout'
503 });
504
505 controlbox.on('unknown_command', unknownCommand);
506
507 controlbox.on('command', allCommands);
508 controlbox.on('command:msg', msgCommand);
509
510 controlbox.on('command:action', actionCommand);
511
512 controlbox.on('command:join', joinCommand);
513
514 controlbox.on('command:part', partCommand);
515
516 controlbox.on('command:nick', function (ev) {
517 _kiwi.gateway.changeNick(null, ev.params[0]);
518 });
519
520 controlbox.on('command:query', queryCommand);
521
522 controlbox.on('command:invite', inviteCommand);
523
524 controlbox.on('command:topic', topicCommand);
525
526 controlbox.on('command:notice', noticeCommand);
527
528 controlbox.on('command:quote', quoteCommand);
529
530 controlbox.on('command:kick', kickCommand);
531
532 controlbox.on('command:clear', clearCommand);
533
534 controlbox.on('command:ctcp', ctcpCommand);
535
536 controlbox.on('command:server', serverCommand);
537
538 controlbox.on('command:whois', whoisCommand);
539
540 controlbox.on('command:whowas', whowasCommand);
541
542 controlbox.on('command:encoding', encodingCommand);
543
544 controlbox.on('command:info', function(ev) {
545 var active_panel = _kiwi.app.panels().active;
546
547 if (!active_panel.isChannel())
548 return;
549
550 new _kiwi.model.ChannelInfo({channel: _kiwi.app.panels().active});
551 });
552
553 controlbox.on('command:css', function (ev) {
554 var queryString = '?reload=' + new Date().getTime();
555 $('link[rel="stylesheet"]').each(function () {
556 this.href = this.href.replace(/\?.*|$/, queryString);
557 });
558 });
559
560 controlbox.on('command:js', function (ev) {
561 if (!ev.params[0]) return;
562 $script(ev.params[0] + '?' + (new Date().getTime()));
563 });
564
565
566 controlbox.on('command:set', function (ev) {
567 if (!ev.params[0]) return;
568
569 var setting = ev.params[0],
570 value;
571
572 // Do we have a second param to set a value?
573 if (ev.params[1]) {
574 ev.params.shift();
575
576 value = ev.params.join(' ');
577
578 // If we're setting a true boolean value..
579 if (value === 'true')
580 value = true;
581
582 // If we're setting a false boolean value..
583 if (value === 'false')
584 value = false;
585
586 // If we're setting a number..
587 if (parseInt(value, 10).toString() === value)
588 value = parseInt(value, 10);
589
590 _kiwi.global.settings.set(setting, value);
591 }
592
593 // Read the value to the user
594 _kiwi.app.panels().active.addMsg('', setting + ' = ' + _kiwi.global.settings.get(setting).toString());
595 });
596
597
598 controlbox.on('command:save', function (ev) {
599 _kiwi.global.settings.save();
600 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_settings_saved').fetch());
601 });
602
603
604 controlbox.on('command:alias', function (ev) {
605 var name, rule;
606
607 // No parameters passed so list them
608 if (!ev.params[1]) {
609 $.each(controlbox.preprocessor.aliases, function (name, rule) {
610 _kiwi.app.panels().server.addMsg(' ', name + ' => ' + rule);
611 });
612 return;
613 }
614
615 // Deleting an alias?
616 if (ev.params[0] === 'del' || ev.params[0] === 'delete') {
617 name = ev.params[1];
618 if (name[0] !== '/') name = '/' + name;
619 delete controlbox.preprocessor.aliases[name];
620 return;
621 }
622
623 // Add the alias
624 name = ev.params[0];
625 ev.params.shift();
626 rule = ev.params.join(' ');
627
628 // Make sure the name starts with a slash
629 if (name[0] !== '/') name = '/' + name;
630
631 // Now actually add the alias
632 controlbox.preprocessor.aliases[name] = rule;
633 });
634
635
636 controlbox.on('command:ignore', function (ev) {
637 var list = _kiwi.gateway.get('ignore_list');
638
639 // No parameters passed so list them
640 if (!ev.params[0]) {
641 if (list.length > 0) {
642 _kiwi.app.panels().active.addMsg(' ', _kiwi.global.i18n.translate('client_models_application_ignore_title').fetch() + ':');
643 $.each(list, function (idx, ignored_pattern) {
644 _kiwi.app.panels().active.addMsg(' ', ignored_pattern);
645 });
646 } else {
647 _kiwi.app.panels().active.addMsg(' ', _kiwi.global.i18n.translate('client_models_application_ignore_none').fetch());
648 }
649 return;
650 }
651
652 // We have a parameter, so add it
653 list.push(ev.params[0]);
654 _kiwi.gateway.set('ignore_list', list);
655 _kiwi.app.panels().active.addMsg(' ', _kiwi.global.i18n.translate('client_models_application_ignore_nick').fetch(ev.params[0]));
656 });
657
658
659 controlbox.on('command:unignore', function (ev) {
660 var list = _kiwi.gateway.get('ignore_list');
661
662 if (!ev.params[0]) {
663 _kiwi.app.panels().active.addMsg(' ', _kiwi.global.i18n.translate('client_models_application_ignore_stop_notice').fetch());
664 return;
665 }
666
667 list = _.reject(list, function(pattern) {
668 return pattern === ev.params[0];
669 });
670
671 _kiwi.gateway.set('ignore_list', list);
672
673 _kiwi.app.panels().active.addMsg(' ', _kiwi.global.i18n.translate('client_models_application_ignore_stopped').fetch(ev.params[0]));
674 });
675
676
677 controlbox.on('command:applet', appletCommand);
678 controlbox.on('command:settings', settingsCommand);
679 controlbox.on('command:script', scriptCommand);
680 };
681
682 // A fallback action. Send a raw command to the server
683 function unknownCommand (ev) {
684 var raw_cmd = ev.command + ' ' + ev.params.join(' ');
685 console.log('RAW: ' + raw_cmd);
686 _kiwi.gateway.raw(null, raw_cmd);
687 }
688
689 function allCommands (ev) {}
690
691 function joinCommand (ev) {
692 var panels, channel_names;
693
694 channel_names = ev.params.join(' ').split(',');
695 panels = that.connections.active_connection.createAndJoinChannels(channel_names);
696
697 // Show the last channel if we have one
698 if (panels.length)
699 panels[panels.length - 1].view.show();
700 }
701
702 function queryCommand (ev) {
703 var destination, message, panel;
704
705 destination = ev.params[0];
706 ev.params.shift();
707
708 message = ev.params.join(' ');
709
710 // Check if we have the panel already. If not, create it
711 panel = that.connections.active_connection.panels.getByName(destination);
712 if (!panel) {
713 panel = new _kiwi.model.Query({name: destination});
714 that.connections.active_connection.panels.add(panel);
715 }
716
717 if (panel) panel.view.show();
718
719 if (message) {
720 that.connections.active_connection.gateway.msg(panel.get('name'), message);
721 panel.addMsg(_kiwi.app.connections.active_connection.get('nick'), message);
722 }
723
724 }
725
726 function msgCommand (ev) {
727 var message,
728 destination = ev.params[0],
729 panel = that.connections.active_connection.panels.getByName(destination) || that.panels().server;
730
731 ev.params.shift();
732 message = formatToIrcMsg(ev.params.join(' '));
733
734 panel.addMsg(_kiwi.app.connections.active_connection.get('nick'), message);
735 _kiwi.gateway.privmsg(null, destination, message);
736 }
737
738 function actionCommand (ev) {
739 if (_kiwi.app.panels().active.isServer()) {
740 return;
741 }
742
743 var panel = _kiwi.app.panels().active;
744 panel.addMsg('', '* ' + _kiwi.app.connections.active_connection.get('nick') + ' ' + ev.params.join(' '), 'action');
745 _kiwi.gateway.action(null, panel.get('name'), ev.params.join(' '));
746 }
747
748 function partCommand (ev) {
749 if (ev.params.length === 0) {
750 _kiwi.gateway.part(null, _kiwi.app.panels().active.get('name'));
751 } else {
752 _.each(ev.params, function (channel) {
753 _kiwi.gateway.part(null, channel);
754 });
755 }
756 }
757
758 function topicCommand (ev) {
759 var channel_name;
760
761 if (ev.params.length === 0) return;
762
763 if (that.isChannelName(ev.params[0])) {
764 channel_name = ev.params[0];
765 ev.params.shift();
766 } else {
767 channel_name = _kiwi.app.panels().active.get('name');
768 }
769
770 _kiwi.gateway.topic(null, channel_name, ev.params.join(' '));
771 }
772
773 function noticeCommand (ev) {
774 var destination;
775
776 // Make sure we have a destination and some sort of message
777 if (ev.params.length <= 1) return;
778
779 destination = ev.params[0];
780 ev.params.shift();
781
782 _kiwi.gateway.notice(null, destination, ev.params.join(' '));
783 }
784
785 function quoteCommand (ev) {
786 var raw = ev.params.join(' ');
787 _kiwi.gateway.raw(null, raw);
788 }
789
790 function kickCommand (ev) {
791 var nick, panel = _kiwi.app.panels().active;
792
793 if (!panel.isChannel()) return;
794
795 // Make sure we have a nick
796 if (ev.params.length === 0) return;
797
798 nick = ev.params[0];
799 ev.params.shift();
800
801 _kiwi.gateway.kick(null, panel.get('name'), nick, ev.params.join(' '));
802 }
803
804 function clearCommand (ev) {
805 // Can't clear a server or applet panel
806 if (_kiwi.app.panels().active.isServer() || _kiwi.app.panels().active.isApplet()) {
807 return;
808 }
809
810 if (_kiwi.app.panels().active.clearMessages) {
811 _kiwi.app.panels().active.clearMessages();
812 }
813 }
814
815 function ctcpCommand(ev) {
816 var target, type;
817
818 // Make sure we have a target and a ctcp type (eg. version, time)
819 if (ev.params.length < 2) return;
820
821 target = ev.params[0];
822 ev.params.shift();
823
824 type = ev.params[0];
825 ev.params.shift();
826
827 _kiwi.gateway.ctcp(null, true, type, target, ev.params.join(' '));
828 }
829
830 function settingsCommand (ev) {
831 var settings = _kiwi.model.Applet.loadOnce('kiwi_settings');
832 settings.view.show();
833 }
834
835 function scriptCommand (ev) {
836 var editor = _kiwi.model.Applet.loadOnce('kiwi_script_editor');
837 editor.view.show();
838 }
839
840 function appletCommand (ev) {
841 if (!ev.params[0]) return;
842
843 var panel = new _kiwi.model.Applet();
844
845 if (ev.params[1]) {
846 // Url and name given
847 panel.load(ev.params[0], ev.params[1]);
848 } else {
849 // Load a pre-loaded applet
850 if (_kiwi.applets[ev.params[0]]) {
851 panel.load(new _kiwi.applets[ev.params[0]]());
852 } else {
853 _kiwi.app.panels().server.addMsg('', _kiwi.global.i18n.translate('client_models_application_applet_notfound').fetch(ev.params[0]));
854 return;
855 }
856 }
857
858 _kiwi.app.connections.active_connection.panels.add(panel);
859 panel.view.show();
860 }
861
862
863
864 function inviteCommand (ev) {
865 var nick, channel;
866
867 // A nick must be specified
868 if (!ev.params[0])
869 return;
870
871 // Can only invite into channels
872 if (!_kiwi.app.panels().active.isChannel())
873 return;
874
875 nick = ev.params[0];
876 channel = _kiwi.app.panels().active.get('name');
877
878 _kiwi.app.connections.active_connection.gateway.raw('INVITE ' + nick + ' ' + channel);
879
880 _kiwi.app.panels().active.addMsg('', '== ' + nick + ' has been invited to ' + channel, 'action');
881 }
882
883
884 function whoisCommand (ev) {
885 var nick;
886
887 if (ev.params[0]) {
888 nick = ev.params[0];
889 } else if (_kiwi.app.panels().active.isQuery()) {
890 nick = _kiwi.app.panels().active.get('name');
891 }
892
893 if (nick)
894 _kiwi.app.connections.active_connection.gateway.raw('WHOIS ' + nick + ' ' + nick);
895 }
896
897
898 function whowasCommand (ev) {
899 var nick;
900
901 if (ev.params[0]) {
902 nick = ev.params[0];
903 } else if (_kiwi.app.panels().active.isQuery()) {
904 nick = _kiwi.app.panels().active.get('name');
905 }
906
907 if (nick)
908 _kiwi.app.connections.active_connection.gateway.raw('WHOWAS ' + nick);
909 }
910
911 function encodingCommand (ev) {
912 if (ev.params[0]) {
913 _kiwi.gateway.setEncoding(null, ev.params[0], function (success) {
914 if (success) {
915 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_encoding_changed').fetch(ev.params[0]));
916 } else {
917 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_encoding_invalid').fetch(ev.params[0]));
918 }
919 });
920 } else {
921 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_encoding_notspecified').fetch());
922 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_encoding_usage').fetch());
923 }
924 }
925
926 function serverCommand (ev) {
927 var server, port, ssl, password, nick,
928 tmp;
929
930 // If no server address given, show the new connection dialog
931 if (!ev.params[0]) {
932 tmp = new _kiwi.view.MenuBox(_kiwi.global.i18n.translate('client_models_application_connection_create').fetch());
933 tmp.addItem('new_connection', new _kiwi.model.NewConnection().view.$el);
934 tmp.show();
935
936 // Center screen the dialog
937 tmp.$el.offset({
938 top: (that.view.$el.height() / 2) - (tmp.$el.height() / 2),
939 left: (that.view.$el.width() / 2) - (tmp.$el.width() / 2)
940 });
941
942 return;
943 }
944
945 // Port given in 'host:port' format and no specific port given after a space
946 if (ev.params[0].indexOf(':') > 0) {
947 tmp = ev.params[0].split(':');
948 server = tmp[0];
949 port = tmp[1];
950
951 password = ev.params[1] || undefined;
952
953 } else {
954 // Server + port given as 'host port'
955 server = ev.params[0];
956 port = ev.params[1] || 6667;
957
958 password = ev.params[2] || undefined;
959 }
960
961 // + in the port means SSL
962 if (port.toString()[0] === '+') {
963 ssl = true;
964 port = parseInt(port.substring(1), 10);
965 } else {
966 ssl = false;
967 }
968
969 // Default port if one wasn't found
970 port = port || 6667;
971
972 // Use the same nick as we currently have
973 nick = _kiwi.app.connections.active_connection.get('nick');
974
975 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_connection_connecting').fetch(server, port.toString()));
976
977 _kiwi.gateway.newConnection({
978 nick: nick,
979 host: server,
980 port: port,
981 ssl: ssl,
982 password: password
983 }, function(err, new_connection) {
984 if (err)
985 _kiwi.app.panels().active.addMsg('', _kiwi.global.i18n.translate('client_models_application_connection_error').fetch(server, port.toString(), err.toString()));
986 });
987 }
988
989
990
991
992
993 this.isChannelName = function (channel_name) {
994 var channel_prefix = _kiwi.gateway.get('channel_prefix');
995
996 if (!channel_name || !channel_name.length) return false;
997 return (channel_prefix.indexOf(channel_name[0]) > -1);
998 };
999
1000
1001 };
1002
1003
1004 model = Backbone.Model.extend(new model());
1005
1006 return new model(arguments);
1007 };