Skip to content

Commit 170e57f

Browse files
committed
[TASK] change style
1 parent f586358 commit 170e57f

File tree

9 files changed

+443
-262
lines changed

9 files changed

+443
-262
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Version - 0.3.0](https://img.shields.io/badge/Version-0.3.0-009688?style=for-the-badge)](https://github.com/KartoffelToby/better-thermostat-ui-card)
1+
[![Version - 0.6.0](https://img.shields.io/badge/Version-0.6.0-009688?style=for-the-badge)](https://github.com/KartoffelToby/better-thermostat-ui-card)
22
[![Discord](https://img.shields.io/discord/925725316540923914.svg?style=for-the-badge)](https://discord.gg/9BUegWTG3K)
33
[![hacs_badge](https://img.shields.io/badge/HACS-Default-41BDF5.svg?style=for-the-badge)](https://github.com/hacs/integration)
44

dist/better-thermostat-ui-card.js

Lines changed: 102 additions & 82 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 197 additions & 112 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "better-thermostat-ui",
3-
"version": "0.5.0",
3+
"version": "0.6.0",
44
"description": "Lovelace better-thermostat-ui",
55
"keywords": [
66
"home-assistant",
@@ -18,7 +18,9 @@
1818
"author": "",
1919
"dependencies": {
2020
"@mdi/js": "^7.0.96",
21+
"@types/gsap": "^3.0.0",
2122
"custom-card-helpers": "^1.9.0",
23+
"gasp": "^0.0.2",
2224
"home-assistant-js-websocket": "^8.0.0",
2325
"lit": "^2.4.0"
2426
},

src/better-thermostat-ui-card.ts

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ import {
3939
mdiWaterPercent,
4040
mdiWindowOpenVariant,
4141
mdiSunThermometer,
42-
mdiLeaf
42+
mdiLeaf,
43+
mdiThermometer,
4344
} from "@mdi/js";
4445
import {
4546
HassEntity
@@ -73,7 +74,9 @@ const modeIcons: {
7374
dry: mdiWaterPercent,
7475
window_open: mdiWindowOpenVariant,
7576
eco: mdiLeaf,
76-
summer: mdiSunThermometer
77+
summer: mdiSunThermometer,
78+
temperature: mdiThermometer,
79+
humidity: mdiWaterPercent
7780
};
7881

7982
/* eslint no-console: 0 */
@@ -154,6 +157,7 @@ export class BetterThermostatUiCard extends LitElement {
154157
stateObj.attributes.temperature :
155158
stateObj.attributes.min_temp;
156159

160+
157161
const slider =
158162
stateObj.state === UNAVAILABLE ?
159163
html ` <bt-round-slider disabled="true"></bt-round-slider> ` :
@@ -226,25 +230,48 @@ export class BetterThermostatUiCard extends LitElement {
226230
</svg>
227231
`;
228232

233+
const currentHumidity = svg `
234+
<div class="humindity">
235+
<ha-svg-icon
236+
class="info-icon"
237+
tabindex="0"
238+
.path=${modeIcons['humidity']}
239+
.title=${localize(`common.current`)}
240+
>
241+
</ha-svg-icon>
242+
<span>
243+
${svg`${this.formatNumber(
244+
stateObj.attributes.humidity,
245+
this.hass.locale
246+
)}`}
247+
<span class="h-indication">%</span>
248+
</span>
249+
</div>
250+
`;
251+
229252
const currentTemperature = svg `
230-
<svg id="set-values">
231-
<g>
232-
<text text-anchor="middle" dy="-22">${localize(`common.current`)}</text>
233-
<text text-anchor="middle" class="set-value">
234-
${
235-
stateObj.attributes.current_temperature !== null &&
236-
!isNaN(stateObj.attributes.current_temperature)
237-
? svg`${this.formatNumber(
238-
stateObj.attributes.current_temperature,
239-
this.hass.locale
240-
)}
241-
<tspan dx="-1" dy="-4.5" style="font-size: 10px;">
242-
${this.hass.config.unit_system.temperature}
243-
</tspan>`
244-
: ""
245-
}
246-
</text>
247-
<!--<text
253+
<div class="temperature">
254+
<ha-svg-icon
255+
class="info-icon"
256+
tabindex="0"
257+
.path=${modeIcons['temperature']}
258+
.title=${localize(`common.current`)}
259+
>
260+
</ha-svg-icon>
261+
<span>
262+
${svg`${this.formatNumber(
263+
stateObj.attributes.current_temperature,
264+
this.hass.locale
265+
)}`}
266+
${svg`<svg id="set-values" style="transform: translateY(-2px);"><g><text text-anchor="middle" class="set-value"><tspan dx="-1" dy="-8.5" style="font-size: 10px;">
267+
${this.hass.config.unit_system.temperature}
268+
</tspan></text><g></svg>`}
269+
</span>
270+
</div>
271+
`;
272+
273+
/*
274+
<!--<text
248275
dy="22"
249276
text-anchor="middle"
250277
id="set-mode"
@@ -259,9 +286,7 @@ export class BetterThermostatUiCard extends LitElement {
259286
)
260287
}
261288
</text>-->
262-
</g>
263-
</svg>
264-
`;
289+
*/
265290

266291
setTimeout(() => this._rescale_svg(), 100);
267292

@@ -316,6 +341,9 @@ export class BetterThermostatUiCard extends LitElement {
316341
</div>
317342
<div id="current-infos">
318343
${currentTemperature}
344+
${
345+
stateObj.attributes.humidity !== null && stateObj.attributes.humidity > 0 ? currentHumidity : ""
346+
}
319347
</div>
320348
</div>
321349
</ha-card>
@@ -371,7 +399,6 @@ export class BetterThermostatUiCard extends LitElement {
371399
if (!stateObj) {
372400
return;
373401
}
374-
375402
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
376403

377404
if (!oldHass || oldHass.states[this._config.entity] !== stateObj) {
@@ -694,6 +721,21 @@ export class BetterThermostatUiCard extends LitElement {
694721
:host {
695722
display: block;
696723
}
724+
.humindity, .temperature {
725+
display: grid;
726+
justify-items: center;
727+
gap: 0.3em;
728+
font-weight: bold;
729+
}
730+
.info-icon {
731+
opacity: 0.75;
732+
height: 20px;
733+
}
734+
.h-indication {
735+
font-size: 10px;
736+
transform: translateY(-4px);
737+
display: inline-block;
738+
}
697739
ha-card {
698740
height: 100%;
699741
position: relative;
@@ -725,7 +767,7 @@ export class BetterThermostatUiCard extends LitElement {
725767
min-height: 30px;
726768
}
727769
ha-svg-icon.status-icon.window_open {
728-
color: #1d9187 !important;
770+
color: #00bcd4 !important;
729771
}
730772
ha-svg-icon.status-icon.eco {
731773
color: #6cff71 !important;
@@ -808,7 +850,7 @@ export class BetterThermostatUiCard extends LitElement {
808850
position: relative;
809851
}
810852
.window bt-round-slider {
811-
--round-slider-bar-color: #00bcd461 !important;
853+
--round-slider-bar-color: #00bcd4 !important;
812854
}
813855
814856
#slider-center {
@@ -836,7 +878,8 @@ export class BetterThermostatUiCard extends LitElement {
836878
flex-flow: row;
837879
justify-content: center;
838880
gap: 1.2em;
839-
padding-bottom: 1em;
881+
padding-bottom: 0.5em;
882+
padding-top: 0.3em
840883
font-size: 16px;
841884
}
842885
#set-values {

src/const.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const CARD_VERSION = '0.5.0';
1+
export const CARD_VERSION = '0.6.0';

src/editor.ts

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,20 @@ const options = {
1616

1717
@customElement('better-thermostat-ui-card-editor')
1818
export class BetterThermostatUiCardEditor extends LitElement implements LovelaceCardEditor {
19-
@property({ attribute: false }) public hass?: HomeAssistant;
20-
@state() private _config?: BetterThermostatUiCardConfig;
19+
@property({ attribute: false })
20+
public hass!: HomeAssistant;
21+
@state() private _config?: any;
2122
@state() private _toggle?: boolean;
2223
@state() private _helpers?: any;
2324
private _initialized = false;
2425

25-
public setConfig(config: BetterThermostatUiCardConfig): void {
26+
public setConfig(config: any): void {
2627
this._config = config;
2728

29+
if (!this._config.entity) {
30+
this._config.entity = this.getEntitiesByType('climate')[0];
31+
fireEvent(this, 'config-changed', { config: this._config });
32+
}
2833
this.loadCardHelpers();
2934
}
3035

@@ -64,6 +69,12 @@ export class BetterThermostatUiCardEditor extends LitElement implements Lovelace
6469
return this._config?.double_tap_action || { action: 'none' };
6570
}
6671

72+
getEntitiesByType(type) {
73+
return Object.keys(this.hass.states).filter(
74+
(eid) => eid.substr(0, eid.indexOf('.')) === type
75+
);
76+
}
77+
6778
protected render(): TemplateResult | void {
6879
if (!this.hass || !this._helpers) {
6980
return html``;
@@ -79,32 +90,20 @@ export class BetterThermostatUiCardEditor extends LitElement implements Lovelace
7990

8091
return html`
8192
<div class="card-config">
82-
<div class="option" @click=${this._toggleOption} .option=${'required'}>
83-
<div class="row">
84-
<ha-icon .icon=${`mdi:${options.required.icon}`}></ha-icon>
85-
<div class="title">${options.required.name}</div>
86-
</div>
87-
<div class="secondary">${options.required.secondary}</div>
88-
</div>
89-
${options.required.show
90-
? html`
91-
<div class="values">
92-
<paper-dropdown-menu
93-
label="Entity (Required)"
94-
@value-changed=${this._valueChanged}
95-
.configValue=${'entity'}
96-
>
97-
<paper-listbox slot="dropdown-content" .selected=${entities.indexOf(this._entity)}>
98-
${entities.map(entity => {
99-
return html`
100-
<paper-item>${entity}</paper-item>
101-
`;
102-
})}
103-
</paper-listbox>
104-
</paper-dropdown-menu>
105-
</div>
106-
`
107-
: ''}
93+
<paper-dropdown-menu
94+
label="entity"
95+
@value-changed=${this._valueChanged}
96+
.configValue=${'entity'}
97+
>
98+
<paper-listbox
99+
slot="dropdown-content"
100+
.selected=${entities.indexOf(this._entity)}
101+
>
102+
${entities.map((entity) => {
103+
return html` <paper-item>${entity}</paper-item> `;
104+
})}
105+
</paper-listbox>
106+
</paper-dropdown-menu>
108107
</div>
109108
`;
110109
}
@@ -133,7 +132,7 @@ export class BetterThermostatUiCardEditor extends LitElement implements Lovelace
133132
this._toggle = !this._toggle;
134133
}
135134

136-
private _valueChanged(ev): void {
135+
_valueChanged(ev) {
137136
if (!this._config || !this.hass) {
138137
return;
139138
}
@@ -143,13 +142,12 @@ export class BetterThermostatUiCardEditor extends LitElement implements Lovelace
143142
}
144143
if (target.configValue) {
145144
if (target.value === '') {
146-
const tmpConfig = { ...this._config };
147-
delete tmpConfig[target.configValue];
148-
this._config = tmpConfig;
145+
delete this._config[target.configValue];
149146
} else {
150147
this._config = {
151148
...this._config,
152-
[target.configValue]: target.checked !== undefined ? target.checked : target.value,
149+
[target.configValue]:
150+
target.checked !== undefined ? target.checked : target.value,
153151
};
154152
}
155153
}

src/localize/localize.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ const languages: any = {
5050
};
5151

5252
export function localize(string: string, search = '', replace = ''): string {
53-
const lang = (localStorage.getItem('selectedLanguage') || navigator.language).replace(/['"]+/g, '').replace('-', '_');
54-
53+
const localLangStore = localStorage.getItem('i18nextLng') || localStorage.getItem('lang') || navigator.language || 'en';
54+
const lang = RegExp("^.{0,2}").exec((localLangStore).replace(/['"]+/g, '').replace('-', '_')) || ['en'];
5555
let translated: string;
5656

5757
try {
58-
translated = string.split('.').reduce((o, i) => o[i], languages[lang]);
58+
translated = string.split('.').reduce((o, i) => o[i], languages[lang[0]]);
5959
} catch (e) {
6060
translated = string.split('.').reduce((o, i) => o[i], languages['en']);
6161
}

src/round-slider.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
CSSResultGroup,
1212
} from "lit";
1313
import { customElement, property, state } from "lit/decorators.js";
14+
import gsap from 'gsap';
1415
@customElement('bt-round-slider')
1516
class RoundSlider extends LitElement {
1617
@property({ type: Number }) public value: number | undefined;
@@ -318,6 +319,37 @@ import {
318319

319320
protected updated(changedProperties: PropertyValues) {
320321
// Adjust margin in the bar slider stroke width is greater than the handle size
322+
/*
323+
setTimeout(() => {
324+
const val = { distance: 0 };
325+
const path = this.shadowRoot.querySelector('path.shadowpath');
326+
const pathOverflow = this.shadowRoot.querySelector('path.overflow');
327+
const bar = this.shadowRoot?.querySelector('path.bar')
328+
const circle = this.shadowRoot.querySelector('path.handle');
329+
console.log({path,circle})
330+
// Create a tween
331+
gsap.to(val, {
332+
// Animate from distance 0 to the total distance
333+
distance: path.getTotalLength(),
334+
duration: 5,
335+
repeat: -1,
336+
// Function call on each frame of the animation
337+
onUpdate: () => {
338+
// Query a point at the new distance value
339+
const point = path.getPointAtLength(val.distance);
340+
// Update the circle coordinates
341+
const d=`M ${point.x} ${point.y} L ${point.x + 0.001} ${point.y + 0.001}`;
342+
circle.setAttribute('d', d);
343+
pathOverflow.setAttribute('d', d);
344+
bar.setAttribute('d', this._renderArc(
345+
point.y,
346+
point.y + point.x
347+
));
348+
}
349+
});
350+
},3000);
351+
*/
352+
321353
if (this.shadowRoot.querySelector(".slider")) {
322354
const styles = window.getComputedStyle(
323355
this.shadowRoot.querySelector(".slider")
@@ -489,7 +521,7 @@ import {
489521
: svg`${this._renderHandle("low")} ${this._renderHandle(
490522
"high"
491523
)}`
492-
: svg`${this._renderHandle("current")}${this._renderHandle("value")}`
524+
: svg`${this._renderHandle("value")}${this._renderHandle("current")}`
493525
: ``}
494526
</g>
495527
</svg>
@@ -511,6 +543,7 @@ import {
511543
}
512544
.current-handle {
513545
pointer-events: none;
546+
z-index: 90;
514547
stroke: var(--round-slider-path-color, lightgray);
515548
}
516549
.slider {

0 commit comments

Comments
 (0)