Skip to content

Commit

Permalink
v0.14.2 Release Candidate (#98)
Browse files Browse the repository at this point in the history
- Fix rendering issues on iPads and other legacy devices
- Add visual editor
  • Loading branch information
vasqued2 authored Aug 24, 2024
1 parent 8adc928 commit 77e12d3
Show file tree
Hide file tree
Showing 12 changed files with 410 additions and 207 deletions.
270 changes: 260 additions & 10 deletions dist/card_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,130 @@
import { html, LitElement } from "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js";


export class MyCustomCardEditor extends LitElement {
export class TeamtrackerCardEditor extends LitElement {

static get properties() {
return {
hass: {},
_config: {},
_config: { type: Object },
currentPage: { type: String },
entities: { type: Array },
hass: { type: Object },
_entity: { type: String },
};
}

// setConfig works the same way as for the card itself
constructor() {
super();
this.currentPage = 'card';
this._entity = '';
this.entities = [];
this._formValueChanged = this._formValueChanged.bind(this);
}


setConfig(config) {
if (!config) {
throw new Error("Invalid configuration");
}
this._config = config;
this._entity = config.entity || '';
}


get config() {
return this._config;
}

updated(changedProperties) {
if (changedProperties.has('hass')) {
this.fetchEntities();
}
if (changedProperties.has('_config') && this._config && this._config.entity) {
this._entity = this._config.entity;
}
}

fetchEntities() {
if (this.hass) {
this.entities = Object.keys(this.hass.states).filter((e) =>
e.startsWith('sensor.') &&
this.hass.states[e].attributes.hasOwnProperty('sport')
)
.sort((a, b) => a.localeCompare(b));
}
}

configChanged(newConfig) {
const event = new Event("config-changed", {
bubbles: true,
composed: true,
});
event.detail = { config: newConfig };
this.dispatchEvent(event);
}

_EntityChanged(event, key) {
if (!this._config) {
return;
}

const newConfig = { ...this._config };

if (key === 'entity') {
newConfig.entity = event.target.value;
this._entity = event.target.value;
}

this.configChanged(newConfig);
this.requestUpdate();
}

_valueChanged(event, key) {
if (!this._config) {
return;
}

let newConfig = { ...this._config };

if (key.includes('.')) {
const parts = key.split('.');
let currentLevel = newConfig;

for (let i = 0; i < parts.length - 1; i++) {
const part = parts[i];

currentLevel[part] = { ...currentLevel[part] };

currentLevel = currentLevel[part];
}

const finalKey = parts[parts.length - 1];
if (event.target.checked !== undefined) {
currentLevel[finalKey] = event.target.checked;
} else {
currentLevel[finalKey] = event.target.value;
}
} else {
if (event.target.checked !== undefined) {
newConfig[key] = event.target.checked;
} else {
newConfig[key] = event.target.value;
}
}

this.configChanged(newConfig);
this.requestUpdate();
}


_formValueChanged(event) {
if (event.target.tagName.toLowerCase() === 'ha-form') {
const newConfig = event.detail.value;
this.configChanged(newConfig);
this.requestUpdate();
}
}

// This function is called when the input element of the editor loses focus
entityChanged(ev) {

Expand All @@ -43,13 +153,153 @@ export class MyCustomCardEditor extends LitElement {
return html``;
}

// @focusout below will call entityChanged when the input field loses focus (e.g. the user tabs away or clicks outside of it)
return html`
Entity:
<input
.value=${this._config.entity}
@focusout=${this.entityChanged}
></input>
<style>
.switch-label {
padding-left: 14px;
}
.switch-container {
margin-top: 12px;
margin-left: 15px;
}
.textfield-container {
display: flex;
flex-direction: column;
margin-bottom: 10px;
gap: 0px;
}
.ha-textfield {
flex-basis: 50%;
flex-grow: 1;
}
.indented-container {
margin-left: 55px;
}
h4 {
margin-bottom: 0px;
}
</style>
<div>
<h4>Teamtracker Sensor:</h4>
<div class="textfield-container">
<ha-select
naturalMenuWidth
fixedMenuPosition
label="Entity"
.configValue=${'entity'}
.value=${this._entity}
@change=${(e) => this._EntityChanged(e, 'entity')}
@closed=${(ev) => ev.stopPropagation()}
>
${this.entities.map((entity) => {
return html`<ha-list-item .value=${entity}>${entity}</ha-list-item>`;
})}
</ha-select>
</div>
<hr>
<h4>Settings:</h4>
<ha-select
naturalMenuWidth
fixedMenuPosition
.configValue=${'home_side'}
.value=${this._config.home_side}
@change=${(e) => this._valueChanged(e, 'home_side')}
@closed=${(ev) => ev.stopPropagation()}
>
<ha-list-item .value=${''}>Team on Left</ha-list-item>
<ha-list-item .value=${'left'}>Home on Left</ha-list-item>
<ha-list-item .value=${'right'}>Home on Right</ha-list-item>
</ha-select>
<div class="switch-container">
<ha-switch
@change="${(e) => this._valueChanged(e, 'show_league')}"
.checked="${this._config.show_league === true}"
>
</ha-switch>
<label class="switch-label">
Show League
</label>
</div>
<div class="switch-container">
<ha-switch
@change="${(e) => this._valueChanged(e, 'show_rank')}"
.checked="${this._config.show_rank !== false}"
>
</ha-switch>
<label class="switch-label">
Show Rank
</label>
</div>
<div class="switch-container">
<ha-switch
@change="${(e) => this._valueChanged(e, 'show_timeouts')}"
.checked="${this._config.show_timeouts!== false}"
>
</ha-switch>
<label class="switch-label">
Show Timeouts
</label>
</div>
<div class="switch-container">
<ha-switch
@change="${(e) => this._valueChanged(e, 'outline')}"
.checked="${this._config.outline=== true}"
>
</ha-switch>
<label class="switch-label">
Show Outline
</label>
</div>
<div class="indented-container">
<ha-textfield
label="Outline Color"
.value="${this._config.outline_color || 'lightgrey'}"
@change="${(e) => this._valueChanged(e, 'outline_color')}"
>
</ha-textfield>
</div>
<hr>
<h4>Overrides:</h4>
<ha-textfield
label="Title"
.value="${this._config.card_title || ''}"
@change="${(e) => this._valueChanged(e, 'card_title')}"
>
</ha-textfield>
</br>
<ha-textfield
label="Team URL"
.value="${this._config.team_url || ''}"
@change="${(e) => this._valueChanged(e, 'team_url')}"
>
</ha-textfield>
</br>
<ha-textfield
label="Opponent URL"
.value="${this._config.opponent_url || ''}"
@change="${(e) => this._valueChanged(e, 'opponent_url')}"
>
</ha-textfield>
</br>
<ha-textfield
label="Bottom URL"
.value="${this._config.bottom_url || ''}"
@change="${(e) => this._valueChanged(e, 'bottom_url')}"
>
</ha-textfield>
<hr>
<div class="switch-container">
<ha-switch
@change="${(e) => this._valueChanged(e, 'debug')}"
.checked="${this._config.debug=== true}"
>
</ha-switch>
<label class="switch-label">
Show Debug Info
</label>
</div>
</div>
`;
}
}
2 changes: 1 addition & 1 deletion dist/const.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export let VERSION = "v0.14.1";
export let VERSION = "v0.14.2";

export let GOLF_HEADSHOT_URL = "https://a.espncdn.com/i/headshots/golf/players/full/";
export let MMA_HEADSHOT_URL = "https://a.espncdn.com/i/headshots/mma/players/full/";
Expand Down
4 changes: 2 additions & 2 deletions dist/ha-teamtracker-card.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { VERSION } from "./const.js";
import { MyCustomCardEditor } from "./card_editor.js";
import { TeamtrackerCardEditor } from "./card_editor.js";
import { TeamTrackerCard } from "./teamtracker_card.js";


customElements.define("teamtracker-card", TeamTrackerCard);
customElements.define("my-custom-card-editor", MyCustomCardEditor);
customElements.define("teamtracker-card-editor", TeamtrackerCardEditor);

console.info("%c TEAMTRACKER-CARD %s IS INSTALLED",
"color: blue; font-weight: bold",
Expand Down
10 changes: 0 additions & 10 deletions dist/render_bye.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,6 @@ import { html } from "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.j
export function renderBye(c) {
// Render the HTML template using the provided object `c`
const htmlTemplate = html`
<style>
.card { position: relative; overflow: hidden; padding: 16px 16px 20px; font-weight: 400; border-radius: var(--ha-card-border-radius, 10px); }
.team-bg { opacity: 0.08; position: absolute; top: -20%; left: -20%; width: 58%; z-index: 0; }
.card-content { display: flex; justify-content: space-evenly; align-items: center; text-align: center; position: relative; z-index: 1; }
.team { text-align: center; width: 35%;
.team img { max-width: 90px; }
.name { font-size: 1.6em; margin-bottom: 4px; }
.line { height: 1px; background-color: var(--primary-text-color); margin:10px 0; }
.bye { font-size: 1.8em; text-align: center; width: 50%; }
</style>
<ha-card>
<div class="card">
<img class="team-bg" src="${c.logoBG[team]}" />
Expand Down
Loading

0 comments on commit 77e12d3

Please sign in to comment.