1
0
mirror of https://github.com/beestat/app.git synced 2025-05-24 02:14:03 -04:00
beestat/js/component/header.js

444 lines
12 KiB
JavaScript

/**
* Header component for all of the layers.
*
* @param {string} active_layer The currently active layer.
*/
beestat.component.header = function(active_layer) {
const self = this;
this.active_layer_ = active_layer;
beestat.dispatcher.addEventListener([
'view_announcements',
'cache.user'
], function() {
self.rerender();
});
beestat.component.apply(this, arguments);
};
beestat.extend(beestat.component.header, beestat.component);
beestat.component.header.prototype.rerender_on_resize_ = true;
/**
* Decorate.
*
* @param {rocket.Elements} parent
*/
beestat.component.header.prototype.decorate_ = function(parent) {
// Define base widths for every part of the header at different sizes.
const switcher_width = this.get_switcher_width_();
this.dimensions_ = {
'large': {
'logo': 160,
'navigation': 565,
'switcher': switcher_width,
'menu': 50,
'right_margin': 16
},
'medium': {
'logo': 160,
'navigation': 225,
'switcher': switcher_width,
'menu': 50,
'right_margin': 16
},
'small': {
'logo': 55,
'navigation': 225,
'switcher': switcher_width,
'menu': 50,
'right_margin': 16
}
};
/**
* Figure out which configuration will fit, preferring the largest first
* with the switcher, then without the switcher. Same pattern as we get
* smaller.
*/
if (
window.innerWidth >= (
this.dimensions_.large.logo +
this.dimensions_.large.navigation +
this.dimensions_.large.switcher +
this.dimensions_.large.menu +
this.dimensions_.large.right_margin
)
) {
this.dimension_ = 'large';
this.switcher_enabled_ = true;
} else if (
window.innerWidth >= (
this.dimensions_.large.logo +
this.dimensions_.large.navigation +
this.dimensions_.large.menu +
this.dimensions_.large.right_margin
)
) {
this.dimension_ = 'large';
this.switcher_enabled_ = false;
} else if (
window.innerWidth >= (
this.dimensions_.medium.logo +
this.dimensions_.medium.navigation +
this.dimensions_.medium.switcher +
this.dimensions_.medium.menu +
this.dimensions_.medium.right_margin
)
) {
this.dimension_ = 'medium';
this.switcher_enabled_ = true;
} else if (
window.innerWidth >= (
this.dimensions_.medium.logo +
this.dimensions_.medium.navigation +
this.dimensions_.medium.menu +
this.dimensions_.medium.right_margin
)
) {
this.dimension_ = 'medium';
this.switcher_enabled_ = false;
} else if (
window.innerWidth >= (
this.dimensions_.small.logo +
this.dimensions_.small.navigation +
this.dimensions_.small.switcher +
this.dimensions_.small.menu +
this.dimensions_.small.right_margin
)
) {
this.dimension_ = 'small';
this.switcher_enabled_ = true;
} else if (
window.innerWidth >= (
this.dimensions_.small.logo +
this.dimensions_.small.navigation +
this.dimensions_.small.menu +
this.dimensions_.small.right_margin
)
) {
this.dimension_ = 'small';
this.switcher_enabled_ = false;
} else {
this.dimension_ = 'small';
this.switcher_enabled_ = false;
}
// Decorate all the parts into a flex row.
const row = $.createElement('div').style({
'display': 'flex',
'align-items': 'center',
'flex-grow': '1',
'margin': '-' + (beestat.style.size.gutter / 2) + 'px 0 ' + (beestat.style.size.gutter / 4) + 'px -' + beestat.style.size.gutter + 'px'
});
this.decorate_logo_(row);
this.decorate_navigation_(row);
if (this.switcher_enabled_ === true) {
this.decorate_switcher_(row);
}
this.decorate_menu_(row);
parent.appendChild(row);
};
/**
* Decorate the logo.
*
* @param {rocket.Elements} parent
*/
beestat.component.header.prototype.decorate_logo_ = function(parent) {
const column = $.createElement('div')
.style({
'flex': '0 0 ' + this.dimensions_[this.dimension_].logo + 'px',
'padding': beestat.style.size.gutter + 'px 0 0 ' + beestat.style.size.gutter + 'px'
});
if (this.dimension_ === 'medium' || this.dimension_ === 'large') {
column.style({
'margin': '8px 0 4px 0'
});
(new beestat.component.logo(32)).render(column);
} else {
// column.style({'flex': '0 0 ' + dimensions[dimension].logo + 'px'});
const img = $.createElement('img')
.setAttribute('src', '/favicon.png')
.style({
'width': '32px',
'height': '32px',
'margin-top': '11px',
'margin-bottom': '6px'
});
column.appendChild(img);
}
parent.appendChild(column);
};
/**
* Decorate the navigation buttons.
*
* @param {rocket.Elements} parent
*/
beestat.component.header.prototype.decorate_navigation_ = function(parent) {
const self = this;
const pages = [
{
'layer': 'detail',
'text': 'Detail',
'icon': 'eye_circle'
},
{
'layer': 'analyze',
'text': 'Analyze',
'icon': 'home_search'
},
{
'layer': 'visualize',
'text': 'Visualize',
'icon': 'floor_plan'
},
{
'layer': 'compare',
'text': 'Compare',
'icon': 'earth'
},
{
'layer': 'air_quality',
'text': 'Air Quality',
'icon': 'weather_windy'
}
];
const column = $.createElement('div').style({
'padding': beestat.style.size.gutter + 'px 0 0 ' + beestat.style.size.gutter + 'px'
});
// If the swithcer is enabled, that takes up extra space. If not, this does.
if (this.switcher_enabled_ === true) {
column.style({
'flex': '0 0 ' + this.dimensions_[this.dimension_].navigation + 'px'
});
} else {
column.style({
'flex': '1'
});
}
const tile_group = new beestat.component.tile_group();
pages.forEach(function(page) {
const button = new beestat.component.tile()
.set_icon(page.icon)
.set_shadow(false)
.set_text_color(beestat.style.color.bluegray.dark);
if (self.dimension_ === 'large') {
button.set_text(page.text);
}
if (self.active_layer_ === page.layer) {
button
.set_background_color('#fff')
.set_text_color(beestat.style.color.bluegray.dark);
} else {
button
.set_text_color('#fff')
.set_background_hover_color('#fff')
.set_text_hover_color(beestat.style.color.bluegray.dark);
button.addEventListener('click', function() {
(new beestat.layer[page.layer]()).render();
});
}
tile_group.add_tile(button);
});
tile_group.render(column);
parent.appendChild(column);
};
/**
* Decorate the thermostat switcher.
*
* @param {rocket.Elements} parent
*/
beestat.component.header.prototype.decorate_switcher_ = function(parent) {
const column = $.createElement('div').style({
'flex': '1',
'padding': beestat.style.size.gutter + 'px 0 0 ' + beestat.style.size.gutter + 'px',
'text-align': 'right'
});
const change_thermostat_tile_group = new beestat.component.tile_group();
const sorted_thermostats = $.values(beestat.cache.thermostat)
.sort(function(a, b) {
return a.name > b.name;
});
sorted_thermostats.forEach(function(thermostat) {
if (thermostat.thermostat_id !== beestat.setting('thermostat_id')) {
const change_thermostat_tile = new beestat.component.tile.thermostat.switcher(thermostat.thermostat_id)
.set_size('medium')
.set_text_color('#fff')
.set_background_color(beestat.style.color.bluegray.base)
.set_background_hover_color('#fff')
.set_text_hover_color(beestat.style.color.bluegray.dark)
.addEventListener('click', function() {
beestat.setting('thermostat_id', thermostat.thermostat_id, function() {
window.location.reload();
});
});
change_thermostat_tile_group.add_tile(change_thermostat_tile);
}
});
change_thermostat_tile_group.render(column);
parent.appendChild(column);
};
/**
* Get the width of the thermostat switcher box. This could change due to any
* number of factors, but it should more or less work.
*
* @return {number} Width in pixels.
*/
beestat.component.header.prototype.get_switcher_width_ = function() {
let width = 0;
const sorted_thermostats = $.values(beestat.cache.thermostat)
.sort(function(a, b) {
return a.name > b.name;
});
sorted_thermostats.forEach(function(thermostat) {
if (thermostat.thermostat_id !== beestat.setting('thermostat_id')) {
const change_thermostat_tile = new beestat.component.tile.thermostat.switcher(
thermostat.thermostat_id
);
const text_dimensions = beestat.text_dimensions(
change_thermostat_tile.get_text_(),
13,
300
);
width += text_dimensions.width;
// Left/right padding on the button 8+8=16
width += 16;
// Left margin between buttons
width += 8;
}
});
// Left padding on the column
width += 16;
return width;
};
/**
* Decorate the menu.
*
* @param {rocket.Elements} parent
*/
beestat.component.header.prototype.decorate_menu_ = function(parent) {
// Menu
const last_read_announcement_id = beestat.setting('last_read_announcement_id');
const unread_announcement_count = Object.keys(beestat.cache.announcement)
.filter(function(announcement_id) {
return announcement_id > last_read_announcement_id;
}).length;
const column = $.createElement('div').style({
'flex': '0 0 ' + this.dimensions_[this.dimension_].menu + 'px',
'padding': beestat.style.size.gutter + 'px 0 0 ' + beestat.style.size.gutter + 'px',
'text-align': 'right'
});
const menu = new beestat.component.menu();
if (unread_announcement_count > 0) {
menu
.set_bubble_text(unread_announcement_count)
.set_bubble_color(beestat.style.color.red.base);
}
menu.render(column);
if (Object.keys(beestat.cache.ecobee_thermostat).length > 1) {
menu.add_menu_item(new beestat.component.menu_item()
.set_text('Switch Thermostat')
.set_icon('swap_horizontal')
.set_callback(function() {
(new beestat.component.modal.change_thermostat()).render();
}));
}
if (window.is_demo === false) {
menu.add_menu_item(new beestat.component.menu_item()
.set_text('Support beestat')
.set_icon('heart')
.set_callback(function() {
new beestat.layer.contribute().render();
}));
}
const announcements_menu_item = new beestat.component.menu_item()
.set_text('Announcements')
.set_icon('bullhorn')
.set_callback(function() {
(new beestat.component.modal.announcements()).render();
});
if (unread_announcement_count > 0) {
announcements_menu_item
.set_bubble_text(unread_announcement_count)
.set_bubble_color(beestat.style.color.red.base);
}
menu.add_menu_item(announcements_menu_item);
menu.add_menu_item(new beestat.component.menu_item()
.set_text('Download Data')
.set_icon('download')
.set_callback(function() {
(new beestat.component.modal.download_data()).render();
}));
menu.add_menu_item(new beestat.component.menu_item()
.set_text('Settings')
.set_icon('cog')
.set_callback(function() {
(new beestat.layer.settings()).render();
}));
if (beestat.platform() === 'ios' || beestat.platform() === 'android') {
menu.add_menu_item(new beestat.component.menu_item()
.set_text('Open Ecobee App')
.set_icon('open_in_app')
.set_callback(function() {
window.location.replace('ecobee://beestat');
}));
}
menu.add_menu_item(new beestat.component.menu_item()
.set_text('Log Out')
.set_icon('exit_to_app')
.set_callback(function() {
window.location.replace(
window.location.href +
'api/?resource=user&method=log_out&arguments={}&api_key=' +
window.beestat_api_key_local
);
}));
parent.appendChild(column);
};