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