Skip to content

Commit

Permalink
Climate card fixes + Actions fix + More
Browse files Browse the repository at this point in the history
- [x] Reverted a breaking change from a previous beta, where the pop-up blurred backdrop was disabled by default. But this is still a breaking change, now the default backdrop is darker without any blur. This can be changed in the editor, just go to your first pop-up on your view, then go to Styling options > Pop-up styling then change `Optional - Backdrop blur` to 10 (it was the previous value). In YAML just add `backdrop_blur: 10`. If you missed it, I changed that because the blur can slow down pop-ups on some older devices.

- [x] Changing temperature values in a climate card is now correctly synched if there was a change elsewhere. #942
- [x] New toggle in the climate card editor for users who wants to have a constant background color when the entity is `on`. #933
- [x] Buttons with a white light (or without RGB) are now more visible on bright/light themes. I also improved the overall color system for better color handling. It is also possible to change the color with the `--bubble-light-color` variable. #692
- [x] The climate card now correctly support `entity_picture` for the icon. #939
- [x] Actions now have a new toggle in the editor when set to Call service, this way it will automatically match the card/sub-button entity if defined. This is a breaking change for users of the previous beta who removed the entity_id completely, I had to change this because it was causing an issue in #935.
  • Loading branch information
Clooos authored Nov 21, 2024
1 parent 6f0734e commit 2d017ca
Show file tree
Hide file tree
Showing 14 changed files with 362 additions and 164 deletions.
95 changes: 65 additions & 30 deletions dist/bubble-card.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/bubble-pop-up-fix.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 22 additions & 22 deletions src/bubble-pop-up-fix.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
function hideElementsUntilBubbleCard() {
const selector = "body";
const root = document.querySelector(selector);
let bubbleCard = customElements.get("bubble-card");
// function hideElementsUntilBubbleCard() {
// const selector = "body";
// const root = document.querySelector(selector);
// let bubbleCard = customElements.get("bubble-card");

const intervalId = setInterval(function() {
bubbleCard = customElements.get("bubble-card");
// const intervalId = setInterval(function() {
// bubbleCard = customElements.get("bubble-card");

if (bubbleCard) {
clearInterval(intervalId);
root.style.transition = "opacity 0.5s";
root.style.opacity = "1";
} else {
root.style.opacity = "0";
}
}, 0);
// if (bubbleCard) {
// clearInterval(intervalId);
// root.style.transition = "opacity 0.5s";
// root.style.opacity = "1";
// } else {
// root.style.opacity = "0";
// }
// }, 0);

setTimeout(function() {
clearInterval(intervalId);
root.style.transition = "opacity 0.5s";
root.style.opacity = "1";
}, 1500);
}
// setTimeout(function() {
// clearInterval(intervalId);
// root.style.transition = "opacity 0.5s";
// root.style.opacity = "1";
// }, 1500);
// }

hideElementsUntilBubbleCard();
// hideElementsUntilBubbleCard();

