3 _kiwi
.model
.Network
= Backbone
.Model
.extend({
7 * The name of the network
13 * The address (URL) of the network
19 * The current nickname
25 * The channel prefix for this network
31 * The user prefixes for channel owner/admin/op/voice etc. on this network
34 user_prefixes
: ['~', '&', '@', '+']
38 initialize: function () {
39 this.gateway
= _kiwi
.global
.components
.Network(this.get('connection_id'));
40 this.bindGatewayEvents();
42 this.panels
= new _kiwi
.model
.PanelList(this);
46 bindGatewayEvents: function () {
47 //this.gateway.on('all', function() {console.log('ALL', arguments);});
49 this.gateway
.on('connect', function(event
) {
50 this.set('nick', event
.nick
);
53 this.gateway
.on('nick', function(event
) {
54 if (event
.nick
=== event
.get('nick')) {
55 this.set('nick', event
.newnick
);
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);
78 this.gateway
.on('list_channel', onListChannel
, this);
79 this.gateway
.on('list_end', onListEnd
, this);
85 function onOptions(event
) {
88 $.each(event
.options
, function (name
, value
) {
91 that
.set('channel_prefix', value
.join(''));
94 that
.set('name', value
);
97 that
.set('user_prefixes', value
);
102 this.set('cap', event
.cap
);
107 function onMotd(event
) {
108 this.panels
.server
.addMsg(this.get('name'), event
.msg
, 'motd');
113 function onJoin(event
) {
114 var c
, members
, user
;
115 c
= this.panels
.getByName(event
.channel
);
117 c
= new _kiwi
.model
.Channel({name
: event
.channel
});
121 members
= c
.get('members');
122 if (!members
) return;
124 user
= new _kiwi
.model
.Member({nick
: event
.nick
, ident
: event
.ident
, hostname
: event
.hostname
});
130 function onPart(event
) {
131 var channel
, members
, user
,
134 part_options
.type
= 'part';
135 part_options
.message
= event
.message
|| '';
137 channel
= this.panels
.getByName(event
.channel
);
138 if (!channel
) return;
140 // If this is us, close the panel
141 if (event
.nick
=== this.get('nick')) {
146 members
= channel
.get('members');
147 if (!members
) return;
149 user
= members
.getByNick(event
.nick
);
152 members
.remove(user
, part_options
);
157 function onQuit(event
) {
161 quit_options
.type
= 'quit';
162 quit_options
.message
= event
.message
|| '';
164 $.each(this.panels
.models
, function (index
, panel
) {
165 if (!panel
.isChannel()) return;
167 member
= panel
.get('members').getByNick(event
.nick
);
169 panel
.get('members').remove(member
, quit_options
);
176 function onKick(event
) {
177 var channel
, members
, user
,
180 part_options
.type
= 'kick';
181 part_options
.by
= event
.nick
;
182 part_options
.message
= event
.message
|| '';
184 channel
= this.panels
.getByName(event
.channel
);
185 if (!channel
) return;
187 members
= channel
.get('members');
188 if (!members
) return;
190 user
= members
.getByNick(event
.kicked
);
193 members
.remove(user
, part_options
);
195 if (event
.kicked
=== this.get('nick')) {
202 function onMsg(event
) {
204 is_pm
= (event
.channel
== this.get('nick'));
206 // An ignored user? don't do anything with it
207 if (_kiwi
.gateway
.isNickIgnored(event
.nick
)) {
212 // If a panel isn't found for this PM, create one
213 panel
= this.panels
.getByName(event
.nick
);
215 panel
= new _kiwi
.model
.Query({name
: event
.nick
});
216 this.panels
.add(panel
);
220 // If a panel isn't found for this channel, reroute to the
222 panel
= this.panels
.getByName(event
.channel
);
224 panel
= this.panels
.server
;
228 panel
.addMsg(event
.nick
, event
.msg
);
233 function onCtcpRequest(event
) {
234 // An ignored user? don't do anything with it
235 if (_kiwi
.gateway
.isNickIgnored(event
.nick
)) {
239 // Reply to a TIME ctcp
240 if (event
.msg
.toUpperCase() === 'TIME') {
241 this.gateway
.ctcp(false, event
.type
, event
.nick
, (new Date()).toString());
247 function onCtcpResponse(event
) {
248 // An ignored user? don't do anything with it
249 if (_kiwi
.gateway
.isNickIgnored(event
.nick
)) {
253 this.panels
.server
.addMsg('[' + event
.nick
+ ']', 'CTCP ' + event
.msg
);
258 function onNotice(event
) {
261 // An ignored user? don't do anything with it
262 if (event
.nick
&& _kiwi
.gateway
.isNickIgnored(event
.nick
)) {
266 // Find a panel for the destination(channel) or who its from
267 panel
= this.panels
.getByName(event
.target
) || this.panels
.getByName(event
.nick
);
269 panel
= this.panels
.server
;
272 panel
.addMsg('[' + (event
.nick
||'') + ']', event
.msg
);
277 function onAction(event
) {
279 is_pm
= (event
.channel
== this.get('nick'));
281 // An ignored user? don't do anything with it
282 if (_kiwi
.gateway
.isNickIgnored(event
.nick
)) {
287 // If a panel isn't found for this PM, create one
288 panel
= this.panels
.getByName(event
.nick
);
290 panel
= new _kiwi
.model
.Channel({name
: event
.nick
});
291 this.panels
.add(panel
);
295 // If a panel isn't found for this channel, reroute to the
297 panel
= this.panels
.getByName(event
.channel
);
299 panel
= this.panels
.server
;
303 panel
.addMsg('', '* ' + event
.nick
+ ' ' + event
.msg
, 'action');
308 function onTopic(event
) {
310 c
= this.panels
.getByName(event
.channel
);
313 // Set the channels topic
314 c
.set('topic', event
.topic
);
316 // If this is the active channel, update the topic bar too
317 if (c
.get('name') === this.panels
.active
.get('name')) {
318 _kiwi
.app
.topicbar
.setCurrentTopic(event
.topic
);
324 function onTopicSetBy(event
) {
326 c
= this.panels
.getByName(event
.channel
);
329 when
= formatDate(new Date(event
.when
* 1000));
330 c
.addMsg('', 'Topic set by ' + event
.nick
+ ' at ' + when
, 'topic');
335 function onUserlist(event
) {
337 channel
= this.panels
.getByName(event
.channel
);
339 // If we didn't find a channel for this, may aswell leave
340 if (!channel
) return;
342 channel
.temp_userlist
= channel
.temp_userlist
|| [];
343 _
.each(event
.users
, function (item
) {
344 var user
= new _kiwi
.model
.Member({nick
: item
.nick
, modes
: item
.modes
});
345 channel
.temp_userlist
.push(user
);
351 function onUserlistEnd(event
) {
353 channel
= this.panels
.getByName(event
.channel
);
355 // If we didn't find a channel for this, may aswell leave
356 if (!channel
) return;
358 // Update the members list with the new list
359 channel
.get('members').reset(channel
.temp_userlist
|| []);
361 // Clear the temporary userlist
362 delete channel
.temp_userlist
;
367 function onMode(event
) {
368 var channel
, i
, prefixes
, members
, member
, find_prefix
;
370 // Build a nicely formatted string to be displayed to a regular human
371 function friendlyModeString (event_modes
, alt_target
) {
372 var modes
= {}, return_string
;
374 // If no default given, use the main event info
376 event_modes
= event
.modes
;
377 alt_target
= event
.target
;
380 // Reformat the mode object to make it easier to work with
381 _
.each(event_modes
, function (mode
){
382 var param
= mode
.param
|| alt_target
|| '';
384 // Make sure we have some modes for this param
386 modes
[param
] = {'+':'', '-':''};
389 modes
[param
][mode
.mode
[0]] += mode
.mode
.substr(1);
392 // Put the string together from each mode
394 _
.each(modes
, function (modeset
, param
) {
396 if (modeset
['+']) str
+= '+' + modeset
['+'];
397 if (modeset
['-']) str
+= '-' + modeset
['-'];
398 return_string
.push(str
+ ' ' + param
);
400 return_string
= return_string
.join(', ');
402 return return_string
;
406 channel
= this.panels
.getByName(event
.target
);
408 prefixes
= this.get('user_prefixes');
409 find_prefix = function (p
) {
410 return event
.modes
[i
].mode
[1] === p
.mode
;
412 for (i
= 0; i
< event
.modes
.length
; i
++) {
413 if (_
.any(prefixes
, find_prefix
)) {
415 members
= channel
.get('members');
417 member
= members
.getByNick(event
.modes
[i
].param
);
419 console
.log('MODE command recieved for unknown member %s on channel %s', event
.modes
[i
].param
, event
.target
);
422 if (event
.modes
[i
].mode
[0] === '+') {
423 member
.addMode(event
.modes
[i
].mode
[1]);
424 } else if (event
.modes
[i
].mode
[0] === '-') {
425 member
.removeMode(event
.modes
[i
].mode
[1]);
428 //channel.addMsg('', '== ' + event.nick + ' set mode ' + event.modes[i].mode + ' ' + event.modes[i].param, 'action mode');
431 // Channel mode being set
432 // TODO: Store this somewhere?
433 //channel.addMsg('', 'CHANNEL === ' + event.nick + ' set mode ' + event.modes[i].mode + ' on ' + event.target, 'action mode');
437 channel
.addMsg('', '== ' + event
.nick
+ ' sets mode ' + friendlyModeString(), 'action mode');
439 // This is probably a mode being set on us.
440 if (event
.target
.toLowerCase() === this.get("nick").toLowerCase()) {
441 this.panels
.server
.addMsg('', '== ' + event
.nick
+ ' set mode ' + friendlyModeString(), 'action mode');
443 console
.log('MODE command recieved for unknown target %s: ', event
.target
, event
);
450 function onWhois(event
) {
451 var logon_date
, idle_time
= '', panel
;
456 if (typeof event
.idle
!== 'undefined') {
457 idle_time
= secondsToTime(parseInt(event
.idle
, 10));
458 idle_time
= idle_time
.h
.toString().lpad(2, "0") + ':' + idle_time
.m
.toString().lpad(2, "0") + ':' + idle_time
.s
.toString().lpad(2, "0");
461 panel
= _kiwi
.app
.panels
.active
;
463 panel
.addMsg(event
.nick
, event
.nick
+ ' [' + event
.nick
+ '!' + event
.ident
+ '@' + event
.host
+ '] * ' + event
.msg
, 'whois');
464 } else if (event
.chans
) {
465 panel
.addMsg(event
.nick
, 'Channels: ' + event
.chans
, 'whois');
466 } else if (event
.irc_server
) {
467 panel
.addMsg(event
.nick
, 'Connected to server: ' + event
.irc_server
, 'whois');
468 } else if (event
.msg
) {
469 panel
.addMsg(event
.nick
, event
.msg
, 'whois');
470 } else if (event
.logon
) {
471 logon_date
= new Date();
472 logon_date
.setTime(event
.logon
* 1000);
473 logon_date
= formatDate(logon_date
);
475 panel
.addMsg(event
.nick
, 'idle for ' + idle_time
+ ', signed on ' + logon_date
, 'whois');
477 panel
.addMsg(event
.nick
, 'idle for ' + idle_time
, 'whois');
483 function onAway(event
) {
484 $.each(this.panels
.models
, function (index
, panel
) {
485 if (!panel
.isChannel()) return;
487 member
= panel
.get('members').getByNick(event
.nick
);
489 member
.set('away', !(!event
.trailing
));
496 function onListStart(event
) {
497 if (_kiwi
.app
.channel_list
) {
498 _kiwi
.app
.channel_list
.close();
499 delete _kiwi
.app
.channel_list
;
502 var panel
= new _kiwi
.model
.Applet(),
503 applet
= new _kiwi
.applets
.Chanlist();
507 _kiwi
.app
.panels
.add(panel
);
510 _kiwi
.app
.channel_list
= applet
;
515 function onListChannel(event
) {
516 // TODO: Put this listener within the applet itself
517 _kiwi
.app
.channel_list
.addChannel(event
.chans
);
522 function onListEnd(event
) {
523 // TODO: Put this listener within the applet itself
524 delete _kiwi
.app
.channel_list
;
529 function onIrcError(event
) {
532 if (event
.channel
!== undefined && !(panel
= _kiwi
.app
.panels
.getByName(event
.channel
))) {
533 panel
= this.panels
.server
;
536 switch (event
.error
) {
537 case 'banned_from_channel':
538 panel
.addMsg(' ', '== You are banned from ' + event
.channel
+ '. ' + event
.reason
, 'status');
539 _kiwi
.app
.message
.text('You are banned from ' + event
.channel
+ '. ' + event
.reason
);
541 case 'bad_channel_key':
542 panel
.addMsg(' ', '== Bad channel key for ' + event
.channel
, 'status');
543 _kiwi
.app
.message
.text('Bad channel key or password for ' + event
.channel
);
545 case 'invite_only_channel':
546 panel
.addMsg(' ', '== ' + event
.channel
+ ' is invite only.', 'status');
547 _kiwi
.app
.message
.text(event
.channel
+ ' is invite only');
549 case 'channel_is_full':
550 panel
.addMsg(' ', '== ' + event
.channel
+ ' is full.', 'status');
551 _kiwi
.app
.message
.text(event
.channel
+ ' is full');
553 case 'chanop_privs_needed':
554 panel
.addMsg(' ', '== ' + event
.reason
, 'status');
555 _kiwi
.app
.message
.text(event
.reason
+ ' (' + event
.channel
+ ')');
558 tmp
= this.panels
.getByName(event
.nick
);
560 tmp
.addMsg(' ', '== ' + event
.nick
+ ': ' + event
.reason
, 'status');
562 this.panels
.server
.addMsg(' ', '== ' + event
.nick
+ ': ' + event
.reason
, 'status');
565 case 'nickname_in_use':
566 this.panels
.server
.addMsg(' ', '== The nickname ' + event
.nick
+ ' is already in use. Please select a new nickname', 'status');
567 if (this.panels
.server
!== thia
.panels
.active
) {
568 _kiwi
.app
.message
.text('The nickname "' + event
.nick
+ '" is already in use. Please select a new nickname');
571 // Only show the nickchange component if the controlbox is open
572 if (that
.controlbox
.$el
.css('display') !== 'none') {
573 (new _kiwi
.view
.NickChangeBox()).render();
578 case 'password_mismatch':
579 this.panels
.server
.addMsg(' ', '== Incorrect password given', 'status');
582 // We don't know what data contains, so don't do anything with it.
583 //_kiwi.front.tabviews.server.addMsg(null, ' ', '== ' + data, 'status');