Default window_title if not set
[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
68 if (!theme_name) theme_name = _kiwi.global.settings.get('theme');
69
70 // Clear any current theme
71 this.$el.removeClass(function (i, css) {
72 return (css.match(/\btheme_\S+/g) || []).join(' ');
73 });
74
75 // Apply the new theme
76 this.$el.addClass('theme_' + (theme_name || 'relaxed'));
77 },
78
79
80 setTabLayout: function (layout_style) {
81 // If called by the settings callback, get the correct new_value
82 if (layout_style === _kiwi.global.settings) {
83 layout_style = arguments[1];
84 }
ee2f0962 85
50ac472f
D
86 if (layout_style == 'list') {
87 this.$el.addClass('chanlist_treeview');
88 } else {
89 this.$el.removeClass('chanlist_treeview');
90 }
ee2f0962 91
50ac472f
D
92 this.doLayout();
93 },
94
95
96 displayTimestamps: function (show_timestamps) {
97 // If called by the settings callback, get the correct new_value
98 if (show_timestamps === _kiwi.global.settings) {
99 show_timestamps = arguments[1];
100 }
101
102 if (show_timestamps) {
103 this.$el.addClass('timestamps');
104 } else {
105 this.$el.removeClass('timestamps');
106 }
107 },
108
109
110 // Globally shift focus to the command input box on a keypress
111 setKeyFocus: function (ev) {
112 // If we're copying text, don't shift focus
113 if (ev.ctrlKey || ev.altKey || ev.metaKey) {
114 return;
115 }
116
117 // If we're typing into an input box somewhere, ignore
118 if ((ev.target.tagName.toLowerCase() === 'input') || (ev.target.tagName.toLowerCase() === 'textarea') || $(ev.target).attr('contenteditable')) {
119 return;
120 }
121
122 $('#kiwi .controlbox .inp').focus();
123 },
124
125
126 doLayout: function () {
127 var el_kiwi = this.$el;
783fcf1f
D
128 var el_panels = this.elements.panels;
129 var el_memberlists = this.elements.memberlists;
130 var el_toolbar = this.elements.toolbar;
131 var el_controlbox = this.elements.controlbox;
132 var el_resize_handle = this.elements.resize_handle;
50ac472f 133
9aa4b87d
D
134 if (!el_kiwi.is(':visible')) {
135 return;
136 }
137
50ac472f
D
138 var css_heights = {
139 top: el_toolbar.outerHeight(true),
140 bottom: el_controlbox.outerHeight(true)
141 };
142
143
144 // If any elements are not visible, full size the panals instead
145 if (!el_toolbar.is(':visible')) {
146 css_heights.top = 0;
147 }
148
149 if (!el_controlbox.is(':visible')) {
150 css_heights.bottom = 0;
151 }
152
153 // Apply the CSS sizes
154 el_panels.css(css_heights);
155 el_memberlists.css(css_heights);
156 el_resize_handle.css(css_heights);
157
158 // If we have channel tabs on the side, adjust the height
159 if (el_kiwi.hasClass('chanlist_treeview')) {
160 this.$el.find('.tabs', el_kiwi).css(css_heights);
161 }
162
163 // Determine if we have a narrow window (mobile/tablet/or even small desktop window)
164 if (el_kiwi.outerWidth() < 400) {
165 el_kiwi.addClass('narrow');
166 } else {
167 el_kiwi.removeClass('narrow');
168 }
169
170 // Set the panels width depending on the memberlist visibility
171 if (el_memberlists.css('display') != 'none') {
172 // Panels to the side of the memberlist
173 el_panels.css('right', el_memberlists.outerWidth(true));
174 // The resize handle sits overlapping the panels and memberlist
175 el_resize_handle.css('left', el_memberlists.position().left - (el_resize_handle.outerWidth(true) / 2));
176 } else {
177 // Memberlist is hidden so panels to the right edge
178 el_panels.css('right', 0);
179 // And move the handle just out of sight to the right
180 el_resize_handle.css('left', el_panels.outerWidth(true));
181 }
182
183 var input_wrap_width = parseInt($('#kiwi .controlbox .input_tools').outerWidth());
184 el_controlbox.find('.input_wrap').css('right', input_wrap_width + 7);
185 },
186
187
188 alertWindow: function (title) {
189 if (!this.alertWindowTimer) {
190 this.alertWindowTimer = new (function () {
191 var that = this;
192 var tmr;
193 var has_focus = true;
194 var state = 0;
73b7cc44 195 var default_title = _kiwi.app.server_settings.client.window_title || 'Kiwi IRC';
50ac472f
D
196 var title = 'Kiwi IRC';
197
198 this.setTitle = function (new_title) {
199 new_title = new_title || default_title;
200 window.document.title = new_title;
201 return new_title;
202 };
203
204 this.start = function (new_title) {
205 // Don't alert if we already have focus
206 if (has_focus) return;
207
208 title = new_title;
209 if (tmr) return;
210 tmr = setInterval(this.update, 1000);
211 };
212
213 this.stop = function () {
214 // Stop the timer and clear the title
215 if (tmr) clearInterval(tmr);
216 tmr = null;
217 this.setTitle();
218
219 // Some browsers don't always update the last title correctly
220 // Wait a few seconds and then reset
221 setTimeout(this.reset, 2000);
222 };
223
224 this.reset = function () {
225 if (tmr) return;
226 that.setTitle();
227 };
228
229
230 this.update = function () {
231 if (state === 0) {
232 that.setTitle(title);
233 state = 1;
234 } else {
235 that.setTitle();
236 state = 0;
237 }
238 };
239
240 $(window).focus(function (event) {
241 has_focus = true;
242 that.stop();
243
244 // Some browsers don't always update the last title correctly
245 // Wait a few seconds and then reset
246 setTimeout(that.reset, 2000);
247 });
248
249 $(window).blur(function (event) {
250 has_focus = false;
251 });
252 })();
253 }
254
255 this.alertWindowTimer.start(title);
256 },
257
258
259 barsHide: function (instant) {
260 var that = this;
261
262 if (!instant) {
263 this.$el.find('.toolbar').slideUp({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});
264 $('#kiwi .controlbox').slideUp({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});
265 } else {
266 this.$el.find('.toolbar').slideUp(0);
267 $('#kiwi .controlbox').slideUp(0);
268 this.doLayout();
269 }
270 },
271
272 barsShow: function (instant) {
273 var that = this;
274
275 if (!instant) {
276 this.$el.find('.toolbar').slideDown({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});
277 $('#kiwi .controlbox').slideDown({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});
278 } else {
279 this.$el.find('.toolbar').slideDown(0);
280 $('#kiwi .controlbox').slideDown(0);
281 this.doLayout();
282 }
283 },
284
285
286 initSound: function () {
287 var that = this,
288 base_path = this.model.get('base_path');
289
290 $script(base_path + '/assets/libs/soundmanager2/soundmanager2-nodebug-jsmin.js', function() {
291 if (typeof soundManager === 'undefined')
292 return;
293
294 soundManager.setup({
295 url: base_path + '/assets/libs/soundmanager2/',
296 flashVersion: 9, // optional: shiny features (default = 8)// optional: ignore Flash where possible, use 100% HTML5 mode
297 preferFlash: true,
298
299 onready: function() {
300 that.sound_object = soundManager.createSound({
301 id: 'highlight',
302 url: base_path + '/assets/sound/highlight.mp3'
303 });
304 }
305 });
306 });
307 },
308
309
310 playSound: function (sound_id) {
311 if (!this.sound_object) return;
312
313 if (_kiwi.global.settings.get('mute_sounds'))
314 return;
ee2f0962 315
50ac472f 316 soundManager.play(sound_id);
d70c63d4
K
317 },
318
ee2f0962
D
319
320 showNotification: function(title, message) {
321 var icon = this.model.get('base_path') + '/assets/img/ico.png';
322
323 // Check if we have notification support
324 if (!window.webkitNotifications)
325 return;
326
327 if (this.has_focus)
328 return;
329
330 if (webkitNotifications.checkPermission() === 0){
331 window.webkitNotifications.createNotification(icon, title, message).show();
332 }
50ac472f 333 }
d70c63d4 334});