Skip to content

Instantly share code, notes, and snippets.

@grischard
Last active September 3, 2024 15:14
Show Gist options
  • Save grischard/ce5b9707652b67e81bc6957911f2324a to your computer and use it in GitHub Desktop.
Save grischard/ce5b9707652b67e81bc6957911f2324a to your computer and use it in GitHub Desktop.
Swatch beats Home Assistant
class SwatchBeatBase extends HTMLElement {
connectedCallback() {
this.interval = setInterval(() => this.updateBeats(), 86);
}
disconnectedCallback() {
clearInterval(this.interval);
}
updateBeats() {
const now = new Date();
const beats = (
(((now.getUTCHours() * 3600 +
now.getUTCMinutes() * 60 +
now.getUTCSeconds()) *
1000 +
now.getUTCMilliseconds() +
3600000) %
86400000) /
86400
).toFixed(3);
this.render(beats);
}
render(beats) {
throw new Error('Method "render(beats)" must be implemented');
}
}
class SwatchBeatCard extends SwatchBeatBase {
set hass(hass) {
if (!this.content) {
const card = document.createElement("hui-badge");
card.header = "Swatch Internet Beats";
this.content = document.createElement("div");
this.content.id = "swatch-beat";
this.content.className = "card-content";
card.appendChild(this.content);
this.appendChild(card);
}
this.updateBeats();
}
render(beats) {
this.content.innerHTML = `@${beats}`;
}
setConfig(config) {
this.config = config;
}
getCardSize() {
return 1;
}
}
class SwatchBeatBadge extends SwatchBeatBase {
setConfig() {}
set hass(hass) {
this._hass = hass;
if (!this.shadowRoot) {
this.attachShadow({mode: "open" });
this.shadowRoot.innerHTML = `
<style>
:host {
--badge-color: var(--state-inactive-color);
-webkit-tap-highlight-color: transparent;
}
.badge.error {
--badge-color: var(--red-color);
}
.badge {
position: relative;
--ha-ripple-color: var(--badge-color);
--ha-ripple-hover-opacity: 0.04;
--ha-ripple-pressed-opacity: 0.12;
transition:
box-shadow 180ms ease-in-out,
border-color 180ms ease-in-out;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 8px;
height: var(--ha-badge-size, 36px);
min-width: var(--ha-badge-size, 36px);
padding: 0px 8px;
box-sizing: border-box;
width: auto;
border-radius: var(
--ha-badge-border-radius,
calc(var(--ha-badge-size, 36px) / 2)
);
background: var(
--ha-card-background,
var(--card-background-color, white)
);
-webkit-backdrop-filter: var(--ha-card-backdrop-filter, none);
backdrop-filter: var(--ha-card-backdrop-filter, none);
border-width: var(--ha-card-border-width, 1px);
box-shadow: var(--ha-card-box-shadow, none);
border-style: solid;
border-color: var(
--ha-card-border-color,
var(--divider-color, #e0e0e0)
);
--mdc-icon-size: 18px;
text-align: center;
font-family: Roboto;
}
.badge:focus-visible {
--shadow-default: var(--ha-card-box-shadow, 0 0 0 0 transparent);
--shadow-focus: 0 0 0 1px var(--badge-color);
border-color: var(--badge-color);
box-shadow: var(--shadow-default), var(--shadow-focus);
}
button,
[role="button"] {
cursor: pointer;
}
button:focus,
[role="button"]:focus {
outline: none;
}
.badge.active {
--badge-color: var(--primary-color);
}
.info {
display: flex;
flex-direction: column;
align-items: flex-start;
padding-right: 4px;
padding-inline-end: 4px;
padding-inline-start: initial;
}
.label {
font-size: 10px;
font-style: normal;
font-weight: 500;
line-height: 10px;
letter-spacing: 0.1px;
color: var(--secondary-text-color);
}
.content {
font-size: 12px;
font-style: normal;
font-weight: 500;
line-height: 16px;
letter-spacing: 0.1px;
color: var(--primary-text-color);
}
ha-icon,
ha-state-icon,
ha-svg-icon {
color: var(--badge-color);
line-height: 0;
}
img {
width: 30px;
height: 30px;
border-radius: 50%;
object-fit: cover;
overflow: hidden;
}
.badge.no-info {
padding: 0;
}
.badge:not(.no-icon):not(.no-info) img {
margin-left: -6px;
margin-inline-start: -6px;
margin-inline-end: initial;
}
.badge.no-icon .info {
padding-right: 4px;
padding-left: 4px;
padding-inline-end: 4px;
padding-inline-start: 4px;
}
.content {
display: flex;
flex-direction: column;
align-items: flex-start;
padding-right: 4px;
padding-inline-end: 4px;
padding-inline-start: initial;
}
.name {
font-size: 10px;
font-style: normal;
font-weight: 500;
line-height: 10px;
letter-spacing: 0.1px;
color: var(--secondary-text-color);
}
</style>
<div style="" class="badge active complete " role="button" tabindex="0">
<ha-ripple aria-hidden="true"></ha-ripple>
<ha-icon icon="mdi:at"></ha-icon>
<span class="content">
<span class="name">Beats</span>
<span class="state">
<state-display></state-display>
</span>
</span>
</div>
`;
this.beatsDisplay = this.shadowRoot.querySelector('state-display');
// this.beatsDisplay = document.createElement("div");
// this.shadowRoot.appendChild(this.beatsDisplay);
// this.content.setAttribute("style", "");
// this.content.className = "badge active standard";
// this.content.setAttribute("role", "button");
// this.content.setAttribute("tabindex", "0");
// // Ripple effect?
// const ripple = document.createElement("ha-ripple");
// ripple.setAttribute("aria-hidden", "true");
// const surface = document.createElement("div");
// surface.className = "surface";
// ripple.appendChild(surface);
// this.content.appendChild(ripple);
// // State icon
// const stateIcon = document.createElement("ha-state-icon");
// const haIcon = document.createElement("ha-icon");
// haIcon.setAttribute("icon", "mdi:at"); // Using mdi:at icon
// stateIcon.appendChild(haIcon);
// this.content.appendChild(stateIcon);
// // Content
// const contentSpan = document.createElement("span");
// contentSpan.className = "content";
// // Name
// const nameSpan = document.createElement("span");
// nameSpan.className = "name";
// nameSpan.textContent = "beat"; // Set the name of your badge
// contentSpan.appendChild(nameSpan);
// // State
// const stateSpan = document.createElement("span");
// stateSpan.className = "state";
// this.beatsDisplay = document.createElement("state-display");
// stateSpan.appendChild(this.beatsDisplay);
// contentSpan.appendChild(stateSpan);
// this.content.appendChild(contentSpan);
// this.appendChild(this.content);
}
this.updateBeats();
}
render(beats) {
if (this.beatsDisplay) {
this.beatsDisplay.textContent = `${beats}`;
}
}
setConfig(config) {
this.config = config;
}
}
customElements.define("swatch-beat-badge", SwatchBeatBadge);
customElements.define("swatch-beat-card", SwatchBeatCard);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment