Connection issues fix #472
[KiwiIRC.git] / client / src / views / application.js
CommitLineData
50ac472f
D
1_kiwi.view.Application = Backbone.View.extend({
2 initialize: function () {
3 var that = this;
4
00203b94
D
5 this.$el = $($('#tmpl_application').html().trim());
6 this.el = this.$el[0];
7
8 $(this.model.get('container') || 'body').append(this.$el);
9aa4b87d 9
783fcf1f
D
10 this.elements = {
11 panels: this.$el.find('.panels'),
12 memberlists: this.$el.find('.memberlists'),
13 toolbar: this.$el.find('.toolbar'),
14 controlbox: this.$el.find('.controlbox'),
15 resize_handle: this.$el.find('.memberlists_resize_handle')
16 };
17
50ac472f 18 $(window).resize(function() { that.doLayout.apply(that); });
783fcf1f
D
19 this.elements.toolbar.resize(function() { that.doLayout.apply(that); });
20 this.elements.controlbox.resize(function() { that.doLayout.apply(that); });
50ac472f
D
21
22 // Change the theme when the config is changed
23 _kiwi.global.settings.on('change:theme', this.updateTheme, this);
24 this.updateTheme(getQueryVariable('theme'));
25
26 _kiwi.global.settings.on('change:channel_list_style', this.setTabLayout, this);
27 this.setTabLayout(_kiwi.global.settings.get('channel_list_style'));
28
29 _kiwi.global.settings.on('change:show_timestamps', this.displayTimestamps, this);
30 this.displayTimestamps(_kiwi.global.settings.get('show_timestamps'));
31
9aa4b87d 32 this.$el.appendTo($('body'));
50ac472f
D
33 this.doLayout();
34
35 $(document).keydown(this.setKeyFocus);
36
37 // Confirmation require to leave the page
38 window.onbeforeunload = function () {
39 if (_kiwi.gateway.isConnected()) {
247dd7ac 40 return _kiwi.global.i18n.translate('client_views_application_close_notice').fetch();
50ac472f
D
41 }
42 };
43
ee2f0962
D
44 // Keep tabs on the browser having focus
45 this.has_focus = true;
46
47 $(window).on('focus', function () {
48 that.has_focus = true;
49 });
50 $(window).on('blur', function () {
51 that.has_focus = false;
52 });
53
54
0b7949de 55 this.favicon = new _kiwi.view.Favicon();
50ac472f
D
56 this.initSound();
57 },
58
59
60
61 updateTheme: function (theme_name) {
62 // If called by the settings callback, get the correct new_value
63 if (theme_name === _kiwi.global.settings) {
64 theme_name = arguments[1];
65 }
66
67 // If we have no theme specified, get it from the settings
05934d33
JA
68 if (!theme_name) theme_name = _kiwi.global.settings.get('theme') || 'relaxed';
69
70 theme_name = theme_name.toLowerCase();
50ac472f
D
71
72 // Clear any current theme
f80d5a6b 73 $('[data-theme]:not([disabled])').each(function (idx, link) {
05934d33 74 var $link = $(link);
15dc5f90 75 $link.attr('rel', 'alternate ' + $link.attr('rel')).attr('disabled', true)[0].disabled = true;
50ac472f
D
76 });
77
78 // Apply the new theme
f80d5a6b 79 var link = $('[data-theme][title=' + theme_name + ']');
05934d33 80 if (link.length > 0) {
15dc5f90 81 link.attr('rel', 'stylesheet').attr('disabled', false)[0].disabled = false;
05934d33 82 }
f7c668a5
D
83
84 this.doLayout();
50ac472f
D
85 },
86
87
88 setTabLayout: function (layout_style) {
89 // If called by the settings callback, get the correct new_value
90 if (layout_style === _kiwi.global.settings) {
91 layout_style = arguments[1];
92 }
ee2f0962 93
50ac472f
D
94 if (layout_style == 'list') {
95 this.$el.addClass('chanlist_treeview');
96 } else {
97 this.$el.removeClass('chanlist_treeview');
98 }
ee2f0962 99
50ac472f
D
100 this.doLayout();
101 },
102
103
104 displayTimestamps: function (show_timestamps) {
105 // If called by the settings callback, get the correct new_value
106 if (show_timestamps === _kiwi.global.settings) {
107 show_timestamps = arguments[1];
108 }
109
110 if (show_timestamps) {
111 this.$el.addClass('timestamps');
112 } else {
113 this.$el.removeClass('timestamps');
114 }
115 },
116
117
118 // Globally shift focus to the command input box on a keypress
119 setKeyFocus: function (ev) {
120 // If we're copying text, don't shift focus
121 if (ev.ctrlKey || ev.altKey || ev.metaKey) {
122 return;
123 }
124
125 // If we're typing into an input box somewhere, ignore
126 if ((ev.target.tagName.toLowerCase() === 'input') || (ev.target.tagName.toLowerCase() === 'textarea') || $(ev.target).attr('contenteditable')) {
127 return;
128 }
129
130 $('#kiwi .controlbox .inp').focus();
131 },
132
133
134 doLayout: function () {
135 var el_kiwi = this.$el;
783fcf1f
D
136 var el_panels = this.elements.panels;
137 var el_memberlists = this.elements.memberlists;
138 var el_toolbar = this.elements.toolbar;
139 var el_controlbox = this.elements.controlbox;
140 var el_resize_handle = this.elements.resize_handle;
50ac472f 141
9aa4b87d
D
142 if (!el_kiwi.is(':visible')) {
143 return;
144 }
145
50ac472f
D
146 var css_heights = {
147 top: el_toolbar.outerHeight(true),
148 bottom: el_controlbox.outerHeight(true)
149 };
150
151
152 // If any elements are not visible, full size the panals instead
153 if (!el_toolbar.is(':visible')) {
154 css_heights.top = 0;
155 }
156
157 if (!el_controlbox.is(':visible')) {
158 css_heights.bottom = 0;
159 }
160
161 // Apply the CSS sizes
162 el_panels.css(css_heights);
163 el_memberlists.css(css_heights);
164 el_resize_handle.css(css_heights);
165
166 // If we have channel tabs on the side, adjust the height
167 if (el_kiwi.hasClass('chanlist_treeview')) {
168 this.$el.find('.tabs', el_kiwi).css(css_heights);
169 }
170
171 // Determine if we have a narrow window (mobile/tablet/or even small desktop window)
172 if (el_kiwi.outerWidth() < 400) {
173 el_kiwi.addClass('narrow');
174 } else {
175 el_kiwi.removeClass('narrow');
176 }
177
178 // Set the panels width depending on the memberlist visibility
179 if (el_memberlists.css('display') != 'none') {
180 // Panels to the side of the memberlist
181 el_panels.css('right', el_memberlists.outerWidth(true));
182 // The resize handle sits overlapping the panels and memberlist
183 el_resize_handle.css('left', el_memberlists.position().left - (el_resize_handle.outerWidth(true) / 2));
184 } else {
185 // Memberlist is hidden so panels to the right edge
186 el_panels.css('right', 0);
187 // And move the handle just out of sight to the right
188 el_resize_handle.css('left', el_panels.outerWidth(true));
189 }
190
191 var input_wrap_width = parseInt($('#kiwi .controlbox .input_tools').outerWidth());
192 el_controlbox.find('.input_wrap').css('right', input_wrap_width + 7);
193 },
194
195
196 alertWindow: function (title) {
197 if (!this.alertWindowTimer) {
198 this.alertWindowTimer = new (function () {
199 var that = this;
200 var tmr;
201 var has_focus = true;
202 var state = 0;
73b7cc44 203 var default_title = _kiwi.app.server_settings.client.window_title || 'Kiwi IRC';
50ac472f
D
204 var title = 'Kiwi IRC';
205
206 this.setTitle = function (new_title) {
207 new_title = new_title || default_title;
208 window.document.title = new_title;
209 return new_title;
210 };
211
212 this.start = function (new_title) {
213 // Don't alert if we already have focus
214 if (has_focus) return;
215
216 title = new_title;
217 if (tmr) return;
218 tmr = setInterval(this.update, 1000);
219 };
220
221 this.stop = function () {
222 // Stop the timer and clear the title
223 if (tmr) clearInterval(tmr);
224 tmr = null;
225 this.setTitle();
226
227 // Some browsers don't always update the last title correctly
228 // Wait a few seconds and then reset
229 setTimeout(this.reset, 2000);
230 };
231
232 this.reset = function () {
233 if (tmr) return;
234 that.setTitle();
235 };
236
237
238 this.update = function () {
239 if (state === 0) {
240 that.setTitle(title);
241 state = 1;
242 } else {
243 that.setTitle();
244 state = 0;
245 }
246 };
247
248 $(window).focus(function (event) {
249 has_focus = true;
250 that.stop();
251
252 // Some browsers don't always update the last title correctly
253 // Wait a few seconds and then reset
254 setTimeout(that.reset, 2000);
255 });
256
257 $(window).blur(function (event) {
258 has_focus = false;
259 });
260 })();
261 }
262
263 this.alertWindowTimer.start(title);
264 },
265
266
267 barsHide: function (instant) {
268 var that = this;
269
270 if (!instant) {
271 this.$el.find('.toolbar').slideUp({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});
272 $('#kiwi .controlbox').slideUp({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});
273 } else {
274 this.$el.find('.toolbar').slideUp(0);
275 $('#kiwi .controlbox').slideUp(0);
276 this.doLayout();
277 }
278 },
279
280 barsShow: function (instant) {
281 var that = this;
282
283 if (!instant) {
284 this.$el.find('.toolbar').slideDown({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});
285 $('#kiwi .controlbox').slideDown({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});
286 } else {
287 this.$el.find('.toolbar').slideDown(0);
288 $('#kiwi .controlbox').slideDown(0);
289 this.doLayout();
290 }
291 },
292
293
294 initSound: function () {
295 var that = this,
296 base_path = this.model.get('base_path');
297
298 $script(base_path + '/assets/libs/soundmanager2/soundmanager2-nodebug-jsmin.js', function() {
299 if (typeof soundManager === 'undefined')
300 return;
301
302 soundManager.setup({
303 url: base_path + '/assets/libs/soundmanager2/',
304 flashVersion: 9, // optional: shiny features (default = 8)// optional: ignore Flash where possible, use 100% HTML5 mode
305 preferFlash: true,
306
307 onready: function() {
308 that.sound_object = soundManager.createSound({
309 id: 'highlight',
310 url: base_path + '/assets/sound/highlight.mp3'
311 });
312 }
313 });
314 });
315 },
316
317
318 playSound: function (sound_id) {
319 if (!this.sound_object) return;
320
321 if (_kiwi.global.settings.get('mute_sounds'))
322 return;
ee2f0962 323
50ac472f 324 soundManager.play(sound_id);
d70c63d4
K
325 },
326
ee2f0962
D
327
328 showNotification: function(title, message) {
329 var icon = this.model.get('base_path') + '/assets/img/ico.png';
330
331 // Check if we have notification support
332 if (!window.webkitNotifications)
333 return;
334
335 if (this.has_focus)
336 return;
337
338 if (webkitNotifications.checkPermission() === 0){
339 window.webkitNotifications.createNotification(icon, title, message).show();
340 }
50ac472f 341 }
d70c63d4 342});