mirror of
https://github.com/DigiLive/mushroom-strategy.git
synced 2025-08-04 20:14:28 +02:00
Optimize Home View
Changed code to be compatible with changed imports. Also, the code is optimized and more concise.
This commit is contained in:
@@ -67,224 +67,194 @@ class HomeView extends AbstractView {
|
|||||||
return homeViewCards;
|
return homeViewCards;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chips.length) {
|
if (chipsSection) {
|
||||||
// TODO: Create the Chip card at this.#createChips()
|
homeViewCards.push(chipsSection);
|
||||||
homeViewCards.push({
|
}
|
||||||
type: "custom:mushroom-chips-card",
|
|
||||||
alignment: "center",
|
|
||||||
chips: chips,
|
|
||||||
} as ChipsCardConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (personCards.length) {
|
if (personsSection) {
|
||||||
// TODO: Create the stack at this.#createPersonCards()
|
homeViewCards.push(personsSection);
|
||||||
homeViewCards.push({
|
}
|
||||||
type: "horizontal-stack",
|
|
||||||
cards: personCards,
|
|
||||||
} as StackCardConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(Helper.strategyOptions.home_view.hidden as string[]).includes("greeting")) {
|
// Create the greeting section.
|
||||||
homeViewCards.push({
|
if (!('greeting' in Registry.strategyOptions.home_view.hidden)) {
|
||||||
type: "custom:mushroom-template-card",
|
|
||||||
primary:
|
|
||||||
`{% set time = now().hour %} {% if (time >= 18) %} ${Helper.customLocalize("generic.good_evening")},{{user}}!
|
|
||||||
{% elif (time >= 12) %} ${Helper.customLocalize("generic.good_afternoon")}, {{user}}!
|
|
||||||
{% elif (time >= 5) %} ${Helper.customLocalize("generic.good_morning")}, {{user}}!
|
|
||||||
{% else %} ${Helper.customLocalize("generic.hello")}, {{user}}! {% endif %}`,
|
|
||||||
icon: "mdi:hand-wave",
|
|
||||||
icon_color: "orange",
|
|
||||||
tap_action: {
|
|
||||||
action: "none",
|
|
||||||
} as ActionConfig,
|
|
||||||
double_tap_action: {
|
|
||||||
action: "none",
|
|
||||||
} as ActionConfig,
|
|
||||||
hold_action: {
|
|
||||||
action: "none",
|
|
||||||
} as ActionConfig,
|
|
||||||
} as TemplateCardConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add quick access cards.
|
|
||||||
if (options.quick_access_cards) {
|
|
||||||
homeViewCards.push(...options.quick_access_cards);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add area cards.
|
|
||||||
homeViewCards.push({
|
homeViewCards.push({
|
||||||
type: "vertical-stack",
|
type: 'custom:mushroom-template-card',
|
||||||
cards: areaCards,
|
primary: `{% set time = now().hour %}
|
||||||
} as StackCardConfig);
|
{% if (time >= 18) %}
|
||||||
|
${localize('generic.good_evening')},{{user}}!
|
||||||
|
{% elif (time >= 12) %}
|
||||||
|
${localize('generic.good_afternoon')}, {{user}}!
|
||||||
|
{% elif (time >= 6) %}
|
||||||
|
${localize('generic.good_morning')}, {{user}}!
|
||||||
|
{% else %}
|
||||||
|
${localize('generic.hello')}, {{user}}! {% endif %}`,
|
||||||
|
icon: 'mdi:hand-wave',
|
||||||
|
icon_color: 'orange',
|
||||||
|
tap_action: {
|
||||||
|
action: 'none',
|
||||||
|
} as ActionConfig,
|
||||||
|
double_tap_action: {
|
||||||
|
action: 'none',
|
||||||
|
} as ActionConfig,
|
||||||
|
hold_action: {
|
||||||
|
action: 'none',
|
||||||
|
} as ActionConfig,
|
||||||
|
} as TemplateCardConfig);
|
||||||
|
}
|
||||||
|
|
||||||
// Add custom cards.
|
if (Registry.strategyOptions.quick_access_cards) {
|
||||||
if (options.extra_cards) {
|
homeViewCards.push(...Registry.strategyOptions.quick_access_cards);
|
||||||
homeViewCards.push(...options.extra_cards);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return homeViewCards;
|
if (areasSection) {
|
||||||
});
|
homeViewCards.push(areasSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Registry.strategyOptions.extra_cards) {
|
||||||
|
homeViewCards.push(...Registry.strategyOptions.extra_cards);
|
||||||
|
}
|
||||||
|
|
||||||
|
return homeViewCards;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the chips to include in the view.
|
* Create a chip section to include in the view
|
||||||
*
|
*
|
||||||
* @returns {Promise<LovelaceChipConfig[]>} Promise a chip array.
|
* If the section is marked as hidden in the strategy option, then the section is not created.
|
||||||
*/
|
*/
|
||||||
async #createChips(): Promise<LovelaceChipConfig[]> {
|
private async createChipsSection(): Promise<ChipsCardConfig | undefined> {
|
||||||
if ((Helper.strategyOptions.home_view.hidden as string[]).includes("chips")) {
|
if ((Registry.strategyOptions.home_view.hidden as string[]).includes('chips')) {
|
||||||
// The Chip section is hidden.
|
// The section is hidden.
|
||||||
|
return;
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const chips: LovelaceChipConfig[] = [];
|
const chipConfigurations: LovelaceChipConfig[] = [];
|
||||||
const chipOptions = Helper.strategyOptions.chips;
|
const exposedChips = Registry.getExposedNames('chip');
|
||||||
|
const areaIds = Registry.areas.map((area) => area.area_id ?? '');
|
||||||
|
|
||||||
// TODO: Get domains from config.
|
let Chip;
|
||||||
const exposedChips: supportedChips[] = ["light", "fan", "cover", "switch", "climate"];
|
|
||||||
// Create a list of area-ids, used for switching all devices via chips
|
|
||||||
const areaIds = Helper.areas.map(area => area.area_id ?? "");
|
|
||||||
|
|
||||||
let chipModule;
|
|
||||||
|
|
||||||
// Weather chip.
|
// Weather chip.
|
||||||
const weatherEntityId = chipOptions.weather_entity ?? Helper.entities.find(
|
// FIXME: It's not possible to hide the weather chip in the configuration.
|
||||||
(entity) => entity.entity_id.startsWith("weather.") && entity.disabled_by === null && entity.hidden_by === null,
|
const weatherEntityId =
|
||||||
)?.entity_id;
|
Registry.strategyOptions.chips.weather_entity === 'auto'
|
||||||
|
? Registry.entities.find((entity) => entity.entity_id.startsWith('weather.'))?.entity_id
|
||||||
|
: Registry.strategyOptions.chips.weather_entity;
|
||||||
|
|
||||||
if (weatherEntityId) {
|
if (weatherEntityId) {
|
||||||
try {
|
try {
|
||||||
chipModule = await import("../chips/WeatherChip");
|
Chip = (await import('../chips/WeatherChip')).default;
|
||||||
const weatherChip = new chipModule.WeatherChip(weatherEntityId);
|
const weatherChip = new Chip(weatherEntityId);
|
||||||
|
|
||||||
chips.push(weatherChip.getChip());
|
chipConfigurations.push(weatherChip.getChipConfiguration());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Helper.logError("An error occurred while creating the weather chip!", e);
|
logMessage(lvlError, 'Error creating the configuration for chip weather!', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Numeric chips.
|
// Numeric chips.
|
||||||
for (let chipType of exposedChips) {
|
for (const chipName of exposedChips) {
|
||||||
if (chipType !== "weather" && (chipOptions?.[(`${chipType}_count`)] ?? true)) {
|
if (!isSupportedChip(chipName)) {
|
||||||
const className = Helper.sanitizeClassName(chipType + "Chip");
|
continue;
|
||||||
try {
|
}
|
||||||
chipModule = await import((`../chips/${className}`));
|
|
||||||
const chip = new chipModule[className]();
|
|
||||||
|
|
||||||
chip.setTapActionTarget({area_id: areaIds});
|
const moduleName = sanitizeClassName(chipName + 'Chip');
|
||||||
chips.push(chip.getChip());
|
|
||||||
} catch (e) {
|
try {
|
||||||
Helper.logError(`An error occurred while creating the ${chipType} chip!`, e);
|
Chip = (await import(`../chips/${moduleName}`)).default;
|
||||||
}
|
const currentChip = new Chip();
|
||||||
|
|
||||||
|
currentChip.setTapActionTarget({ area_id: areaIds });
|
||||||
|
chipConfigurations.push(currentChip.getChipConfiguration());
|
||||||
|
} catch (e) {
|
||||||
|
logMessage(lvlError, `Error creating the configuration for chip ${chipName}!`, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extra chips.
|
// Add extra chips.
|
||||||
if (chipOptions?.extra_chips) {
|
if (Registry.strategyOptions.chips?.extra_chips) {
|
||||||
chips.push(...chipOptions.extra_chips);
|
chipConfigurations.push(...Registry.strategyOptions.chips.extra_chips);
|
||||||
}
|
}
|
||||||
|
|
||||||
return chips;
|
return {
|
||||||
|
type: 'custom:mushroom-chips-card',
|
||||||
|
alignment: 'center',
|
||||||
|
chips: chipConfigurations,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the person cards to include in the view.
|
* Create a persons section to include in the view.
|
||||||
*
|
*
|
||||||
* @returns {PersonCardConfig[]} A Person Card array.
|
* If the section is marked as hidden in the strategy option, then the section is not created.
|
||||||
*/
|
*/
|
||||||
#createPersonCards(): PersonCardConfig[] {
|
private async createPersonsSection(): Promise<StackCardConfig | undefined> {
|
||||||
if ((Helper.strategyOptions.home_view.hidden as string[]).includes("persons")) {
|
if ((Registry.strategyOptions.home_view.hidden as string[]).includes('persons')) {
|
||||||
// The Person section is hidden.
|
// The section is hidden.
|
||||||
|
|
||||||
return [];
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cards: PersonCardConfig[] = [];
|
const cardConfigurations: PersonCardConfig[] = [];
|
||||||
|
const PersonCard = (await import('../cards/PersonCard')).default;
|
||||||
|
|
||||||
import("../cards/PersonCard").then(personModule => {
|
cardConfigurations.push(
|
||||||
for (const person of Helper.entities.filter((entity) => {
|
...Registry.entities
|
||||||
return entity.entity_id.startsWith("person.")
|
.filter((entity) => entity.entity_id.startsWith('person.'))
|
||||||
&& entity.hidden_by == null
|
.map((person) => new PersonCard(person).getCard()),
|
||||||
&& entity.disabled_by == null;
|
);
|
||||||
})) {
|
|
||||||
cards.push(new personModule.PersonCard(person).getCard());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return cards;
|
// FIXME: The columns are too narrow when having many persons.
|
||||||
|
return {
|
||||||
|
type: 'vertical-stack',
|
||||||
|
cards: Registry.stackHorizontal(cardConfigurations, 2),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the area cards to include in the view.
|
* Create the area cards to include in the view.
|
||||||
*
|
*
|
||||||
* Area cards are grouped into two areas per row.
|
* Area cards are grouped into two areas per row.
|
||||||
*
|
* If the section is marked as hidden in the strategy option, then the section is not created.
|
||||||
* @returns {Promise<(TitleCardConfig | StackCardConfig)[]>} Promise an Area Card Section.
|
|
||||||
*/
|
*/
|
||||||
async #createAreaSection(): Promise<(TitleCardConfig | StackCardConfig)[]> {
|
private async createAreasSection(): Promise<StackCardConfig | undefined> {
|
||||||
if ((Helper.strategyOptions.home_view.hidden as string[]).includes("areas")) {
|
if ((Registry.strategyOptions.home_view.hidden as string[]).includes('areas')) {
|
||||||
// Areas section is hidden.
|
// Areas section is hidden.
|
||||||
|
|
||||||
return [];
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupedCards: (TitleCardConfig | StackCardConfig)[] = [];
|
const cardConfigurations: (TemplateCardConfig | AreaCardConfig)[] = [];
|
||||||
|
|
||||||
let areaCards: (TemplateCardConfig | AreaCardConfig)[] = [];
|
for (const area of Registry.areas) {
|
||||||
|
const moduleName =
|
||||||
|
Registry.strategyOptions.areas[area.area_id]?.type ?? Registry.strategyOptions.areas['_']?.type ?? 'default';
|
||||||
|
|
||||||
if (!(Helper.strategyOptions.home_view.hidden as string[]).includes("areasTitle")) {
|
let AreaCard;
|
||||||
groupedCards.push({
|
|
||||||
type: "custom:mushroom-title-card",
|
|
||||||
title: Helper.customLocalize("generic.areas"),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [i, area] of Helper.areas.entries()) {
|
|
||||||
type ModuleType = typeof import("../cards/AreaCard");
|
|
||||||
|
|
||||||
let module: ModuleType;
|
|
||||||
let moduleName =
|
|
||||||
Helper.strategyOptions.areas[area.area_id]?.type ??
|
|
||||||
Helper.strategyOptions.areas["_"]?.type ??
|
|
||||||
"default";
|
|
||||||
|
|
||||||
// Load module by type in strategy options.
|
|
||||||
try {
|
try {
|
||||||
module = await import((`../cards/${moduleName}`));
|
AreaCard = (await import(`../cards/${moduleName}`)).default;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Fallback to the default strategy card.
|
// Fallback to the default strategy card.
|
||||||
module = await import("../cards/AreaCard");
|
AreaCard = (await import('../cards/AreaCard')).default;
|
||||||
|
|
||||||
if (Helper.strategyOptions.debug && moduleName !== "default") {
|
if (Registry.strategyOptions.debug && moduleName !== 'default') {
|
||||||
console.error(e);
|
logMessage(lvlError, `Error importing ${moduleName}: card!`, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a card for the area.
|
cardConfigurations.push(new AreaCard(area).getCard());
|
||||||
if (!Helper.strategyOptions.areas[area.area_id as string]?.hidden) {
|
|
||||||
let options = {
|
|
||||||
...Helper.strategyOptions.areas["_"],
|
|
||||||
...Helper.strategyOptions.areas[area.area_id],
|
|
||||||
};
|
|
||||||
|
|
||||||
areaCards.push(new module.AreaCard(area, options).getCard());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Horizontally group every two area cards if all cards are created.
|
|
||||||
if (i === Helper.areas.length - 1) {
|
|
||||||
for (let i = 0; i < areaCards.length; i += 2) {
|
|
||||||
groupedCards.push({
|
|
||||||
type: "horizontal-stack",
|
|
||||||
cards: areaCards.slice(i, i + 2),
|
|
||||||
} as StackCardConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return groupedCards;
|
// FIXME: The columns are too narrow when having HASS area cards.
|
||||||
|
return {
|
||||||
|
type: 'vertical-stack',
|
||||||
|
title: !(Registry.strategyOptions.home_view.hidden as HomeViewSections[]).includes('areasTitle')
|
||||||
|
? localize('generic.areas')
|
||||||
|
: undefined,
|
||||||
|
cards: Registry.stackHorizontal(cardConfigurations, 2),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {HomeView};
|
export default HomeView;
|
||||||
|
Reference in New Issue
Block a user