console.info(
`%c Bubble Card %c Pop-up fix `,
`%c Bubble Card %c Pop-up fix - Deprecated, please remove it`,
'background-color: #555;color: #fff;padding: 3px 2px 3px 3px;border-radius: 14px 0 0 14px;font-family: DejaVu Sans,Verdana,Geneva,sans-serif;text-shadow: 0 1px 0 rgba(1, 1, 1, 0.3)',
'background-color: #506eac;color: #fff;padding: 3px 3px 3px 2px;border-radius: 0 14px 14px 0;font-family: DejaVu Sans,Verdana,Geneva,sans-serif;text-shadow: 0 1px 0 rgba(1, 1, 1, 0.3)'
);
19 changes: 1 addition & 18 deletions src/cards/button/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default `
background-color: var(--bubble-button-background-color);
opacity: .5;
border-radius: var(--bubble-button-border-radius, var(--bubble-border-radius, 32px));
transition: color .2s;
}
.bubble-range-fill {
position: absolute;
Expand Down Expand Up @@ -83,24 +84,6 @@ export default `
position: relative;
cursor: pointer;
}
.bubble-icon-container::after {
content: '';
background-color: currentColor;
position: absolute;
display: block;
width: 100%;
height: 100%;
transition: all 1s;
left: 0;
right: 0;
opacity: 0;
}
.is-light.is-on .bubble-icon-container::after {
opacity: 0.2;
}
.is-unavailable.is-light .bubble-icon-container::after {
opacity: 0;
}
.bubble-icon {
display: flex;
Expand Down
48 changes: 38 additions & 10 deletions src/cards/climate/changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,45 @@ import {

export function changeIcon(context) {
const isOn = isStateOn(context);
const icon = getIcon(context);
const state = getState(context);
const stateObj = context._hass.states[context.config.entity];
const newIcon = getIcon(context);
const newImage = getImage(context);

const currentImage = context.elements.image.style.backgroundImage;
const currentIcon = context.elements.icon.icon;
const currentIconColor = context.elements.icon.style.color;

if (icon !== '') {
context.elements.icon.icon = icon;
context.elements.icon.style.color = isOn ? getClimateColor(stateObj) : 'inherit';
context.elements.icon.style.display = '';
if (newImage !== '') {
const newBackgroundImage = 'url(' + newImage + ')';
if (currentImage !== newBackgroundImage) {
context.elements.image.style.backgroundImage = newBackgroundImage;
}
if (context.elements.icon.style.display !== 'none') {
context.elements.icon.style.display = 'none';
}
if (context.elements.image.style.display !== '') {
context.elements.image.style.display = '';
}
} else if (newIcon !== '') {
if (currentIcon !== newIcon) {
context.elements.icon.icon = newIcon;
}
const newColor = isOn ? `var(--bubble-icon-background-color, ${getClimateColor(context)})` : 'inherit';
if (currentIconColor !== newColor) {
context.elements.icon.style.color = newColor;
}
if (context.elements.icon.style.display !== '') {
context.elements.icon.style.display = '';
}
if (context.elements.image.style.display !== 'none') {
context.elements.image.style.display = 'none';
}
} else {
context.elements.icon.style.display = 'none';
if (context.elements.icon.style.display !== 'none') {
context.elements.icon.style.display = 'none';
}
if (context.elements.image.style.display !== 'none') {
context.elements.image.style.display = 'none';
}
}
}

Expand Down Expand Up @@ -123,14 +152,13 @@ export function changeStyle(context) {
initializesubButtonIcon(context);
setLayout(context);

const stateObj = context._hass.states[context.config.entity];
const state = getState(context);
const isOn = state !== "off" && state !== "unknown";

if (context.previousState !== state) {
context.previousState = state;
const element = context.elements.colorBackground;
element.style.backgroundColor = `var(--bubble-climate-background-color, ${getClimateColor(stateObj)})`;
element.style.backgroundColor = `var(--bubble-climate-background-color, ${getClimateColor(context)})`;
}

const cardLayout = context.config.card_layout;
Expand Down
33 changes: 15 additions & 18 deletions src/cards/climate/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ export function createStructure(context) {
context.elements.name = createElement('div', 'bubble-name');
context.elements.state = createElement('div', 'bubble-state');
context.elements.icon = createElement('ha-icon', 'bubble-icon');
context.elements.image = createElement('div', 'bubble-entity-picture entity-picture');
context.elements.colorBackground = createElement('div', 'bubble-color-background');
context.elements.style = createElement('style');
context.elements.customStyle = createElement('style');
context.elements.style.innerText = styles;

context.elements.iconContainer.appendChild(context.elements.icon);
context.elements.iconContainer.appendChild(context.elements.image);
context.elements.nameContainer.appendChild(context.elements.name);
context.elements.nameContainer.appendChild(context.elements.state);

Expand Down Expand Up @@ -61,6 +63,7 @@ export function createStructure(context) {

let tempTimeout;
let currentTemp = parseFloat(getAttribute(context, attribute)) || 0;
let lastSyncedTemp = currentTemp;

function updateTempDisplay(newTemp) {
if (attribute === 'temperature') {
Expand All @@ -72,7 +75,17 @@ export function createStructure(context) {
}
}

function syncTemp() {
const latestTemp = parseFloat(getAttribute(context, attribute)) || 0;
if (latestTemp !== lastSyncedTemp) {
currentTemp = latestTemp;
lastSyncedTemp = latestTemp;
}
}

function callSetTemperature() {
syncTemp();

const serviceData = { entity_id: context.config.entity };

if (attribute === 'target_temp_low') {
Expand All @@ -89,40 +102,24 @@ export function createStructure(context) {
}

minusButton.addEventListener('click', () => {
syncTemp();
currentTemp = parseFloat((currentTemp - step).toFixed(1));
updateTempDisplay(currentTemp);

clearTimeout(tempTimeout);

tempTimeout = setTimeout(callSetTemperature, 700);
});

plusButton.addEventListener('click', () => {
syncTemp();
currentTemp = parseFloat((currentTemp + step).toFixed(1));
updateTempDisplay(currentTemp);

clearTimeout(tempTimeout);

tempTimeout = setTimeout(callSetTemperature, 700);
});
}

function adjustTemperature(attribute, newTemp) {
const serviceData = { entity_id: context.config.entity };

if (attribute === 'target_temp_low') {
serviceData.target_temp_low = newTemp;
serviceData.target_temp_high = getAttribute(context, 'target_temp_high');
} else if (attribute === 'target_temp_high') {
serviceData.target_temp_high = newTemp;
serviceData.target_temp_low = getAttribute(context, 'target_temp_low');
} else {
serviceData[attribute] = newTemp;
}

context._hass.callService('climate', 'set_temperature', serviceData);
}

const hasTargetTempLow = state?.attributes?.target_temp_low !== undefined;
const hasTargetTempHigh = state?.attributes?.target_temp_high !== undefined;
const hasTemperature = state?.attributes?.temperature !== undefined;
Expand Down
46 changes: 20 additions & 26 deletions src/cards/climate/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,42 @@ import {
isEntityType
} from "../../tools/utils.ts";

export function getClimateColor(stateObj) {
export function getClimateColor(context) {
let overlayColor = '';

const stateObj = context._hass.states[context.config.entity];
const currentTemp = stateObj.attributes.current_temperature;
const hvacAction = stateObj.attributes.hvac_action;
const state = stateObj.state;

const isHeating = hvacAction === 'heating';
const isCooling = hvacAction === 'cooling';
const isHeating = hvacAction === 'heating' || (state === "heat" && context.config.state_color);
const isCooling = hvacAction === 'cooling' || (state === "cool" && context.config.state_color);
const isOn = state !== "off" && state !== "unknown";

switch (state) {
case "heat":
overlayColor = isHeating
? 'var(--state-climate-heat-color, var(--state-climate-active-color, var(--state-active-color)))'
: '';
case "fan_only":
overlayColor = 'var(--bubble-state-climate-fan-only-color, var(--state-climate-fan-only-color, var(--state-climate-active-color, var(--state-active-color))))';
break;
case "cool":
overlayColor = isCooling
? 'var(--state-climate-cool-color, var(--state-climate-active-color, var(--state-active-color)))'
: '';
case "dry":
overlayColor = 'var(--bubble-state-climate-dry-color, var(--state-climate-dry-color, var(--state-climate-active-color, var(--state-active-color))))';
break;
case "heat_cool":
default:
if (isCooling) {
overlayColor = 'var(--state-climate-cool-color, var(--state-climate-active-color, var(--state-active-color)))';
overlayColor = 'var(--bubble-state-climate-cool-color, var(--state-climate-cool-color, var(--state-climate-active-color, var(--state-active-color))))';
} else if (isHeating) {
overlayColor = 'var(--state-climate-heat-color, var(--state-climate-active-color, var(--state-active-color)))';
overlayColor = 'var(--bubble-state-climate-heat-color, var(--state-climate-heat-color, var(--state-climate-active-color, var(--state-active-color))))';
} else if (isOn && context.config.state_color) {
if (state === 'auto') {
overlayColor = 'var(--bubble-state-climate-auto-color, var(--state-climate-auto-color, var(--state-climate-active-color, var(--state-active-color))))';
} else if (state = "heat_cool") {
overlayColor = 'var(--bubble-state-climate-heat-cool-color, var(--state-climate-heat-cool-color, var(--state-climate-active-color, var(--state-active-color))))';
} else {
overlayColor = 'var(--bubble-climate-accent-color, var(--bubble-accent-color, var(--accent-color)))';
}
} else {
overlayColor = '';
}
break;
case "fan_only":
overlayColor = 'var(--state-climate-fan-only-color, var(--state-climate-active-color, var(--state-active-color)))';
break;
case "dry":
overlayColor = 'var(--state-climate-dry-color, var(--state-climate-active-color, var(--state-active-color)))';
break;
case "auto":
overlayColor = 'var(--state-climate-auto-color, var(--state-climate-active-color, var(--state-active-color)))';
break;
default:
overlayColor = '';
break;
}

return overlayColor;
Expand Down
12 changes: 6 additions & 6 deletions src/cards/pop-up/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ function updateBackdropColor() {
getComputedStyle(document.body).getPropertyValue('--ha-card-background') ||
getComputedStyle(document.body).getPropertyValue('--card-background-color');

backdropStyle.style.setProperty('--bubble-backdrop-background-color', convertToRGBA(themeColorBackground, 0.7, 0.7));
document.body.style.setProperty('--bubble-backdrop-background-color', convertToRGBA(themeColorBackground, 0.8, 0.6));
}

colorScheme.addEventListener('change', updateBackdropColor);
updateBackdropColor();

export function getBackdrop(context) {
const isBackdropHidden = context.config.hide_backdrop ?? true;
const isBackdropHidden = context.config.hide_backdrop ?? false;

if (backdrop) return backdrop;

Expand All @@ -43,7 +43,7 @@ export function getBackdrop(context) {
}

document.body.appendChild(backdropElement);
backdropElement.style.setProperty('--custom-backdrop-filter', `blur(${context.config.bg_blur ?? 10}px)`);
backdropElement.style.setProperty('--custom-backdrop-filter', `blur(${context.config.backdrop_blur ?? 0}px)`);

function showBackdrop() {
requestAnimationFrame(() => {
Expand Down Expand Up @@ -193,6 +193,8 @@ export function createStructure(context) {
context.popUp.appendChild(context.elements.popUpContainer);

hideContent(context, 0);

window.dispatchEvent(new Event('location-changed'));
} catch (e) {
console.error(e)
}
Expand All @@ -219,15 +221,13 @@ export function prepareStructure(context) {
context.popUp.style.setProperty('--custom-height-offset-desktop', context.config.margin_top_desktop ?? '0px');
context.popUp.style.setProperty('--custom-height-offset-mobile', context.config.margin_top_mobile ?? '0px');
context.popUp.style.setProperty('--custom-margin', `-${context.config.margin ?? '7px'}`);
context.popUp.style.setProperty('--custom-popup-filter', hideBackdrop ? `blur(${context.config.bg_blur ?? 10}px)` : 'none');
context.popUp.style.setProperty('--custom-popup-filter', !context.config.backdrop_blur || context.config.backdrop_blur === '0' ? `blur(${context.config.bg_blur ?? 10}px)` : 'none');
context.popUp.style.setProperty('--custom-shadow-opacity', (context.config.shadow_opacity ?? 0) / 100);

const contextOnUrlChange = onUrlChange(context);

window.addEventListener('location-changed', contextOnUrlChange);
window.addEventListener('popstate', contextOnUrlChange);

window.dispatchEvent(new Event('location-changed'));
} catch (e) {
console.error(e);
}
Expand Down
Loading

0 comments on commit 2d017ca

Please sign in to comment.