Commit | Line | Data |
---|---|---|
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 | ||
d6eec6ed D |
18 | /** |
19 | * The port for the network | |
20 | * @type Int | |
21 | */ | |
22 | port: 6667, | |
23 | ||
24 | /** | |
25 | * If this network uses SSL | |
26 | * @type Bool | |
27 | */ | |
28 | ssl: false, | |
29 | ||
30 | /** | |
31 | * The password to connect to this network | |
32 | * @type String | |
33 | */ | |
34 | password: '', | |
35 | ||
ce13508b D |
36 | /** |
37 | * The current nickname | |
38 | * @type String | |
39 | */ | |
40 | nick: '', | |
41 | ||
42 | /** | |
43 | * The channel prefix for this network | |
44 | * @type String | |
45 | */ | |
46 | channel_prefix: '#', | |
47 | ||
48 | /** | |
49 | * The user prefixes for channel owner/admin/op/voice etc. on this network | |
50 | * @type Array | |
51 | */ | |
d772b95d D |
52 | user_prefixes: [ |
53 | {symbol: '~', mode: 'q'}, | |
54 | {symbol: '&', mode: 'a'}, | |
55 | {symbol: '@', mode: 'o'}, | |
56 | {symbol: '%', mode: 'h'}, | |
57 | {symbol: '+', mode: 'v'} | |
58 | ], | |
425efe7a JA |
59 | |
60 | /** | |
61 | * List of nicks we are ignoring | |
62 | * @type Array | |
63 | */ | |
64 | ignore_list: [] | |
ce13508b D |
65 | }, |
66 | ||
67 | ||
68 | initialize: function () { | |
d6eec6ed D |
69 | // If we already have a connection, bind our events |
70 | if (typeof this.get('connection_id') !== 'undefined') { | |
71 | this.gateway = _kiwi.global.components.Network(this.get('connection_id')); | |
72 | this.bindGatewayEvents(); | |
73 | } | |
ce13508b | 74 | |
c62a9570 | 75 | // Create our panel list (tabs) |
0e546dd4 | 76 | this.panels = new _kiwi.model.PanelList([], this); |
c62a9570 | 77 | //this.panels.network = this; |
0e546dd4 D |
78 | |
79 | // Automatically create a server tab | |
17fd8703 | 80 | var server_panel = new _kiwi.model.Server({name: 'Server', network: this}); |
0e546dd4 | 81 | this.panels.add(server_panel); |
c966123a | 82 | this.panels.server = this.panels.active = server_panel; |
ce13508b D |
83 | }, |
84 | ||
85 | ||
d6eec6ed D |
86 | reconnect: function(callback_fn) { |
87 | var that = this, | |
88 | server_info = { | |
89 | nick: this.get('nick'), | |
fb161845 | 90 | host: this.get('address'), |
d6eec6ed D |
91 | port: this.get('port'), |
92 | ssl: this.get('ssl'), | |
93 | password: this.get('password') | |
94 | }; | |
95 | ||
96 | _kiwi.gateway.makeIrcConnection(server_info, function(err, connection_id) { | |
97 | if (!err) { | |
98 | that.gateway.dispose(); | |
99 | ||
100 | that.set('connection_id', connection_id); | |
101 | that.gateway = _kiwi.global.components.Network(that.get('connection_id')); | |
102 | that.bindGatewayEvents(); | |
103 | ||
ab1e3748 D |
104 | // Reset each of the panels connection ID |
105 | that.panels.forEach(function(panel) { | |
106 | panel.set('connection_id', connection_id); | |
107 | }); | |
108 | ||
d6eec6ed D |
109 | callback_fn && callback_fn(err); |
110 | ||
111 | } else { | |
112 | console.log("_kiwi.gateway.socket.on('error')", {reason: err}); | |
113 | callback_fn && callback_fn(err); | |
114 | } | |
115 | }); | |
116 | }, | |
117 | ||
118 | ||
ce13508b | 119 | bindGatewayEvents: function () { |
0e546dd4 | 120 | //this.gateway.on('all', function() {console.log('ALL', this.get('connection_id'), arguments);}); |
ce13508b | 121 | |
4047ee2b | 122 | this.gateway.on('connect', onConnect, this); |
a36b7eb6 | 123 | this.gateway.on('disconnect', onDisconnect, this); |
ce13508b D |
124 | |
125 | this.gateway.on('nick', function(event) { | |
2ffd1291 | 126 | if (event.nick === this.get('nick')) { |
ce13508b D |
127 | this.set('nick', event.newnick); |
128 | } | |
129 | }, this); | |
130 | ||
131 | this.gateway.on('options', onOptions, this); | |
132 | this.gateway.on('motd', onMotd, this); | |
c0bbfb79 D |
133 | this.gateway.on('channel:join', onJoin, this); |
134 | this.gateway.on('channel:part', onPart, this); | |
8c90d1dc | 135 | this.gateway.on('channel:kick', onKick, this); |
641f5b6b | 136 | this.gateway.on('quit', onQuit, this); |
6b2eb06b | 137 | this.gateway.on('message', onMessage, this); |
e2c54b3e | 138 | this.gateway.on('nick', onNick, this); |
ce13508b D |
139 | this.gateway.on('ctcp_request', onCtcpRequest, this); |
140 | this.gateway.on('ctcp_response', onCtcpResponse, this); | |
ce13508b D |
141 | this.gateway.on('topic', onTopic, this); |
142 | this.gateway.on('topicsetby', onTopicSetBy, this); | |
143 | this.gateway.on('userlist', onUserlist, this); | |
144 | this.gateway.on('userlist_end', onUserlistEnd, this); | |
72db27e4 | 145 | this.gateway.on('banlist', onBanlist, this); |
ce13508b D |
146 | this.gateway.on('mode', onMode, this); |
147 | this.gateway.on('whois', onWhois, this); | |
5989f3f4 | 148 | this.gateway.on('whowas', onWhowas, this); |
ce13508b D |
149 | this.gateway.on('away', onAway, this); |
150 | this.gateway.on('list_start', onListStart, this); | |
f8240e98 | 151 | this.gateway.on('irc_error', onIrcError, this); |
3d753975 | 152 | this.gateway.on('unknown_command', onUnknownCommand, this); |
72db27e4 | 153 | this.gateway.on('channel_info', onChannelInfo, this); |
44f18d27 | 154 | this.gateway.on('wallops', onWallops, this); |
18818abd D |
155 | }, |
156 | ||
157 | ||
158 | /** | |
159 | * Create panels and join the channel | |
160 | * This will not wait for the join event to create a panel. This | |
161 | * increases responsiveness in case of network lag | |
162 | */ | |
163 | createAndJoinChannels: function (channels) { | |
164 | var that = this, | |
165 | panels = []; | |
166 | ||
d6eec6ed | 167 | // Multiple channels may come as comma-delimited |
18818abd D |
168 | if (typeof channels === 'string') { |
169 | channels = channels.split(','); | |
170 | } | |
171 | ||
172 | $.each(channels, function (index, channel_name_key) { | |
173 | // We may have a channel key so split it off | |
174 | var spli = channel_name_key.trim().split(' '), | |
175 | channel_name = spli[0], | |
176 | channel_key = spli[1] || ''; | |
177 | ||
178 | // Trim any whitespace off the name | |
179 | channel_name = channel_name.trim(); | |
180 | ||
b8bba51e | 181 | // Add channel_prefix in front of the first channel if missing |
0db58ad7 D |
182 | if (that.get('channel_prefix').indexOf(channel_name[0]) === -1) { |
183 | // Could be many prefixes but '#' is highly likely the required one | |
184 | channel_name = '#' + channel_name; | |
18818abd D |
185 | } |
186 | ||
187 | // Check if we have the panel already. If not, create it | |
188 | channel = that.panels.getByName(channel_name); | |
189 | if (!channel) { | |
72db27e4 | 190 | channel = new _kiwi.model.Channel({name: channel_name, network: that}); |
18818abd D |
191 | that.panels.add(channel); |
192 | } | |
193 | ||
194 | panels.push(channel); | |
195 | ||
196 | that.gateway.join(channel_name, channel_key); | |
197 | }); | |
198 | ||
b62f086f | 199 | |
18818abd | 200 | return panels; |
24d27c8c D |
201 | }, |
202 | ||
203 | ||
204 | /** | |
205 | * Join all the open channels we have open | |
206 | * Reconnecting to a network would typically call this. | |
207 | */ | |
208 | rejoinAllChannels: function() { | |
209 | var that = this; | |
210 | ||
211 | this.panels.forEach(function(panel) { | |
212 | if (!panel.isChannel()) | |
213 | return; | |
214 | ||
215 | that.gateway.join(panel.get('name')); | |
216 | }); | |
425efe7a JA |
217 | }, |
218 | ||
219 | isChannelName: function (channel_name) { | |
220 | var channel_prefix = this.get('channel_prefix'); | |
221 | ||
222 | if (!channel_name || !channel_name.length) return false; | |
223 | return (channel_prefix.indexOf(channel_name[0]) > -1); | |
224 | }, | |
225 | ||
226 | // Check a nick alongside our ignore list | |
227 | isNickIgnored: function (nick) { | |
228 | var idx, list = this.get('ignore_list'); | |
229 | var pattern, regex; | |
230 | ||
231 | for (idx = 0; idx < list.length; idx++) { | |
232 | pattern = list[idx].replace(/([.+^$[\]\\(){}|-])/g, "\\$1") | |
233 | .replace('*', '.*') | |
234 | .replace('?', '.'); | |
235 | ||
236 | regex = new RegExp(pattern, 'i'); | |
237 | if (regex.test(nick)) return true; | |
238 | } | |
239 | ||
240 | return false; | |
dabf8ed9 CC |
241 | }, |
242 | ||
243 | // Create a new query panel | |
244 | createQuery: function (nick) { | |
245 | var that = this, | |
58e527c6 | 246 | query; |
dabf8ed9 CC |
247 | |
248 | // Check if we have the panel already. If not, create it | |
249 | query = that.panels.getByName(nick); | |
250 | if (!query) { | |
251 | query = new _kiwi.model.Query({name: nick}); | |
252 | that.panels.add(query); | |
253 | } | |
ab1e3748 | 254 | |
dabf8ed9 | 255 | // In all cases, show the demanded query |
58e527c6 | 256 | query.view.show(); |
4d8e0138 D |
257 | |
258 | return query; | |
ce13508b D |
259 | } |
260 | }); | |
261 | ||
262 | ||
d6eec6ed | 263 | |
a36b7eb6 | 264 | function onDisconnect(event) { |
fa27a34e D |
265 | this.set('connected', false); |
266 | ||
a36b7eb6 | 267 | $.each(this.panels.models, function (index, panel) { |
91236ed7 D |
268 | if (!panel.isApplet()) { |
269 | panel.addMsg('', styleText('network_disconnected', {text: translateText('client_models_network_disconnected', [])}), 'action quit'); | |
270 | } | |
a36b7eb6 D |
271 | }); |
272 | } | |
273 | ||
274 | ||
ce13508b | 275 | |
4047ee2b | 276 | function onConnect(event) { |
18818abd D |
277 | var panels, channel_names; |
278 | ||
279 | // Update our nick with what the network gave us | |
4047ee2b D |
280 | this.set('nick', event.nick); |
281 | ||
fa27a34e D |
282 | this.set('connected', true); |
283 | ||
24d27c8c D |
284 | // If this is a re-connection then we may have some channels to re-join |
285 | this.rejoinAllChannels(); | |
286 | ||
18818abd | 287 | // Auto joining channels |
4047ee2b | 288 | if (this.auto_join && this.auto_join.channel) { |
852c230c | 289 | panels = this.createAndJoinChannels(this.auto_join.channel + ' ' + (this.auto_join.key || '')); |
18818abd D |
290 | |
291 | // Show the last channel if we have one | |
292 | if (panels) | |
293 | panels[panels.length - 1].view.show(); | |
cf3d9759 D |
294 | |
295 | delete this.auto_join; | |
4047ee2b D |
296 | } |
297 | } | |
298 | ||
299 | ||
300 | ||
ce13508b D |
301 | function onOptions(event) { |
302 | var that = this; | |
303 | ||
304 | $.each(event.options, function (name, value) { | |
305 | switch (name) { | |
306 | case 'CHANTYPES': | |
307 | that.set('channel_prefix', value.join('')); | |
308 | break; | |
309 | case 'NETWORK': | |
310 | that.set('name', value); | |
311 | break; | |
312 | case 'PREFIX': | |
313 | that.set('user_prefixes', value); | |
314 | break; | |
315 | } | |
316 | }); | |
317 | ||
318 | this.set('cap', event.cap); | |
319 | } | |
320 | ||
321 | ||
322 | ||
323 | function onMotd(event) { | |
9ec48c54 | 324 | this.panels.server.addMsg(this.get('name'), styleText('motd', {text: event.msg}), 'motd'); |
ce13508b D |
325 | } |
326 | ||
327 | ||
328 | ||
329 | function onJoin(event) { | |
330 | var c, members, user; | |
331 | c = this.panels.getByName(event.channel); | |
332 | if (!c) { | |
72db27e4 | 333 | c = new _kiwi.model.Channel({name: event.channel, network: this}); |
ce13508b D |
334 | this.panels.add(c); |
335 | } | |
336 | ||
337 | members = c.get('members'); | |
338 | if (!members) return; | |
339 | ||
5a0eb997 D |
340 | // Do we already have this member? |
341 | if (members.getByNick(event.nick)) { | |
342 | return; | |
343 | } | |
344 | ||
11412289 D |
345 | user = new _kiwi.model.Member({ |
346 | nick: event.nick, | |
347 | ident: event.ident, | |
348 | hostname: event.hostname, | |
349 | user_prefixes: this.get('user_prefixes') | |
350 | }); | |
a885d1c9 | 351 | |
181f3f9c | 352 | _kiwi.global.events.emit('channel:join', {channel: event.channel, user: user, network: this.gateway}) |
a885d1c9 D |
353 | .then(function() { |
354 | members.add(user, {kiwi: event}); | |
355 | }); | |
ce13508b D |
356 | } |
357 | ||
358 | ||
359 | ||
360 | function onPart(event) { | |
361 | var channel, members, user, | |
362 | part_options = {}; | |
363 | ||
364 | part_options.type = 'part'; | |
365 | part_options.message = event.message || ''; | |
697a76c5 | 366 | part_options.time = event.time; |
ce13508b D |
367 | |
368 | channel = this.panels.getByName(event.channel); | |
369 | if (!channel) return; | |
370 | ||
371 | // If this is us, close the panel | |
372 | if (event.nick === this.get('nick')) { | |
373 | channel.close(); | |
374 | return; | |
375 | } | |
376 | ||
377 | members = channel.get('members'); | |
378 | if (!members) return; | |
379 | ||
380 | user = members.getByNick(event.nick); | |
381 | if (!user) return; | |
382 | ||
181f3f9c | 383 | _kiwi.global.events.emit('channel:leave', {channel: event.channel, user: user, type: 'part', message: part_options.message, network: this.gateway}) |
a885d1c9 D |
384 | .then(function() { |
385 | members.remove(user, {kiwi: part_options}); | |
386 | }); | |
ce13508b D |
387 | } |
388 | ||
389 | ||
390 | ||
391 | function onQuit(event) { | |
392 | var member, members, | |
393 | quit_options = {}; | |
394 | ||
395 | quit_options.type = 'quit'; | |
396 | quit_options.message = event.message || ''; | |
697a76c5 | 397 | quit_options.time = event.time; |
ce13508b D |
398 | |
399 | $.each(this.panels.models, function (index, panel) { | |
0d73046a D |
400 | // Let any query panels know they quit |
401 | if (panel.isQuery() && panel.get('name').toLowerCase() === event.nick.toLowerCase()) { | |
402 | panel.addMsg(' ', styleText('channel_quit', { | |
403 | nick: event.nick, | |
404 | text: translateText('client_models_channel_quit', [quit_options.message]) | |
405 | }), 'action quit', {time: quit_options.time}); | |
406 | } | |
ce13508b | 407 | |
0d73046a D |
408 | // Remove the nick from any channels |
409 | if (panel.isChannel()) { | |
410 | member = panel.get('members').getByNick(event.nick); | |
411 | if (member) { | |
d0febed3 | 412 | _kiwi.global.events.emit('channel:leave', {channel: panel.get('name'), user: member, type: 'quit', message: quit_options.message, network: this.gateway}) |
a885d1c9 D |
413 | .then(function() { |
414 | panel.get('members').remove(member, {kiwi: quit_options}); | |
415 | }); | |
0d73046a | 416 | } |
ce13508b D |
417 | } |
418 | }); | |
419 | } | |
420 | ||
421 | ||
422 | ||
423 | function onKick(event) { | |
424 | var channel, members, user, | |
425 | part_options = {}; | |
426 | ||
427 | part_options.type = 'kick'; | |
428 | part_options.by = event.nick; | |
429 | part_options.message = event.message || ''; | |
697a76c5 JA |
430 | part_options.current_user_kicked = (event.kicked == this.get('nick')); |
431 | part_options.current_user_initiated = (event.nick == this.get('nick')); | |
432 | part_options.time = event.time; | |
ce13508b D |
433 | |
434 | channel = this.panels.getByName(event.channel); | |
435 | if (!channel) return; | |
436 | ||
437 | members = channel.get('members'); | |
438 | if (!members) return; | |
439 | ||
440 | user = members.getByNick(event.kicked); | |
441 | if (!user) return; | |
442 | ||
eed5ac29 | 443 | |
181f3f9c | 444 | _kiwi.global.events.emit('channel:leave', {channel: event.channel, user: user, type: 'kick', message: part_options.message, network: this.gateway}) |
a885d1c9 D |
445 | .then(function() { |
446 | members.remove(user, {kiwi: part_options}); | |
ce13508b | 447 | |
a885d1c9 D |
448 | if (part_options.current_user_kicked) { |
449 | members.reset([]); | |
450 | } | |
451 | }); | |
ce13508b D |
452 | } |
453 | ||
454 | ||
455 | ||
6b2eb06b | 456 | function onMessage(event) { |
181f3f9c | 457 | _kiwi.global.events.emit('message:new', {network: this.gateway, message: event}) |
060391b1 | 458 | .then(_.bind(function() { |
c1c51f22 D |
459 | var panel, |
460 | is_pm = ((event.target || '').toLowerCase() == this.get('nick').toLowerCase()); | |
461 | ||
462 | // An ignored user? don't do anything with it | |
463 | if (this.isNickIgnored(event.nick)) { | |
464 | return; | |
465 | } | |
ce13508b | 466 | |
c1c51f22 D |
467 | if (event.type == 'notice') { |
468 | if (event.from_server) { | |
469 | panel = this.panels.server; | |
6b2eb06b | 470 | |
c1c51f22 D |
471 | } else { |
472 | panel = this.panels.getByName(event.target) || this.panels.getByName(event.nick); | |
6b2eb06b | 473 | |
c1c51f22 D |
474 | // Forward ChanServ messages to its associated channel |
475 | if (event.nick && event.nick.toLowerCase() == 'chanserv' && event.msg.charAt(0) == '[') { | |
476 | channel_name = /\[([^ \]]+)\]/gi.exec(event.msg); | |
477 | if (channel_name && channel_name[1]) { | |
478 | channel_name = channel_name[1]; | |
6b2eb06b | 479 | |
c1c51f22 D |
480 | panel = this.panels.getByName(channel_name); |
481 | } | |
6b2eb06b | 482 | } |
6b2eb06b | 483 | |
c1c51f22 | 484 | } |
6b2eb06b | 485 | |
c1c51f22 D |
486 | if (!panel) { |
487 | panel = this.panels.server; | |
488 | } | |
6b2eb06b | 489 | |
c1c51f22 D |
490 | } else if (is_pm) { |
491 | // If a panel isn't found for this PM, create one | |
492 | panel = this.panels.getByName(event.nick); | |
493 | if (!panel) { | |
494 | panel = new _kiwi.model.Query({name: event.nick, network: this}); | |
495 | this.panels.add(panel); | |
496 | } | |
ce13508b | 497 | |
c1c51f22 D |
498 | } else { |
499 | // If a panel isn't found for this target, reroute to the | |
500 | // server panel | |
501 | panel = this.panels.getByName(event.target); | |
502 | if (!panel) { | |
503 | panel = this.panels.server; | |
504 | } | |
ce13508b | 505 | } |
ce13508b | 506 | |
c1c51f22 D |
507 | switch (event.type){ |
508 | case 'message': | |
509 | panel.addMsg(event.nick, styleText('privmsg', {text: event.msg}), 'privmsg', {time: event.time}); | |
510 | break; | |
6b2eb06b | 511 | |
c1c51f22 D |
512 | case 'action': |
513 | panel.addMsg('', styleText('action', {nick: event.nick, text: event.msg}), 'action', {time: event.time}); | |
514 | break; | |
6b2eb06b | 515 | |
c1c51f22 D |
516 | case 'notice': |
517 | panel.addMsg('[' + (event.nick||'') + ']', styleText('notice', {text: event.msg}), 'notice', {time: event.time}); | |
6b2eb06b | 518 | |
c1c51f22 D |
519 | // Show this notice to the active panel if it didn't have a set target, but only in an active channel or query window |
520 | active_panel = _kiwi.app.panels().active; | |
6b2eb06b | 521 | |
c1c51f22 D |
522 | if (!event.from_server && panel === this.panels.server && active_panel !== this.panels.server) { |
523 | if (active_panel.get('network') === this && (active_panel.isChannel() || active_panel.isQuery())) | |
524 | active_panel.addMsg('[' + (event.nick||'') + ']', styleText('notice', {text: event.msg}), 'notice', {time: event.time}); | |
525 | } | |
526 | break; | |
6b2eb06b | 527 | } |
c1c51f22 | 528 | }, this)); |
ce13508b D |
529 | } |
530 | ||
531 | ||
532 | ||
e2c54b3e D |
533 | function onNick(event) { |
534 | var member; | |
535 | ||
536 | $.each(this.panels.models, function (index, panel) { | |
537 | if (panel.get('name') == event.nick) | |
538 | panel.set('name', event.newnick); | |
539 | ||
540 | if (!panel.isChannel()) return; | |
541 | ||
542 | member = panel.get('members').getByNick(event.nick); | |
543 | if (member) { | |
544 | member.set('nick', event.newnick); | |
9ec48c54 | 545 | panel.addMsg('', styleText('nick_changed', {nick: event.nick, text: translateText('client_models_network_nickname_changed', [event.newnick]), channel: name}), 'action nick', {time: event.time}); |
e2c54b3e D |
546 | } |
547 | }); | |
548 | } | |
549 | ||
550 | ||
551 | ||
ce13508b D |
552 | function onCtcpRequest(event) { |
553 | // An ignored user? don't do anything with it | |
425efe7a | 554 | if (this.isNickIgnored(event.nick)) { |
ce13508b D |
555 | return; |
556 | } | |
557 | ||
558 | // Reply to a TIME ctcp | |
559 | if (event.msg.toUpperCase() === 'TIME') { | |
9de52d29 | 560 | this.gateway.ctcpResponse(event.type, event.nick, (new Date()).toString()); |
766f53d3 RB |
561 | } else if(event.type.toUpperCase() === 'PING') { // CTCP PING reply |
562 | this.gateway.ctcpResponse(event.type, event.nick, event.msg.substr(5)); | |
ce13508b D |
563 | } |
564 | } | |
565 | ||
566 | ||
567 | ||
568 | function onCtcpResponse(event) { | |
569 | // An ignored user? don't do anything with it | |
425efe7a | 570 | if (this.isNickIgnored(event.nick)) { |
ce13508b D |
571 | return; |
572 | } | |
573 | ||
9ec48c54 | 574 | this.panels.server.addMsg('[' + event.nick + ']', styleText('ctcp', {text: event.msg}), 'ctcp', {time: event.time}); |
ce13508b D |
575 | } |
576 | ||
577 | ||
578 | ||
ce13508b D |
579 | function onTopic(event) { |
580 | var c; | |
581 | c = this.panels.getByName(event.channel); | |
582 | if (!c) return; | |
583 | ||
584 | // Set the channels topic | |
585 | c.set('topic', event.topic); | |
586 | ||
587 | // If this is the active channel, update the topic bar too | |
588 | if (c.get('name') === this.panels.active.get('name')) { | |
589 | _kiwi.app.topicbar.setCurrentTopic(event.topic); | |
590 | } | |
591 | } | |
592 | ||
593 | ||
594 | ||
595 | function onTopicSetBy(event) { | |
596 | var c, when; | |
597 | c = this.panels.getByName(event.channel); | |
598 | if (!c) return; | |
599 | ||
3aa7b8cc D |
600 | when = new Date(event.when * 1000); |
601 | c.set('topic_set_by', {nick: event.nick, when: when}); | |
ce13508b D |
602 | } |
603 | ||
604 | ||
605 | ||
72db27e4 D |
606 | function onChannelInfo(event) { |
607 | var channel = this.panels.getByName(event.channel); | |
608 | if (!channel) return; | |
609 | ||
610 | if (event.url) { | |
611 | channel.set('info_url', event.url); | |
612 | } else if (event.modes) { | |
613 | channel.set('info_modes', event.modes); | |
614 | } | |
615 | } | |
616 | ||
617 | ||
618 | ||
ce13508b | 619 | function onUserlist(event) { |
11412289 D |
620 | var that = this, |
621 | channel = this.panels.getByName(event.channel); | |
ce13508b D |
622 | |
623 | // If we didn't find a channel for this, may aswell leave | |
624 | if (!channel) return; | |
625 | ||
626 | channel.temp_userlist = channel.temp_userlist || []; | |
627 | _.each(event.users, function (item) { | |
11412289 D |
628 | var user = new _kiwi.model.Member({ |
629 | nick: item.nick, | |
630 | modes: item.modes, | |
631 | user_prefixes: that.get('user_prefixes') | |
632 | }); | |
ce13508b D |
633 | channel.temp_userlist.push(user); |
634 | }); | |
635 | } | |
636 | ||
637 | ||
638 | ||
639 | function onUserlistEnd(event) { | |
640 | var channel; | |
641 | channel = this.panels.getByName(event.channel); | |
642 | ||
643 | // If we didn't find a channel for this, may aswell leave | |
644 | if (!channel) return; | |
645 | ||
646 | // Update the members list with the new list | |
647 | channel.get('members').reset(channel.temp_userlist || []); | |
648 | ||
649 | // Clear the temporary userlist | |
650 | delete channel.temp_userlist; | |
651 | } | |
652 | ||
653 | ||
654 | ||
72db27e4 | 655 | function onBanlist(event) { |
72db27e4 D |
656 | var channel = this.panels.getByName(event.channel); |
657 | if (!channel) | |
658 | return; | |
659 | ||
660 | channel.set('banlist', event.bans || []); | |
661 | } | |
662 | ||
663 | ||
664 | ||
ce13508b | 665 | function onMode(event) { |
19c15434 D |
666 | var channel, i, prefixes, members, member, find_prefix, |
667 | request_updated_banlist = false; | |
ce13508b D |
668 | |
669 | // Build a nicely formatted string to be displayed to a regular human | |
670 | function friendlyModeString (event_modes, alt_target) { | |
671 | var modes = {}, return_string; | |
672 | ||
673 | // If no default given, use the main event info | |
674 | if (!event_modes) { | |
675 | event_modes = event.modes; | |
676 | alt_target = event.target; | |
677 | } | |
678 | ||
679 | // Reformat the mode object to make it easier to work with | |
680 | _.each(event_modes, function (mode){ | |
681 | var param = mode.param || alt_target || ''; | |
682 | ||
683 | // Make sure we have some modes for this param | |
684 | if (!modes[param]) { | |
685 | modes[param] = {'+':'', '-':''}; | |
686 | } | |
687 | ||
688 | modes[param][mode.mode[0]] += mode.mode.substr(1); | |
689 | }); | |
690 | ||
691 | // Put the string together from each mode | |
692 | return_string = []; | |
693 | _.each(modes, function (modeset, param) { | |
694 | var str = ''; | |
695 | if (modeset['+']) str += '+' + modeset['+']; | |
696 | if (modeset['-']) str += '-' + modeset['-']; | |
697 | return_string.push(str + ' ' + param); | |
698 | }); | |
699 | return_string = return_string.join(', '); | |
700 | ||
701 | return return_string; | |
702 | } | |
703 | ||
704 | ||
705 | channel = this.panels.getByName(event.target); | |
706 | if (channel) { | |
707 | prefixes = this.get('user_prefixes'); | |
708 | find_prefix = function (p) { | |
709 | return event.modes[i].mode[1] === p.mode; | |
710 | }; | |
711 | for (i = 0; i < event.modes.length; i++) { | |
712 | if (_.any(prefixes, find_prefix)) { | |
713 | if (!members) { | |
714 | members = channel.get('members'); | |
715 | } | |
716 | member = members.getByNick(event.modes[i].param); | |
717 | if (!member) { | |
718 | console.log('MODE command recieved for unknown member %s on channel %s', event.modes[i].param, event.target); | |
719 | return; | |
720 | } else { | |
721 | if (event.modes[i].mode[0] === '+') { | |
722 | member.addMode(event.modes[i].mode[1]); | |
723 | } else if (event.modes[i].mode[0] === '-') { | |
724 | member.removeMode(event.modes[i].mode[1]); | |
725 | } | |
726 | members.sort(); | |
ce13508b D |
727 | } |
728 | } else { | |
729 | // Channel mode being set | |
730 | // TODO: Store this somewhere? | |
731 | //channel.addMsg('', 'CHANNEL === ' + event.nick + ' set mode ' + event.modes[i].mode + ' on ' + event.target, 'action mode'); | |
732 | } | |
19c15434 D |
733 | |
734 | // TODO: Be smart, remove this specific ban from the banlist rather than request a whole banlist | |
735 | if (event.modes[i].mode[1] == 'b') | |
736 | request_updated_banlist = true; | |
ce13508b D |
737 | } |
738 | ||
9ec48c54 | 739 | channel.addMsg('', styleText('mode', {nick: event.nick, text: translateText('client_models_network_mode', [friendlyModeString()]), channel: event.target}), 'action mode', {time: event.time}); |
19c15434 D |
740 | |
741 | // TODO: Be smart, remove the specific ban from the banlist rather than request a whole banlist | |
742 | if (request_updated_banlist) | |
743 | this.gateway.raw('MODE ' + channel.get('name') + ' +b'); | |
744 | ||
ce13508b D |
745 | } else { |
746 | // This is probably a mode being set on us. | |
747 | if (event.target.toLowerCase() === this.get("nick").toLowerCase()) { | |
9ec48c54 | 748 | this.panels.server.addMsg('', styleText('selfmode', {nick: event.nick, text: translateText('client_models_network_mode', [friendlyModeString()]), channel: event.target}), 'action mode'); |
ce13508b D |
749 | } else { |
750 | console.log('MODE command recieved for unknown target %s: ', event.target, event); | |
751 | } | |
752 | } | |
753 | } | |
754 | ||
755 | ||
756 | ||
757 | function onWhois(event) { | |
758 | var logon_date, idle_time = '', panel; | |
759 | ||
760 | if (event.end) | |
761 | return; | |
762 | ||
763 | if (typeof event.idle !== 'undefined') { | |
764 | idle_time = secondsToTime(parseInt(event.idle, 10)); | |
765 | idle_time = idle_time.h.toString().lpad(2, "0") + ':' + idle_time.m.toString().lpad(2, "0") + ':' + idle_time.s.toString().lpad(2, "0"); | |
766 | } | |
767 | ||
e7d65587 | 768 | panel = _kiwi.app.panels().active; |
ce13508b | 769 | if (event.ident) { |
2bcae26b | 770 | panel.addMsg(event.nick, styleText('whois_ident', {nick: event.nick, ident: event.ident, host: event.hostname, text: event.msg}), 'whois'); |
b8fdd572 | 771 | |
ce13508b | 772 | } else if (event.chans) { |
9ec48c54 | 773 | panel.addMsg(event.nick, styleText('whois_channels', {nick: event.nick, text: translateText('client_models_network_channels', [event.chans])}), 'whois'); |
ce13508b | 774 | } else if (event.irc_server) { |
9ec48c54 | 775 | panel.addMsg(event.nick, styleText('whois_server', {nick: event.nick, text: translateText('client_models_network_server', [event.irc_server, event.server_info])}), 'whois'); |
ce13508b | 776 | } else if (event.msg) { |
9ec48c54 | 777 | panel.addMsg(event.nick, styleText('whois', {text: event.msg}), 'whois'); |
ce13508b D |
778 | } else if (event.logon) { |
779 | logon_date = new Date(); | |
780 | logon_date.setTime(event.logon * 1000); | |
5fb6968e | 781 | logon_date = _kiwi.utils.formatDate(logon_date); |
ce13508b | 782 | |
9ec48c54 | 783 | panel.addMsg(event.nick, styleText('whois_idle_and_signon', {nick: event.nick, text: translateText('client_models_network_idle_and_signon', [idle_time, logon_date])}), 'whois'); |
f701d5ba | 784 | } else if (event.away_reason) { |
9ec48c54 | 785 | panel.addMsg(event.nick, styleText('whois_away', {nick: event.nick, text: translateText('client_models_network_away', [event.away_reason])}), 'whois'); |
ce13508b | 786 | } else { |
9ec48c54 | 787 | panel.addMsg(event.nick, styleText('whois_idle', {nick: event.nick, text: translateText('client_models_network_idle', [idle_time])}), 'whois'); |
ce13508b D |
788 | } |
789 | } | |
790 | ||
5989f3f4 JA |
791 | function onWhowas(event) { |
792 | var panel; | |
793 | ||
794 | if (event.end) | |
795 | return; | |
796 | ||
797 | panel = _kiwi.app.panels().active; | |
7a6ef4aa | 798 | if (event.hostname) { |
2bcae26b | 799 | panel.addMsg(event.nick, styleText('who', {nick: event.nick, ident: event.ident, host: event.hostname, realname: event.real_name, text: event.msg}), 'whois'); |
5989f3f4 | 800 | } else { |
9ec48c54 | 801 | panel.addMsg(event.nick, styleText('whois_notfound', {nick: event.nick, text: translateText('client_models_network_nickname_notfound', [])}), 'whois'); |
5989f3f4 JA |
802 | } |
803 | } | |
ce13508b D |
804 | |
805 | ||
806 | function onAway(event) { | |
807 | $.each(this.panels.models, function (index, panel) { | |
808 | if (!panel.isChannel()) return; | |
809 | ||
810 | member = panel.get('members').getByNick(event.nick); | |
811 | if (member) { | |
17dfa698 | 812 | member.set('away', !(!event.reason)); |
ce13508b D |
813 | } |
814 | }); | |
815 | } | |
816 | ||
817 | ||
818 | ||
819 | function onListStart(event) { | |
b24da6ba D |
820 | var chanlist = _kiwi.model.Applet.loadOnce('kiwi_chanlist'); |
821 | chanlist.view.show(); | |
ce13508b D |
822 | } |
823 | ||
824 | ||
825 | ||
826 | function onIrcError(event) { | |
827 | var panel, tmp; | |
828 | ||
f8240e98 | 829 | if (event.channel !== undefined && !(panel = this.panels.getByName(event.channel))) { |
ce13508b D |
830 | panel = this.panels.server; |
831 | } | |
832 | ||
833 | switch (event.error) { | |
834 | case 'banned_from_channel': | |
9ec48c54 | 835 | panel.addMsg(' ', styleText('channel_banned', {nick: event.nick, text: translateText('client_models_network_banned', [event.channel, event.reason]), channel: event.channel}), 'status'); |
247dd7ac | 836 | _kiwi.app.message.text(_kiwi.global.i18n.translate('client_models_network_banned').fetch(event.channel, event.reason)); |
ce13508b D |
837 | break; |
838 | case 'bad_channel_key': | |
9ec48c54 | 839 | panel.addMsg(' ', styleText('channel_badkey', {nick: event.nick, text: translateText('client_models_network_channel_badkey', [event.channel]), channel: event.channel}), 'status'); |
247dd7ac | 840 | _kiwi.app.message.text(_kiwi.global.i18n.translate('client_models_network_channel_badkey').fetch(event.channel)); |
ce13508b D |
841 | break; |
842 | case 'invite_only_channel': | |
9ec48c54 | 843 | panel.addMsg(' ', styleText('channel_inviteonly', {nick: event.nick, text: translateText('client_models_network_channel_inviteonly', [event.nick, event.channel]), channel: event.channel}), 'status'); |
a8675b0b | 844 | _kiwi.app.message.text(event.channel + ' ' + _kiwi.global.i18n.translate('client_models_network_channel_inviteonly').fetch()); |
ce13508b | 845 | break; |
3d753975 | 846 | case 'user_on_channel': |
9ec48c54 | 847 | panel.addMsg(' ', styleText('channel_alreadyin', {nick: event.nick, text: translateText('client_models_network_channel_alreadyin'), channel: event.channel})); |
3d753975 | 848 | break; |
ce13508b | 849 | case 'channel_is_full': |
9ec48c54 | 850 | panel.addMsg(' ', styleText('channel_limitreached', {nick: event.nick, text: translateText('client_models_network_channel_limitreached', [event.channel]), channel: event.channel}), 'status'); |
a8675b0b | 851 | _kiwi.app.message.text(event.channel + ' ' + _kiwi.global.i18n.translate('client_models_network_channel_limitreached').fetch(event.channel)); |
ce13508b D |
852 | break; |
853 | case 'chanop_privs_needed': | |
9ec48c54 | 854 | panel.addMsg(' ', styleText('chanop_privs_needed', {text: event.reason, channel: event.channel}), 'status'); |
ce13508b D |
855 | _kiwi.app.message.text(event.reason + ' (' + event.channel + ')'); |
856 | break; | |
adc46242 | 857 | case 'cannot_send_to_channel': |
1dad9adf | 858 | panel.addMsg(' ', '== ' + _kiwi.global.i18n.translate('Cannot send message to channel, you are not voiced').fetch(event.channel, event.reason), 'status'); |
adc46242 | 859 | break; |
ce13508b D |
860 | case 'no_such_nick': |
861 | tmp = this.panels.getByName(event.nick); | |
862 | if (tmp) { | |
9ec48c54 | 863 | tmp.addMsg(' ', styleText('no_such_nick', {nick: event.nick, text: event.reason, channel: event.channel}), 'status'); |
ce13508b | 864 | } else { |
9ec48c54 | 865 | this.panels.server.addMsg(' ', styleText('no_such_nick', {nick: event.nick, text: event.reason, channel: event.channel}), 'status'); |
ce13508b D |
866 | } |
867 | break; | |
868 | case 'nickname_in_use': | |
9ec48c54 | 869 | this.panels.server.addMsg(' ', styleText('nickname_alreadyinuse', {nick: event.nick, text: translateText('client_models_network_nickname_alreadyinuse', [event.nick]), channel: event.channel}), 'status'); |
2e06af20 | 870 | if (this.panels.server !== this.panels.active) { |
247dd7ac | 871 | _kiwi.app.message.text(_kiwi.global.i18n.translate('client_models_network_nickname_alreadyinuse').fetch(event.nick)); |
ce13508b D |
872 | } |
873 | ||
874 | // Only show the nickchange component if the controlbox is open | |
2e06af20 | 875 | if (_kiwi.app.controlbox.$el.css('display') !== 'none') { |
ce13508b D |
876 | (new _kiwi.view.NickChangeBox()).render(); |
877 | } | |
878 | ||
879 | break; | |
880 | ||
881 | case 'password_mismatch': | |
9ec48c54 | 882 | this.panels.server.addMsg(' ', styleText('channel_badpassword', {nick: event.nick, text: translateText('client_models_network_badpassword', []), channel: event.channel}), 'status'); |
ce13508b | 883 | break; |
b2703835 D |
884 | |
885 | case 'error': | |
886 | if (event.reason) { | |
887 | this.panels.server.addMsg(' ', styleText('general_error', {text: event.reason}), 'status'); | |
888 | } | |
889 | break; | |
890 | ||
ce13508b D |
891 | default: |
892 | // We don't know what data contains, so don't do anything with it. | |
893 | //_kiwi.front.tabviews.server.addMsg(null, ' ', '== ' + data, 'status'); | |
894 | } | |
895 | } | |
3d753975 D |
896 | |
897 | ||
898 | function onUnknownCommand(event) { | |
899 | var display_params = _.clone(event.params); | |
900 | ||
901 | // A lot of commands have our nick as the first parameter. This is redundant for us | |
902 | if (display_params[0] && display_params[0] == this.get('nick')) { | |
903 | display_params.shift(); | |
904 | } | |
905 | ||
9ec48c54 | 906 | this.panels.server.addMsg('', styleText('unknown_command', {text: '[' + event.command + '] ' + display_params.join(', ', '')})); |
3d753975 | 907 | } |
44f18d27 CC |
908 | |
909 | ||
910 | function onWallops(event) { | |
8e3a1248 D |
911 | var active_panel = _kiwi.app.panels().active; |
912 | ||
8d192fd2 CC |
913 | // Send to server panel |
914 | this.panels.server.addMsg('[' + (event.nick||'') + ']', styleText('wallops', {text: event.msg}), 'wallops', {time: event.time}); | |
8e3a1248 D |
915 | |
916 | // Send to active panel if its a channel/query *and* it's related to this network | |
917 | if (active_panel !== this.panels.server && (active_panel.isChannel() || active_panel.isQuery()) && active_panel.get('network') === this) | |
918 | active_panel.addMsg('[' + (event.nick||'') + ']', styleText('wallops', {text: event.msg}), 'wallops', {time: event.time}); | |
44f18d27 CC |
919 | } |
920 | ||
ce13508b D |
921 | } |
922 | ||
eed5ac29 | 923 | )(); |