Misc panels implemented
[KiwiIRC.git] / client_backbone / dev / model_application.js
CommitLineData
2c80d916
D
1kiwi.model.Application = Backbone.Model.extend(new (function () {\r
2 var that = this;\r
3\r
99e0111e
D
4 // The auto connect details entered into the server select box\r
5 var auto_connect_details = {};\r
6\r
b5141adb
D
7 /** Instance of kiwi.model.PanelList */\r
8 this.panels = null;\r
9\r
f8ce99b4
D
10 /** kiwi.view.Application */\r
11 this.view;\r
12\r
13 /** kiwi.view.StatusMessage */\r
14 this.message;\r
15\r
a37b761a
D
16 /* Address for the kiwi server */\r
17 this.kiwi_server = null;\r
18\r
2c80d916
D
19 this.initialize = function () {\r
20 // Update `that` with this new Model object\r
21 that = this;\r
a37b761a
D
22\r
23 // Best guess at where the kiwi server is\r
24 this.detectKiwiServer();\r
48d660e6 25 };\r
2c80d916 26\r
48d660e6 27 this.start = function () {\r
9df70c63
D
28 // Only debug if set in the querystring\r
29 if (!getQueryVariable('debug')) {\r
c4fc06f6 30 //manageDebug(false);\r
9df70c63 31 } else {\r
c4fc06f6 32 //manageDebug(true);\r
9df70c63
D
33 }\r
34 \r
2c80d916
D
35 // Set the gateway up\r
36 kiwi.gateway = new kiwi.model.Gateway();\r
37 this.bindGatewayCommands(kiwi.gateway);\r
38\r
2c80d916 39 this.initializeClient();\r
2af70088 40 this.view.barsHide(true);\r
2c80d916 41\r
4c1f047c 42 this.panels.server.server_login.bind('server_connect', function (event) {\r
a37b761a 43 var server_login = this;\r
c4fc06f6 44 auto_connect_details = event;\r
a37b761a 45\r
c4fc06f6
D
46 server_login.networkConnecting();\r
47 \r
48 $script(that.kiwi_server + '/socket.io/socket.io.js?ts='+(new Date().getTime()), function () {\r
49 if (!window.io) {\r
50 kiwiServerNotFound();\r
51 return;\r
52 }\r
53 kiwi.gateway.set('kiwi_server', that.kiwi_server + '/kiwi');\r
a37b761a 54 kiwi.gateway.set('nick', event.nick);\r
0f3d4221
D
55 \r
56 kiwi.gateway.connect(event.server, event.port, event.ssl, event.password, function () {});\r
a37b761a 57 });\r
2af70088 58 });\r
2c80d916 59\r
2c80d916
D
60 };\r
61\r
62\r
c4fc06f6
D
63 function kiwiServerNotFound (e) {\r
64 that.panels.server.server_login.showError();\r
65 }\r
66\r
67\r
a37b761a
D
68 this.detectKiwiServer = function () {\r
69 // If running from file, default to localhost:7777 by default\r
70 if (window.location.protocol === 'file') {\r
71 this.kiwi_server = 'http://localhost:7777';\r
72\r
73 } else {\r
74 // Assume the kiwi server is on the same server\r
75 var proto = window.location.protocol === 'https' ?\r
76 'https' :\r
77 'http';\r
78\r
c4fc06f6 79 this.kiwi_server = proto + '://' + window.location.host + ':' + (window.location.port || '80');\r
a37b761a
D
80 }\r
81 \r
82 };\r
83\r
84\r
2c80d916 85 this.initializeClient = function () {\r
b5141adb 86 this.view = new kiwi.view.Application({model: this, el: this.get('container')});\r
2c80d916
D
87\r
88 \r
89 /**\r
90 * Set the UI components up\r
91 */\r
4c1f047c
D
92 this.panels = new kiwi.model.PanelList();\r
93\r
2c80d916
D
94 this.controlbox = new kiwi.view.ControlBox({el: $('#controlbox')[0]});\r
95 this.bindControllboxCommands(this.controlbox);\r
96\r
52773494
D
97 this.topicbar = new kiwi.view.TopicBar({el: $('#topic')[0]});\r
98\r
f8ce99b4
D
99 this.message = new kiwi.view.StatusMessage({el: $('#status_message')[0]});\r
100\r
4c1f047c 101 \r
2c80d916
D
102 this.panels.server.view.show();\r
103\r
104 // Rejigg the UI sizes\r
105 this.view.doLayout();\r
2af70088
D
106\r
107 // Populate the server select box with defaults\r
108 this.panels.server.server_login.populateFields({\r
0f3d4221
D
109 nick: getQueryVariable('nick') || 'kiwi_' + Math.ceil(Math.random() * 10000).toString(),\r
110 server: getQueryVariable('server') || 'irc.kiwiirc.com',\r
111 port: 6667,\r
112 ssl: false,\r
113 channel: window.location.hash || '#test'\r
2af70088 114 });\r
2c80d916
D
115 };\r
116\r
117\r
118\r
119 this.bindGatewayCommands = function (gw) {\r
120 gw.on('onmotd', function (event) {\r
121 that.panels.server.addMsg(event.server, event.msg, 'motd');\r
122 });\r
123\r
124\r
99e0111e
D
125 gw.on('onconnect', function (event) {\r
126 that.view.barsShow();\r
127 \r
128 if (auto_connect_details.channel) {\r
129 kiwi.gateway.join(auto_connect_details.channel);\r
130 }\r
131 });\r
2c80d916
D
132\r
133\r
f8ce99b4
D
134 (function () {\r
135 var gw_stat = 0;\r
136\r
137 gw.on('disconnect', function (event) {\r
138 that.message.text('You have been disconnected. Attempting to reconnect..');\r
139 gw_stat = 1;\r
140 });\r
141 gw.on('reconnecting', function (event) {\r
142 that.message.text('You have been disconnected. Attempting to reconnect again in ' + (event.delay/1000) + ' seconds..');\r
143 });\r
144 gw.on('connect', function (event) {\r
145 if (gw_stat !== 1) return;\r
146\r
147 that.message.text('It\'s OK, you\'re connected again :)', {timeout: 5000});\r
148 gw_stat = 0;\r
149 });\r
150 })();\r
151\r
152\r
2c80d916 153 gw.on('onjoin', function (event) {\r
2c80d916
D
154 var c, members, user;\r
155 c = that.panels.getByName(event.channel);\r
156 if (!c) {\r
157 c = new kiwi.model.Channel({name: event.channel});\r
158 that.panels.add(c);\r
159 }\r
160\r
161 members = c.get('members');\r
162 if (!members) return;\r
163\r
164 user = new kiwi.model.Member({nick: event.nick, ident: event.ident, hostname: event.hostname});\r
165 members.add(user);\r
166 // TODO: highlight the new channel in some way\r
167 });\r
168\r
169\r
170 gw.on('onpart', function (event) {\r
5712c148
D
171 var channel, members, user,\r
172 part_options = {};\r
173\r
174 part_options.type = 'part';\r
175 part_options.message = event.message || '';\r
2c80d916
D
176\r
177 channel = that.panels.getByName(event.channel);\r
178 if (!channel) return;\r
179\r
180 // If this is us, close the panel\r
181 if (event.nick === kiwi.gateway.get('nick')) {\r
182 channel.close();\r
183 return;\r
184 }\r
185\r
186 members = channel.get('members');\r
187 if (!members) return;\r
188\r
189 user = members.getByNick(event.nick);\r
190 if (!user) return;\r
191\r
5712c148
D
192 members.remove(user, part_options);\r
193 });\r
194\r
195\r
196 gw.on('onquit', function (event) {\r
197 var member, members,\r
198 quit_options = {};\r
199\r
200 quit_options.type = 'quit';\r
201 quit_options.message = event.message || '';\r
202\r
203 $.each(that.panels.models, function (index, panel) {\r
204 if (!panel.isChannel()) return;\r
205\r
206 member = panel.get('members').getByNick(event.nick);\r
207 if (member) {\r
208 panel.get('members').remove(member, quit_options);\r
209 }\r
210 });\r
2c80d916
D
211 });\r
212\r
213\r
94016cd4
D
214 gw.on('onkick', function (event) {\r
215 var channel, members, user,\r
216 part_options = {};\r
217\r
218 part_options.type = 'kick';\r
219 part_options.by = event.nick;\r
220 part_options.message = event.message || '';\r
221\r
222 channel = that.panels.getByName(event.channel);\r
223 if (!channel) return;\r
224\r
225 members = channel.get('members');\r
226 if (!members) return;\r
227\r
228 user = members.getByNick(event.kicked);\r
229 if (!user) return;\r
230\r
231 members.remove(user, part_options);\r
232\r
233 if (event.kicked === kiwi.gateway.get('nick')) {\r
234 members.reset([]);\r
235 }\r
236 \r
237 });\r
238\r
239\r
2c80d916
D
240 gw.on('onmsg', function (event) {\r
241 var panel,\r
242 is_pm = (event.channel == kiwi.gateway.get('nick'));\r
243\r
244 if (is_pm) {\r
245 // If a panel isn't found for this PM, create one\r
246 panel = that.panels.getByName(event.nick);\r
247 if (!panel) {\r
248 panel = new kiwi.model.Channel({name: event.nick});\r
249 that.panels.add(panel);\r
250 }\r
251\r
252 } else {\r
253 // If a panel isn't found for this channel, reroute to the\r
254 // server panel\r
255 panel = that.panels.getByName(event.channel);\r
256 if (!panel) {\r
257 panel = that.panels.server;\r
258 }\r
259 }\r
260 \r
261 panel.addMsg(event.nick, event.msg);\r
262 });\r
263\r
264\r
265 gw.on('onnotice', function (event) {\r
68314431
D
266 var panel;\r
267\r
9783a703
D
268 // Find a panel for the destination(channel) or who its from\r
269 panel = that.panels.getByName(event.target) || that.panels.getByName(event.nick);\r
68314431
D
270 if (!panel) {\r
271 panel = that.panels.server;\r
272 }\r
273\r
274 panel.addMsg('[' + (event.nick||'') + ']', event.msg);\r
2c80d916
D
275 });\r
276\r
277\r
0f40d499
D
278 gw.on('onaction', function (event) {\r
279 var panel,\r
280 is_pm = (event.channel == kiwi.gateway.get('nick'));\r
281\r
282 if (is_pm) {\r
283 // If a panel isn't found for this PM, create one\r
284 panel = that.panels.getByName(event.nick);\r
285 if (!panel) {\r
286 panel = new kiwi.model.Channel({name: event.nick});\r
287 that.panels.add(panel);\r
288 }\r
289\r
290 } else {\r
291 // If a panel isn't found for this channel, reroute to the\r
292 // server panel\r
293 panel = that.panels.getByName(event.channel);\r
294 if (!panel) {\r
295 panel = that.panels.server;\r
296 }\r
297 }\r
298\r
299 panel.addMsg('', '* ' + event.nick + ' ' + event.msg, 'action');\r
300 });\r
301\r
302\r
2c80d916
D
303 gw.on('ontopic', function (event) {\r
304 var c;\r
305 c = that.panels.getByName(event.channel);\r
306 if (!c) return;\r
307\r
308 // Set the channels topic\r
309 c.set('topic', event.topic);\r
310\r
311 // If this is the active channel, update the topic bar too\r
48d660e6 312 if (c.get('name') === kiwi.app.panels.active.get('name')) {\r
52773494 313 that.topicbar.setCurrentTopic(event.topic);\r
2c80d916
D
314 }\r
315 });\r
316\r
317\r
4a9e8527
D
318 gw.on('ontopicsetby', function (event) {\r
319 var c, when;\r
320 c = that.panels.getByName(event.channel);\r
321 if (!c) return;\r
322\r
323 when = new Date(event.when * 1000).toLocaleString();\r
324 c.addMsg('', 'Topic set by ' + event.nick + ' at ' + when, 'topic');\r
325 });\r
326\r
327\r
2c80d916
D
328 gw.on('onuserlist', function (event) {\r
329 var channel;\r
330 channel = that.panels.getByName(event.channel);\r
331\r
332 // If we didn't find a channel for this, may aswell leave\r
333 if (!channel) return;\r
334\r
335 channel.temp_userlist = channel.temp_userlist || [];\r
336 _.each(event.users, function (item) {\r
337 var user = new kiwi.model.Member({nick: item.nick, modes: item.modes});\r
338 channel.temp_userlist.push(user);\r
339 });\r
340 });\r
341\r
342\r
343 gw.on('onuserlist_end', function (event) {\r
344 var channel;\r
345 channel = that.panels.getByName(event.channel);\r
346\r
347 // If we didn't find a channel for this, may aswell leave\r
348 if (!channel) return;\r
349\r
350 // Update the members list with the new list\r
351 channel.get('members').reset(channel.temp_userlist || []);\r
352\r
353 // Clear the temporary userlist\r
354 delete channel.temp_userlist;\r
355 });\r
dfe8ef37
D
356\r
357\r
358 gw.on('onmode', function (event) {\r
359 var channel, members, member;\r
360\r
361 if (!event.channel) return;\r
362 channel = that.panels.getByName(event.channel);\r
363 if (!channel) return;\r
364\r
365 members = channel.get('members');\r
366 if (!members) return;\r
367\r
368 member = members.getByNick(event.effected_nick);\r
369 if (!member) return;\r
370\r
371 if (event.mode[0] === '+') {\r
372 member.addMode(event.mode.substr(1));\r
373 } else if (event.mode[0] === '-') {\r
374 member.removeMode(event.mode.substr(1));\r
375 }\r
967687fc
D
376 });\r
377\r
378\r
379 gw.on('onnick', function (event) {\r
380 var member;\r
dfe8ef37 381\r
967687fc
D
382 $.each(that.panels.models, function (index, panel) {\r
383 if (!panel.isChannel()) return;\r
384\r
385 member = panel.get('members').getByNick(event.nick);\r
386 if (member) {\r
387 member.set('nick', event.newnick);\r
388 panel.addMsg('', '== ' + event.nick + ' is now known as ' + event.newnick, 'action nick');\r
389 }\r
390 });\r
dfe8ef37 391 });\r
a7758021
D
392\r
393\r
394 gw.on('onwhois', function (event) {\r
395 /*globals secondsToTime */\r
396 var logon_date, idle_time = '', panel;\r
397\r
398 if (event.end) {\r
399 return;\r
400 }\r
401\r
402 if (typeof event.idle !== 'undefined') {\r
403 idle_time = secondsToTime(parseInt(event.idle, 10));\r
404 idle_time = idle_time.h.toString().lpad(2, "0") + ':' + idle_time.m.toString().lpad(2, "0") + ':' + idle_time.s.toString().lpad(2, "0");\r
405 }\r
406\r
407 panel = kiwi.app.panels.active;\r
408 if (event.msg) {\r
409 panel.addMsg(event.nick, event.msg, 'whois');\r
410 } else if (event.logon) {\r
411 logon_date = new Date();\r
412 logon_date.setTime(event.logon * 1000);\r
413 logon_date = logon_date.toLocaleString();\r
414\r
415 panel.addMsg(event.nick, 'idle for ' + idle_time + ', signed on ' + logon_date, 'whois');\r
416 } else {\r
417 panel.addMsg(event.nick, 'idle for ' + idle_time, 'whois');\r
418 }\r
419 });\r
2c80d916
D
420 };\r
421\r
422\r
423\r
424 /**\r
425 * Bind to certain commands that may be typed into the control box\r
426 */\r
427 this.bindControllboxCommands = function (controlbox) {\r
428 controlbox.on('unknown_command', this.unknownCommand);\r
429\r
430 controlbox.on('command', this.allCommands);\r
431 controlbox.on('command_msg', this.msgCommand);\r
432\r
0f40d499
D
433 controlbox.on('command_action', this.actionCommand);\r
434 controlbox.on('command_me', this.actionCommand);\r
435\r
2c80d916
D
436 controlbox.on('command_join', this.joinCommand);\r
437 controlbox.on('command_j', this.joinCommand);\r
438\r
439 controlbox.on('command_part', this.partCommand);\r
440 controlbox.on('command_p', this.partCommand);\r
441\r
442 controlbox.on('command_nick', function (ev) {\r
443 kiwi.gateway.changeNick(ev.params[0]);\r
444 });\r
445\r
9783a703
D
446 controlbox.on('command_query', this.queryCommand);\r
447 controlbox.on('command_q', this.queryCommand);\r
448\r
b5141adb
D
449 controlbox.on('command_topic', this.topicCommand);\r
450\r
68314431
D
451 controlbox.on('command_notice', this.noticeCommand);\r
452\r
2c80d916
D
453 controlbox.on('command_css', function (ev) {\r
454 var queryString = '?reload=' + new Date().getTime();\r
455 $('link[rel="stylesheet"]').each(function () {\r
456 this.href = this.href.replace(/\?.*|$/, queryString);\r
457 });\r
458 });\r
bacc69cb
D
459\r
460 controlbox.on('command_theme', this.themeCommand);\r
2c80d916
D
461 };\r
462\r
9783a703 463 // A fallback action. Send a raw command to the server\r
2c80d916 464 this.unknownCommand = function (ev) {\r
9783a703
D
465 var raw_cmd = ev.command + ' ' + ev.params.join(' ');\r
466 console.log('RAW: ' + raw_cmd);\r
467 kiwi.gateway.raw(raw_cmd);\r
2c80d916
D
468 };\r
469\r
470 this.allCommands = function (ev) {\r
471 console.log('allCommands', ev);\r
472 };\r
473\r
474 this.joinCommand = function (ev) {\r
0e12f51d
D
475 var channel, channel_names;\r
476\r
477 channel_names = ev.params.join(' ').split(',');\r
478\r
479 $.each(channel_names, function (index, channel_name) {\r
480 // Trim any whitespace off the name\r
481 channel_name = channel_name.trim();\r
482\r
483 // Check if we have the panel already. If not, create it\r
484 channel = that.panels.getByName(channel_name);\r
485 if (!channel) {\r
486 channel = new kiwi.model.Channel({name: channel_name});\r
487 kiwi.app.panels.add(channel);\r
488 }\r
489\r
490 kiwi.gateway.join(channel_name);\r
491 });\r
492\r
493 if (channel) channel.view.show();\r
494 \r
2c80d916
D
495 };\r
496\r
9783a703
D
497 this.queryCommand = function (ev) {\r
498 var destination, panel;\r
499\r
500 destination = ev.params[0];\r
501\r
502 // Check if we have the panel already. If not, create it\r
503 panel = that.panels.getByName(destination);\r
504 if (!panel) {\r
505 panel = new kiwi.model.Channel({name: destination});\r
506 kiwi.app.panels.add(panel);\r
507 }\r
508\r
509 if (panel) panel.view.show();\r
510 \r
511 };\r
512\r
2c80d916 513 this.msgCommand = function (ev) {\r
9783a703
D
514 var destination = ev.params[0],\r
515 panel = that.panels.getByName(destination) || that.panels.server;\r
516\r
517 ev.params.shift();\r
518\r
519 panel.addMsg(kiwi.gateway.get('nick'), ev.params.join(' '));\r
520 kiwi.gateway.privmsg(destination, ev.params.join(' '));\r
2c80d916
D
521 };\r
522\r
0f40d499 523 this.actionCommand = function (ev) {\r
48d660e6 524 if (kiwi.app.panels.active === kiwi.app.panels.server) {\r
0f40d499
D
525 return;\r
526 }\r
527\r
48d660e6 528 var panel = kiwi.app.panels.active;\r
0f40d499
D
529 panel.addMsg('', '* ' + kiwi.gateway.get('nick') + ' ' + ev.params.join(' '), 'action');\r
530 kiwi.gateway.action(panel.get('name'), ev.params.join(' '));\r
531 };\r
532\r
2c80d916
D
533 this.partCommand = function (ev) {\r
534 if (ev.params.length === 0) {\r
48d660e6 535 kiwi.gateway.part(kiwi.app.panels.active.get('name'));\r
2c80d916
D
536 } else {\r
537 _.each(ev.params, function (channel) {\r
538 kiwi.gateway.part(channel);\r
539 });\r
540 }\r
52773494 541 // TODO: More responsive = close tab now, more accurate = leave until part event\r
48d660e6 542 //kiwi.app.panels.remove(kiwi.app.panels.active);\r
2c80d916
D
543 };\r
544\r
b5141adb
D
545 this.topicCommand = function (ev) {\r
546 var channel_name;\r
547\r
548 if (ev.params.length === 0) return;\r
549\r
550 if (that.isChannelName(ev.params[0])) {\r
551 channel_name = ev.params[0];\r
552 ev.params.shift();\r
553 } else {\r
48d660e6 554 channel_name = kiwi.app.panels.active.get('name');\r
b5141adb
D
555 }\r
556\r
557 kiwi.gateway.topic(channel_name, ev.params.join(' '));\r
558 };\r
559\r
68314431
D
560 this.noticeCommand = function (ev) {\r
561 var destination;\r
562\r
563 // Make sure we have a destination and some sort of message\r
564 if (ev.params.length <= 1) return;\r
565\r
566 destination = ev.params[0];\r
567 ev.params.shift();\r
568\r
569 kiwi.gateway.notice(destination, ev.params.join(' '));\r
570 };\r
571\r
bacc69cb
D
572 this.themeCommand = function (ev) {\r
573 var theme = ev.params[0] || false,\r
574 containers = $('#panels > .panel_container');\r
575\r
576 // Clear any current theme\r
577 containers.removeClass(function (i, css) {\r
578 return (css.match (/\btheme_\S+/g) || []).join(' ');\r
579 });\r
580\r
581 if (theme) containers.addClass('theme_' + theme);\r
582 };\r
583\r
2c80d916
D
584\r
585\r
586\r
587\r
b5141adb
D
588 this.isChannelName = function (channel_name) {\r
589 var channel_prefix = kiwi.gateway.get('channel_prefix');\r
590\r
591 if (!channel_name || !channel_name.length) return false;\r
592 return (channel_prefix.indexOf(channel_name[0]) > -1);\r
593 };\r
594\r
2dd6a025 595})());