Skip to content

Instantly share code, notes, and snippets.

@alex-phillips
Created March 21, 2025 00:29
Show Gist options
  • Save alex-phillips/f5fb91c801ad8b2b45231b11da255262 to your computer and use it in GitHub Desktop.
Save alex-phillips/f5fb91c801ad8b2b45231b11da255262 to your computer and use it in GitHub Desktop.
import {
LitElement,
html,
css,
} from "https://unpkg.com/[email protected]/lit-element.js?module";
class MusicGroupCard extends LitElement {
static get properties() {
return {
hass: {},
config: {},
};
}
render() {
return html` <div>${this.renderPlayers()}</div> `;
}
renderPlayers() {
const players = this.config.players
.map((player) => {
return {
name: player.name,
entity_id: player.entity_id,
default_source: player.default_source,
isGrouped: this.hass.states[player.entity_id].attributes.source === this.config.source,
};
})
// .sort((a, b) => a.name.localeCompare(b.name))
// .sort((a, b) => {
// if (a.isGrouped && !b.isGrouped) {
// return -1;
// }
// return 0;
// });
return html`<div class="chips">
${players.map((player) => {
return html`
<div
@click="${() => {
if (player.isGrouped) {
this._ungroupSpeaker(player.entity_id, player.default_source);
} else {
this._groupSpeaker(player.entity_id);
}
}}"
class="chip hide-scrollbar ${!player.isGrouped
? "chip-inactive"
: "chip-active"}"
>
<div style="display: flex; aligh-items: center; justify-content: space-between;">
<div class="music-group-circle" style="cursor: pointer;">
<ha-icon class="bubble-icon icon" style="color: inherit;" icon="${player.isGrouped ? "mdi:speaker" : "mdi:speaker-off"}"></ha-icon>
</div>
<div class="music-group-name">
${player.name}
</div>
</div>
</div>
`;
})}
</div> `;
}
_ungroupSpeaker(entity_id, source) {
this.hass.callService("media_player", "select_source", {
entity_id: entity_id,
source: source
});
}
_groupSpeaker(entity_id) {
this.hass.callService("media_player", "select_source", {
entity_id: entity_id,
source: this.config.source
});
}
setConfig(config) {
if (!config.source) {
throw new Error("You need to define the source");
}
this.config = config;
}
// The height of your card. Home Assistant uses this to automatically
// distribute all cards over the available columns.
getCardSize() {
return 1;
}
static get styles() {
return css`
:host {
:host {
}
}
.hide-scrollbar {
/*FireFox*/
scrollbar-width: none;
/*IE10+*/
-ms-overflow-style: -ms-autohiding-scrollbar;
}
.hide-scrollbar::-webkit-scrollbar {
/*Chrome, Safari, Edge*/
display: none;
}
.icon {
// --mdc-icon-size: 16px;
fill: var(--primary-text-color);
color: var(--primary-text-color);
current-color: var(--primary-text-color);
}
.chips {
display: flex;
flex-direction: row;
justify-content: space-around;
overflow-x: auto;
}
.chip {
display: flex;
flex-direction: row;
height: 50px;
width: 100%;
// font-size: 13px;
font-weight: 500;
color: rgba(0, 0, 0, 0.6);
line-height: 32px;
padding: 0;
border-radius: 32px;
background-color: var(--secondary-background-color);
color: var(--primary-text-color);
// margin-bottom: 5px;
margin: 0px 2px;
justify-content: space-between;
align-items: center;
gap: 4px;
text-wrap: nowrap;
cursor: pointer;
transition: background-color 0.5s linear;
}
.music-group-circle {
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: center;
min-width: 38px;
min-height: 38px;
border-radius: 50%;
background-color: var(--card-background-color, var(--ha-card-background));
overflow: hidden;
position: relative;
margin: 6px;
}
.music-group-name {
display: flex;
justify-content: center;
flex-direction: column;
margin-left: 4px;
}
.chip-inactive {
// opacity: 0.5;
}
.chip-active {
// background-color: rgba(255, 152, 0);
background-color: var(--accent-color);
}
`;
}
}
customElements.define("music-group-card", MusicGroupCard);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment