1
0
mirror of https://github.com/home-assistant/frontend.git synced 2025-12-24 20:55:49 +00:00

Revert "Add media playback badge for Area card (#26893)" (#27413)

This reverts commit 7c7a4e61f2.
This commit is contained in:
Paul Bottein
2025-10-08 15:59:37 +02:00
committed by GitHub
parent b312cca050
commit f2c5b91def
4 changed files with 7 additions and 271 deletions

View File

@@ -39,8 +39,6 @@ import type { HomeAssistant, TranslationDict } from "../types";
import { isUnavailableState } from "./entity";
import { isTTSMediaSource } from "./tts";
import { generateEntityFilter } from "../common/entity/entity_filter";
interface MediaPlayerEntityAttributes extends HassEntityAttributeBase {
media_content_id?: string;
media_content_type?: string;
@@ -524,33 +522,3 @@ export const mediaPlayerJoin = (
export const mediaPlayerUnjoin = (hass: HomeAssistant, entity_id: string) =>
hass.callService("media_player", "unjoin", {}, { entity_id });
/**
* Compute active media player states in a specific area.
* @param hass Home Assistant object
* @param areaId Area ID to filter media players by
* @returns Array of playing media player entities
*/
export const computeActiveAreaMediaStates = (
hass: HomeAssistant,
areaId: string
): MediaPlayerEntity[] => {
const area = hass.areas[areaId];
if (!area) {
return [];
}
// Get all media_player entities in this area
const mediaFilter = generateEntityFilter(hass, {
area: areaId,
domain: "media_player",
});
const mediaEntities = Object.keys(hass.entities).filter(mediaFilter);
return mediaEntities
.map((entityId) => hass.states[entityId] as MediaPlayerEntity | undefined)
.filter(
(stateObj): stateObj is MediaPlayerEntity => stateObj?.state === "playing"
);
};

View File

@@ -1,4 +1,4 @@
import { mdiPlay, mdiTextureBox } from "@mdi/js";
import { mdiTextureBox } from "@mdi/js";
import type { HassEntity } from "home-assistant-js-websocket";
import {
css,
@@ -13,10 +13,6 @@ import { classMap } from "lit/directives/class-map";
import { ifDefined } from "lit/directives/if-defined";
import { styleMap } from "lit/directives/style-map";
import memoizeOne from "memoize-one";
import {
computeActiveAreaMediaStates,
type MediaPlayerEntity,
} from "../../../data/media-player";
import { computeCssColor } from "../../../common/color/compute-color";
import { BINARY_STATE_ON } from "../../../common/const";
import { computeAreaName } from "../../../common/entity/compute_area_name";
@@ -289,19 +285,15 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
);
}
private _computeActiveAreaMediaStates(): MediaPlayerEntity[] {
return computeActiveAreaMediaStates(this.hass, this._config?.area || "");
}
private _renderAlertSensorBadge(): TemplateResult<1> | typeof nothing {
const states = this._computeActiveAlertStates();
private _renderAlertSensorBadge(
alertStates: HassEntity[]
): TemplateResult<1> | typeof nothing {
if (alertStates.length === 0) {
if (states.length === 0) {
return nothing;
}
// Only render the first one when using a badge
const stateObj = alertStates[0] as HassEntity | undefined;
const stateObj = states[0] as HassEntity | undefined;
return html`
<ha-tile-badge class="alert-badge">
@@ -310,30 +302,6 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
`;
}
private _renderMediaBadge(): TemplateResult<1> | typeof nothing {
const states = this._computeActiveAreaMediaStates();
if (states.length === 0) {
return nothing;
}
return html`
<ha-tile-badge
class="media-badge"
.label=${this.hass.localize("ui.card.area.media_playing")}
>
<ha-svg-icon .path=${mdiPlay}></ha-svg-icon>
</ha-tile-badge>
`;
}
private _renderCompactBadge(): TemplateResult<1> | typeof nothing {
const alertStates = this._computeActiveAlertStates();
return alertStates.length > 0
? this._renderAlertSensorBadge(alertStates)
: this._renderMediaBadge();
}
private _renderAlertSensors(): TemplateResult<1> | typeof nothing {
const states = this._computeActiveAlertStates();
@@ -595,7 +563,7 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
<div class="content ${classMap(contentClasses)}">
<ha-tile-icon>
${displayType === "compact"
? this._renderCompactBadge()
? this._renderAlertSensorBadge()
: nothing}
${icon
? html`<ha-icon slot="icon" .icon=${icon}></ha-icon>`
@@ -773,9 +741,6 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
.alert-badge {
--tile-badge-background-color: var(--orange-color);
}
.media-badge {
--tile-badge-background-color: var(--light-blue-color);
}
.alerts {
position: absolute;
top: 0;

View File

@@ -106,8 +106,7 @@
}
},
"area": {
"area_not_found": "Area not found.",
"media_playing": "Media playing"
"area_not_found": "Area not found."
},
"automation": {
"last_triggered": "Last triggered",

View File

@@ -1,196 +0,0 @@
import { describe, expect, it } from "vitest";
import {
computeActiveAreaMediaStates,
type MediaPlayerEntity,
} from "../../../src/data/media-player";
describe("computeActiveAreaMediaStates", () => {
it("returns playing media entities in the area", () => {
const hass = {
areas: { living_room: { area_id: "living_room" } },
entities: {
"media_player.tv": {
entity_id: "media_player.tv",
area_id: "living_room",
},
"media_player.speaker": {
entity_id: "media_player.speaker",
area_id: "living_room",
},
},
states: {
"media_player.tv": {
entity_id: "media_player.tv",
state: "playing",
} as MediaPlayerEntity,
"media_player.speaker": {
entity_id: "media_player.speaker",
state: "idle",
} as MediaPlayerEntity,
},
} as any;
const result = computeActiveAreaMediaStates(hass, "living_room");
expect(result).toHaveLength(1);
expect(result[0].entity_id).toBe("media_player.tv");
expect(result[0].state).toBe("playing");
});
it("returns empty array when no area is configured", () => {
const hass = {
areas: {},
entities: {},
states: {},
} as any;
const result = computeActiveAreaMediaStates(hass, "living_room");
expect(result).toHaveLength(0);
});
it("returns empty array when media player is not assigned to area", () => {
const hass = {
areas: { living_room: { area_id: "living_room" } },
entities: {
"media_player.bedroom": { entity_id: "media_player.bedroom" },
},
states: {
"media_player.bedroom": {
entity_id: "media_player.bedroom",
state: "playing",
} as MediaPlayerEntity,
},
} as any;
const result = computeActiveAreaMediaStates(hass, "living_room");
expect(result).toHaveLength(0);
});
it("returns playing speaker when speaker is playing", () => {
const hass = {
areas: { living_room: { area_id: "living_room" } },
entities: {
"media_player.tv": {
entity_id: "media_player.tv",
area_id: "living_room",
},
"media_player.speaker": {
entity_id: "media_player.speaker",
area_id: "living_room",
},
},
states: {
"media_player.tv": {
entity_id: "media_player.tv",
state: "idle",
} as MediaPlayerEntity,
"media_player.speaker": {
entity_id: "media_player.speaker",
state: "playing",
} as MediaPlayerEntity,
},
} as any;
const result = computeActiveAreaMediaStates(hass, "living_room");
expect(result).toHaveLength(1);
expect(result[0].entity_id).toBe("media_player.speaker");
expect(result[0].state).toBe("playing");
});
it("returns media entities that inherit area from device", () => {
const hass = {
areas: { living_room: { area_id: "living_room" } },
devices: {
device_tv: {
id: "device_tv",
area_id: "living_room",
},
},
entities: {
"media_player.tv": {
entity_id: "media_player.tv",
device_id: "device_tv", // Entity belongs to device
// No direct area_id - inherits from device
},
},
states: {
"media_player.tv": {
entity_id: "media_player.tv",
state: "playing",
} as MediaPlayerEntity,
},
} as any;
const result = computeActiveAreaMediaStates(hass, "living_room");
expect(result).toHaveLength(1);
expect(result[0].entity_id).toBe("media_player.tv");
expect(result[0].state).toBe("playing");
});
});
describe("computeActiveAreaMediaStates badge priority", () => {
it("prioritizes alert badge over media badge", () => {
const hass = {
areas: { living_room: { area_id: "living_room" } },
entities: {
"binary_sensor.door": {
entity_id: "binary_sensor.door",
area_id: "living_room",
},
"media_player.tv": {
entity_id: "media_player.tv",
area_id: "living_room",
},
},
states: {
"binary_sensor.door": {
entity_id: "binary_sensor.door",
state: "on",
} as MediaPlayerEntity,
"media_player.tv": {
entity_id: "media_player.tv",
state: "playing",
} as MediaPlayerEntity,
},
} as any;
const alertStates = hass.states["binary_sensor.door"]
? [hass.states["binary_sensor.door"]]
: [];
const mediaStates = computeActiveAreaMediaStates(hass, "living_room");
// Alert badge should take priority
expect(alertStates.length > 0).toBe(true);
expect(mediaStates.length > 0).toBe(true);
expect(alertStates.length > 0 ? "alert" : "media").toBe("alert");
});
it("shows media badge when no alerts", () => {
const hass = {
areas: { living_room: { area_id: "living_room" } },
entities: {
"media_player.tv": {
entity_id: "media_player.tv",
area_id: "living_room",
},
},
states: {
"media_player.tv": {
entity_id: "media_player.tv",
state: "playing",
} as MediaPlayerEntity,
},
} as any;
const alertStates: MediaPlayerEntity[] = [];
const mediaStates = computeActiveAreaMediaStates(hass, "living_room");
expect(alertStates.length).toBe(0);
expect(mediaStates.length).toBe(1);
expect(alertStates.length > 0 ? "alert" : "media").toBe("media");
});
});