c45a73d9eb02e24db6c6491392552c8117cfaf1c
[KiwiIRC.git] / client / src / models / application.js
1 (function () {
2
3 _kiwi.model.Application = Backbone.Model.extend({
4 /** _kiwi.view.Application */
5 view: null,
6
7 /** _kiwi.view.StatusMessage */
8 message: null,
9
10 initialize: function (options) {
11 this.app_options = options;
12
13 if (options.container) {
14 this.set('container', options.container);
15 }
16
17 // The base url to the kiwi server
18 this.set('base_path', options.base_path ? options.base_path : '');
19
20 // Path for the settings.json file
21 this.set('settings_path', options.settings_path ?
22 options.settings_path :
23 this.get('base_path') + '/assets/settings.json'
24 );
25
26 // Any options sent down from the server
27 this.server_settings = options.server_settings || {};
28 this.translations = options.translations || {};
29 this.themes = options.themes || [];
30 this.text_theme = options.text_theme || {};
31
32 // The applet to initially load
33 this.startup_applet_name = options.startup || 'kiwi_startup';
34
35 // Set any default settings before anything else is applied
36 if (this.server_settings && this.server_settings.client && this.server_settings.client.settings) {
37 this.applyDefaultClientSettings(this.server_settings.client.settings);
38 }
39 },
40
41
42 initializeInterfaces: function () {
43 // Best guess at where the kiwi server is if not already specified
44 var kiwi_server = this.app_options.kiwi_server || this.detectKiwiServer();
45
46 // Set the gateway up
47 _kiwi.gateway = new _kiwi.model.Gateway({kiwi_server: kiwi_server});
48 this.bindGatewayCommands(_kiwi.gateway);
49
50 this.initializeClient();
51 this.initializeGlobals();
52
53 this.view.barsHide(true);
54 },
55
56
57 detectKiwiServer: function () {
58 // If running from file, default to localhost:7777 by default
59 if (window.location.protocol === 'file:') {
60 return 'http://localhost:7778';
61 } else {
62 // Assume the kiwi server is on the same server
63 return window.location.protocol + '//' + window.location.host;
64 }
65 },
66
67
68 showStartup: function() {
69 this.startup_applet = _kiwi.model.Applet.load(this.startup_applet_name, {no_tab: true});
70 this.startup_applet.tab = this.view.$('.console');
71 this.startup_applet.view.show();
72
73 _kiwi.global.events.emit('loaded');
74 },
75
76
77 initializeClient: function () {
78 this.view = new _kiwi.view.Application({model: this, el: this.get('container')});
79
80 // Takes instances of model_network
81 this.connections = new _kiwi.model.NetworkPanelList();
82
83 // Applets panel list
84 this.applet_panels = new _kiwi.model.PanelList();
85 this.applet_panels.view.$el.addClass('panellist applets');
86 this.view.$el.find('.tabs').append(this.applet_panels.view.$el);
87
88 /**
89 * Set the UI components up
90 */
91 this.controlbox = (new _kiwi.view.ControlBox({el: $('#kiwi .controlbox')[0]})).render();
92 this.client_ui_commands = new _kiwi.misc.ClientUiCommands(this, this.controlbox);
93
94 this.rightbar = new _kiwi.view.RightBar({el: this.view.$('.right_bar')[0]});
95 this.topicbar = new _kiwi.view.TopicBar({el: this.view.$el.find('.topic')[0]});
96
97 new _kiwi.view.AppToolbar({el: _kiwi.app.view.$el.find('.toolbar .app_tools')[0]});
98 new _kiwi.view.ChannelTools({el: _kiwi.app.view.$el.find('.channel_tools')[0]});
99
100 this.message = new _kiwi.view.StatusMessage({el: this.view.$el.find('.status_message')[0]});
101
102 this.resize_handle = new _kiwi.view.ResizeHandler({el: this.view.$el.find('.memberlists_resize_handle')[0]});
103
104 // Rejigg the UI sizes
105 this.view.doLayout();
106 },
107
108
109 initializeGlobals: function () {
110 _kiwi.global.connections = this.connections;
111
112 _kiwi.global.panels = this.panels;
113 _kiwi.global.panels.applets = this.applet_panels;
114
115 _kiwi.global.components.Applet = _kiwi.model.Applet;
116 _kiwi.global.components.Panel =_kiwi.model.Panel;
117 _kiwi.global.components.MenuBox = _kiwi.view.MenuBox;
118 _kiwi.global.components.DataStore = _kiwi.model.DataStore;
119 _kiwi.global.components.Notification = _kiwi.view.Notification;
120 _kiwi.global.components.Events = function() {
121 return kiwi.events.createProxy();
122 };
123 },
124
125
126 applyDefaultClientSettings: function (settings) {
127 _.each(settings, function (value, setting) {
128 if (typeof _kiwi.global.settings.get(setting) === 'undefined') {
129 _kiwi.global.settings.set(setting, value);
130 }
131 });
132 },
133
134
135 panels: (function() {
136 var active_panel;
137
138 var fn = function(panel_type) {
139 var panels;
140
141 // Default panel type
142 panel_type = panel_type || 'connections';
143
144 switch (panel_type) {
145 case 'connections':
146 panels = this.connections.panels();
147 break;
148 case 'applets':
149 panels = this.applet_panels.models;
150 break;
151 }
152
153 // Active panels / server
154 panels.active = active_panel;
155 panels.server = this.connections.active_connection ?
156 this.connections.active_connection.panels.server :
157 null;
158
159 return panels;
160 };
161
162 _.extend(fn, Backbone.Events);
163
164 // Keep track of the active panel. Channel/query/server or applet
165 fn.bind('active', function (new_active_panel) {
166 var previous_panel = active_panel;
167 active_panel = new_active_panel;
168
169 _kiwi.global.events.emit('panel:active', {previous: previous_panel, active: active_panel});
170 });
171
172 return fn;
173 })(),
174
175
176 bindGatewayCommands: function (gw) {
177 var that = this;
178
179 // As soon as an IRC connection is made, show the full client UI
180 gw.on('connection:connect', function (event) {
181 that.view.barsShow();
182 });
183
184
185 /**
186 * Handle the reconnections to the kiwi server
187 */
188 (function () {
189 // 0 = non-reconnecting state. 1 = reconnecting state.
190 var gw_stat = 0;
191
192 gw.on('disconnect', function (event) {
193 that.view.$el.removeClass('connected');
194
195 // Reconnection phase will start to kick in
196 gw_stat = 1;
197 });
198
199
200 gw.on('reconnecting', function (event) {
201 var msg = translateText('client_models_application_reconnect_in_x_seconds', [event.delay/1000]) + '...';
202
203 // Only need to mention the repeating re-connection messages on server panels
204 _kiwi.app.connections.forEach(function(connection) {
205 connection.panels.server.addMsg('', styleText('quit', {text: msg}), 'action quit');
206 });
207 });
208
209
210 // After the socket has connected, kiwi handshakes and then triggers a kiwi:connected event
211 gw.on('kiwi:connected', function (event) {
212 var msg;
213
214 that.view.$el.addClass('connected');
215
216 // Make the rpc globally available for plugins
217 _kiwi.global.rpc = _kiwi.gateway.rpc;
218
219 _kiwi.global.events.emit('connected');
220
221 // If we were reconnecting, show some messages we have connected back OK
222 if (gw_stat === 1) {
223
224 // No longer in the reconnection state
225 gw_stat = 0;
226
227 msg = translateText('client_models_application_reconnect_successfully') + ' :)';
228 that.message.text(msg, {timeout: 5000});
229
230 // Mention the re-connection on every channel
231 _kiwi.app.connections.forEach(function(connection) {
232 connection.reconnect();
233
234 connection.panels.server.addMsg('', styleText('rejoin', {text: msg}), 'action join');
235
236 connection.panels.forEach(function(panel) {
237 if (!panel.isChannel())
238 return;
239
240 panel.addMsg('', styleText('rejoin', {text: msg}), 'action join');
241 });
242 });
243 }
244
245 });
246 })();
247
248
249 gw.on('kiwi:reconfig', function () {
250 $.getJSON(that.get('settings_path'), function (data) {
251 that.server_settings = data.server_settings || {};
252 that.translations = data.translations || {};
253 });
254 });
255
256
257 gw.on('kiwi:jumpserver', function (data) {
258 var serv;
259 // No server set? Then nowhere to jump to.
260 if (typeof data.kiwi_server === 'undefined')
261 return;
262
263 serv = data.kiwi_server;
264
265 // Strip any trailing slash from the end
266 if (serv[serv.length-1] === '/')
267 serv = serv.substring(0, serv.length-1);
268
269 // Force the jumpserver now?
270 if (data.force) {
271 // Get an interval between 5 and 6 minutes so everyone doesn't reconnect it all at once
272 var jump_server_interval = Math.random() * (360 - 300) + 300;
273 jump_server_interval = 1;
274
275 // Tell the user we are going to disconnect, wait 5 minutes then do the actual reconnect
276 var msg = _kiwi.global.i18n.translate('client_models_application_jumpserver_prepare').fetch();
277 that.message.text(msg, {timeout: 10000});
278
279 setTimeout(function forcedReconnect() {
280 var msg = _kiwi.global.i18n.translate('client_models_application_jumpserver_reconnect').fetch();
281 that.message.text(msg, {timeout: 8000});
282
283 setTimeout(function forcedReconnectPartTwo() {
284 _kiwi.gateway.set('kiwi_server', serv);
285
286 _kiwi.gateway.reconnect(function() {
287 // Reconnect all the IRC connections
288 that.connections.forEach(function(con){ con.reconnect(); });
289 });
290 }, 5000);
291
292 }, jump_server_interval * 1000);
293 }
294 });
295 }
296
297 });
298
299 })();