Client: Active panel/connection tracking
[KiwiIRC.git] / client / assets / dev / model_network.js
CommitLineData
ce13508b
D
1(function () {
2
3 _kiwi.model.Network = Backbone.Model.extend({
4 defaults: {
5 connection_id: 0,
6 /**
7 * The name of the network
8 * @type String
9 */
10 name: 'Network',
11
12 /**
13 * The address (URL) of the network
14 * @type String
15 */
16 address: '',
17
18 /**
19 * The current nickname
20 * @type String
21 */
22 nick: '',
23
24 /**
25 * The channel prefix for this network
26 * @type String
27 */
28 channel_prefix: '#',
29
30 /**
31 * The user prefixes for channel owner/admin/op/voice etc. on this network
32 * @type Array
33 */
34 user_prefixes: ['~', '&', '@', '+']
35 },
36
37
38 initialize: function () {
39 this.gateway = _kiwi.global.components.Network(this.get('connection_id'));
40 this.bindGatewayEvents();
41
0e546dd4
D
42 this.panels = new _kiwi.model.PanelList([], this);
43 this.panels.network = this;
44
45 // Automatically create a server tab
46 var server_panel = new _kiwi.model.Server({name: 'Server'});
47 this.panels.add(server_panel);
48 this.panels.server = server_panel;
ce13508b
D
49 },
50
51
52 bindGatewayEvents: function () {
0e546dd4 53 //this.gateway.on('all', function() {console.log('ALL', this.get('connection_id'), arguments);});
ce13508b
D
54
55 this.gateway.on('connect', function(event) {
56 this.set('nick', event.nick);
57 }, this);
58
59 this.gateway.on('nick', function(event) {
2ffd1291 60 if (event.nick === this.get('nick')) {
ce13508b
D
61 this.set('nick', event.newnick);
62 }
63 }, this);
64
65 this.gateway.on('options', onOptions, this);
66 this.gateway.on('motd', onMotd, this);
67 this.gateway.on('join', onJoin, this);
68 this.gateway.on('part', onPart, this);
69 this.gateway.on('quit', onQuit, this);
70 this.gateway.on('kick', onKick, this);
71 this.gateway.on('msg', onMsg, this);
72 this.gateway.on('ctcp_request', onCtcpRequest, this);
73 this.gateway.on('ctcp_response', onCtcpResponse, this);
74 this.gateway.on('notice', onNotice, this);
75 this.gateway.on('action', onAction, this);
76 this.gateway.on('topic', onTopic, this);
77 this.gateway.on('topicsetby', onTopicSetBy, this);
78 this.gateway.on('userlist', onUserlist, this);
79 this.gateway.on('userlist_end', onUserlistEnd, this);
80 this.gateway.on('mode', onMode, this);
81 this.gateway.on('whois', onWhois, this);
82 this.gateway.on('away', onAway, this);
83 this.gateway.on('list_start', onListStart, this);
ce13508b
D
84 }
85 });
86
87
88
89 function onOptions(event) {
90 var that = this;
91
92 $.each(event.options, function (name, value) {
93 switch (name) {
94 case 'CHANTYPES':
95 that.set('channel_prefix', value.join(''));
96 break;
97 case 'NETWORK':
98 that.set('name', value);
99 break;
100 case 'PREFIX':
101 that.set('user_prefixes', value);
102 break;
103 }
104 });
105
106 this.set('cap', event.cap);
107 }
108
109
110
111 function onMotd(event) {
112 this.panels.server.addMsg(this.get('name'), event.msg, 'motd');
113 }
114
115
116
117 function onJoin(event) {
118 var c, members, user;
119 c = this.panels.getByName(event.channel);
120 if (!c) {
121 c = new _kiwi.model.Channel({name: event.channel});
122 this.panels.add(c);
123 }
124
125 members = c.get('members');
126 if (!members) return;
127
128 user = new _kiwi.model.Member({nick: event.nick, ident: event.ident, hostname: event.hostname});
129 members.add(user);
130 }
131
132
133
134 function onPart(event) {
135 var channel, members, user,
136 part_options = {};
137
138 part_options.type = 'part';
139 part_options.message = event.message || '';
140
141 channel = this.panels.getByName(event.channel);
142 if (!channel) return;
143
144 // If this is us, close the panel
145 if (event.nick === this.get('nick')) {
146 channel.close();
147 return;
148 }
149
150 members = channel.get('members');
151 if (!members) return;
152
153 user = members.getByNick(event.nick);
154 if (!user) return;
155
156 members.remove(user, part_options);
157 }
158
159
160
161 function onQuit(event) {
162 var member, members,
163 quit_options = {};
164
165 quit_options.type = 'quit';
166 quit_options.message = event.message || '';
167
168 $.each(this.panels.models, function (index, panel) {
169 if (!panel.isChannel()) return;
170
171 member = panel.get('members').getByNick(event.nick);
172 if (member) {
173 panel.get('members').remove(member, quit_options);
174 }
175 });
176 }
177
178
179
180 function onKick(event) {
181 var channel, members, user,
182 part_options = {};
183
184 part_options.type = 'kick';
185 part_options.by = event.nick;
186 part_options.message = event.message || '';
187
188 channel = this.panels.getByName(event.channel);
189 if (!channel) return;
190
191 members = channel.get('members');
192 if (!members) return;
193
194 user = members.getByNick(event.kicked);
195 if (!user) return;
196
197 members.remove(user, part_options);
198
199 if (event.kicked === this.get('nick')) {
200 members.reset([]);
201 }
202 }
203
204
205
206 function onMsg(event) {
207 var panel,
208 is_pm = (event.channel == this.get('nick'));
209
210 // An ignored user? don't do anything with it
211 if (_kiwi.gateway.isNickIgnored(event.nick)) {
212 return;
213 }
214
215 if (is_pm) {
216 // If a panel isn't found for this PM, create one
217 panel = this.panels.getByName(event.nick);
218 if (!panel) {
219 panel = new _kiwi.model.Query({name: event.nick});
220 this.panels.add(panel);
221 }
222
223 } else {
224 // If a panel isn't found for this channel, reroute to the
225 // server panel
226 panel = this.panels.getByName(event.channel);
227 if (!panel) {
228 panel = this.panels.server;
229 }
230 }
231
232 panel.addMsg(event.nick, event.msg);
233 }
234
235
236
237 function onCtcpRequest(event) {
238 // An ignored user? don't do anything with it
239 if (_kiwi.gateway.isNickIgnored(event.nick)) {
240 return;
241 }
242
243 // Reply to a TIME ctcp
244 if (event.msg.toUpperCase() === 'TIME') {
245 this.gateway.ctcp(false, event.type, event.nick, (new Date()).toString());
246 }
247 }
248
249
250
251 function onCtcpResponse(event) {
252 // An ignored user? don't do anything with it
253 if (_kiwi.gateway.isNickIgnored(event.nick)) {
254 return;
255 }
256
257 this.panels.server.addMsg('[' + event.nick + ']', 'CTCP ' + event.msg);
258 }
259
260
261
262 function onNotice(event) {
263 var panel;
264
265 // An ignored user? don't do anything with it
266 if (event.nick && _kiwi.gateway.isNickIgnored(event.nick)) {
267 return;
268 }
269
270 // Find a panel for the destination(channel) or who its from
271 panel = this.panels.getByName(event.target) || this.panels.getByName(event.nick);
272 if (!panel) {
273 panel = this.panels.server;
274 }
275
276 panel.addMsg('[' + (event.nick||'') + ']', event.msg);
277 }
278
279
280
281 function onAction(event) {
282 var panel,
283 is_pm = (event.channel == this.get('nick'));
284
285 // An ignored user? don't do anything with it
286 if (_kiwi.gateway.isNickIgnored(event.nick)) {
287 return;
288 }
289
290 if (is_pm) {
291 // If a panel isn't found for this PM, create one
292 panel = this.panels.getByName(event.nick);
293 if (!panel) {
294 panel = new _kiwi.model.Channel({name: event.nick});
295 this.panels.add(panel);
296 }
297
298 } else {
299 // If a panel isn't found for this channel, reroute to the
300 // server panel
301 panel = this.panels.getByName(event.channel);
302 if (!panel) {
303 panel = this.panels.server;
304 }
305 }
306
307 panel.addMsg('', '* ' + event.nick + ' ' + event.msg, 'action');
308 }
309
310
311
312 function onTopic(event) {
313 var c;
314 c = this.panels.getByName(event.channel);
315 if (!c) return;
316
317 // Set the channels topic
318 c.set('topic', event.topic);
319
320 // If this is the active channel, update the topic bar too
321 if (c.get('name') === this.panels.active.get('name')) {
322 _kiwi.app.topicbar.setCurrentTopic(event.topic);
323 }
324 }
325
326
327
328 function onTopicSetBy(event) {
329 var c, when;
330 c = this.panels.getByName(event.channel);
331 if (!c) return;
332
333 when = formatDate(new Date(event.when * 1000));
334 c.addMsg('', 'Topic set by ' + event.nick + ' at ' + when, 'topic');
335 }
336
337
338
339 function onUserlist(event) {
340 var channel;
341 channel = this.panels.getByName(event.channel);
342
343 // If we didn't find a channel for this, may aswell leave
344 if (!channel) return;
345
346 channel.temp_userlist = channel.temp_userlist || [];
347 _.each(event.users, function (item) {
348 var user = new _kiwi.model.Member({nick: item.nick, modes: item.modes});
349 channel.temp_userlist.push(user);
350 });
351 }
352
353
354
355 function onUserlistEnd(event) {
356 var channel;
357 channel = this.panels.getByName(event.channel);
358
359 // If we didn't find a channel for this, may aswell leave
360 if (!channel) return;
361
362 // Update the members list with the new list
363 channel.get('members').reset(channel.temp_userlist || []);
364
365 // Clear the temporary userlist
366 delete channel.temp_userlist;
367 }
368
369
370
371 function onMode(event) {
372 var channel, i, prefixes, members, member, find_prefix;
373
374 // Build a nicely formatted string to be displayed to a regular human
375 function friendlyModeString (event_modes, alt_target) {
376 var modes = {}, return_string;
377
378 // If no default given, use the main event info
379 if (!event_modes) {
380 event_modes = event.modes;
381 alt_target = event.target;
382 }
383
384 // Reformat the mode object to make it easier to work with
385 _.each(event_modes, function (mode){
386 var param = mode.param || alt_target || '';
387
388 // Make sure we have some modes for this param
389 if (!modes[param]) {
390 modes[param] = {'+':'', '-':''};
391 }
392
393 modes[param][mode.mode[0]] += mode.mode.substr(1);
394 });
395
396 // Put the string together from each mode
397 return_string = [];
398 _.each(modes, function (modeset, param) {
399 var str = '';
400 if (modeset['+']) str += '+' + modeset['+'];
401 if (modeset['-']) str += '-' + modeset['-'];
402 return_string.push(str + ' ' + param);
403 });
404 return_string = return_string.join(', ');
405
406 return return_string;
407 }
408
409
410 channel = this.panels.getByName(event.target);
411 if (channel) {
412 prefixes = this.get('user_prefixes');
413 find_prefix = function (p) {
414 return event.modes[i].mode[1] === p.mode;
415 };
416 for (i = 0; i < event.modes.length; i++) {
417 if (_.any(prefixes, find_prefix)) {
418 if (!members) {
419 members = channel.get('members');
420 }
421 member = members.getByNick(event.modes[i].param);
422 if (!member) {
423 console.log('MODE command recieved for unknown member %s on channel %s', event.modes[i].param, event.target);
424 return;
425 } else {
426 if (event.modes[i].mode[0] === '+') {
427 member.addMode(event.modes[i].mode[1]);
428 } else if (event.modes[i].mode[0] === '-') {
429 member.removeMode(event.modes[i].mode[1]);
430 }
431 members.sort();
432 //channel.addMsg('', '== ' + event.nick + ' set mode ' + event.modes[i].mode + ' ' + event.modes[i].param, 'action mode');
433 }
434 } else {
435 // Channel mode being set
436 // TODO: Store this somewhere?
437 //channel.addMsg('', 'CHANNEL === ' + event.nick + ' set mode ' + event.modes[i].mode + ' on ' + event.target, 'action mode');
438 }
439 }
440
441 channel.addMsg('', '== ' + event.nick + ' sets mode ' + friendlyModeString(), 'action mode');
442 } else {
443 // This is probably a mode being set on us.
444 if (event.target.toLowerCase() === this.get("nick").toLowerCase()) {
445 this.panels.server.addMsg('', '== ' + event.nick + ' set mode ' + friendlyModeString(), 'action mode');
446 } else {
447 console.log('MODE command recieved for unknown target %s: ', event.target, event);
448 }
449 }
450 }
451
452
453
454 function onWhois(event) {
455 var logon_date, idle_time = '', panel;
456
457 if (event.end)
458 return;
459
460 if (typeof event.idle !== 'undefined') {
461 idle_time = secondsToTime(parseInt(event.idle, 10));
462 idle_time = idle_time.h.toString().lpad(2, "0") + ':' + idle_time.m.toString().lpad(2, "0") + ':' + idle_time.s.toString().lpad(2, "0");
463 }
464
465 panel = _kiwi.app.panels.active;
466 if (event.ident) {
467 panel.addMsg(event.nick, event.nick + ' [' + event.nick + '!' + event.ident + '@' + event.host + '] * ' + event.msg, 'whois');
468 } else if (event.chans) {
469 panel.addMsg(event.nick, 'Channels: ' + event.chans, 'whois');
470 } else if (event.irc_server) {
471 panel.addMsg(event.nick, 'Connected to server: ' + event.irc_server, 'whois');
472 } else if (event.msg) {
473 panel.addMsg(event.nick, event.msg, 'whois');
474 } else if (event.logon) {
475 logon_date = new Date();
476 logon_date.setTime(event.logon * 1000);
477 logon_date = formatDate(logon_date);
478
479 panel.addMsg(event.nick, 'idle for ' + idle_time + ', signed on ' + logon_date, 'whois');
480 } else {
481 panel.addMsg(event.nick, 'idle for ' + idle_time, 'whois');
482 }
483 }
484
485
486
487 function onAway(event) {
488 $.each(this.panels.models, function (index, panel) {
489 if (!panel.isChannel()) return;
490
491 member = panel.get('members').getByNick(event.nick);
492 if (member) {
493 member.set('away', !(!event.trailing));
494 }
495 });
496 }
497
498
499
500 function onListStart(event) {
b24da6ba
D
501 var chanlist = _kiwi.model.Applet.loadOnce('kiwi_chanlist');
502 chanlist.view.show();
ce13508b
D
503 }
504
505
506
507 function onIrcError(event) {
508 var panel, tmp;
509
510 if (event.channel !== undefined && !(panel = _kiwi.app.panels.getByName(event.channel))) {
511 panel = this.panels.server;
512 }
513
514 switch (event.error) {
515 case 'banned_from_channel':
516 panel.addMsg(' ', '== You are banned from ' + event.channel + '. ' + event.reason, 'status');
517 _kiwi.app.message.text('You are banned from ' + event.channel + '. ' + event.reason);
518 break;
519 case 'bad_channel_key':
520 panel.addMsg(' ', '== Bad channel key for ' + event.channel, 'status');
521 _kiwi.app.message.text('Bad channel key or password for ' + event.channel);
522 break;
523 case 'invite_only_channel':
524 panel.addMsg(' ', '== ' + event.channel + ' is invite only.', 'status');
525 _kiwi.app.message.text(event.channel + ' is invite only');
526 break;
527 case 'channel_is_full':
528 panel.addMsg(' ', '== ' + event.channel + ' is full.', 'status');
529 _kiwi.app.message.text(event.channel + ' is full');
530 break;
531 case 'chanop_privs_needed':
532 panel.addMsg(' ', '== ' + event.reason, 'status');
533 _kiwi.app.message.text(event.reason + ' (' + event.channel + ')');
534 break;
535 case 'no_such_nick':
536 tmp = this.panels.getByName(event.nick);
537 if (tmp) {
538 tmp.addMsg(' ', '== ' + event.nick + ': ' + event.reason, 'status');
539 } else {
540 this.panels.server.addMsg(' ', '== ' + event.nick + ': ' + event.reason, 'status');
541 }
542 break;
543 case 'nickname_in_use':
544 this.panels.server.addMsg(' ', '== The nickname ' + event.nick + ' is already in use. Please select a new nickname', 'status');
545 if (this.panels.server !== thia.panels.active) {
546 _kiwi.app.message.text('The nickname "' + event.nick + '" is already in use. Please select a new nickname');
547 }
548
549 // Only show the nickchange component if the controlbox is open
550 if (that.controlbox.$el.css('display') !== 'none') {
551 (new _kiwi.view.NickChangeBox()).render();
552 }
553
554 break;
555
556 case 'password_mismatch':
557 this.panels.server.addMsg(' ', '== Incorrect password given', 'status');
558 break;
559 default:
560 // We don't know what data contains, so don't do anything with it.
561 //_kiwi.front.tabviews.server.addMsg(null, ' ', '== ' + data, 'status');
562 }
563 }
564}
565
566)();