mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
Added "Media player volume slider" card feature. (#23199)
* Added "Media player volume" card feature. * Make sure the feature is not displayed on unsupported players Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com> * Renamed to Media player volume *slider* * Missed one rename. --------- Co-authored-by: Simon Zumbrunnen <simon-zumbrunnen@users.noreply.github.com> Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
This commit is contained in:
parent
9d83cc6988
commit
da727d3a3a
@ -4,6 +4,7 @@ import { customElement, query } from "lit/decorators";
|
|||||||
import { CoverEntityFeature } from "../../../../src/data/cover";
|
import { CoverEntityFeature } from "../../../../src/data/cover";
|
||||||
import { LightColorMode } from "../../../../src/data/light";
|
import { LightColorMode } from "../../../../src/data/light";
|
||||||
import { LockEntityFeature } from "../../../../src/data/lock";
|
import { LockEntityFeature } from "../../../../src/data/lock";
|
||||||
|
import { MediaPlayerEntityFeature } from "../../../../src/data/media-player";
|
||||||
import { VacuumEntityFeature } from "../../../../src/data/vacuum";
|
import { VacuumEntityFeature } from "../../../../src/data/vacuum";
|
||||||
import { getEntity } from "../../../../src/fake_data/entity";
|
import { getEntity } from "../../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||||
@ -28,6 +29,10 @@ const ENTITIES = [
|
|||||||
device_class: "lock",
|
device_class: "lock",
|
||||||
supported_features: LockEntityFeature.OPEN,
|
supported_features: LockEntityFeature.OPEN,
|
||||||
}),
|
}),
|
||||||
|
getEntity("media_player", "living_room", "playing", {
|
||||||
|
friendly_name: "Living room speaker",
|
||||||
|
supported_features: MediaPlayerEntityFeature.VOLUME_SET,
|
||||||
|
}),
|
||||||
getEntity("climate", "thermostat", "heat", {
|
getEntity("climate", "thermostat", "heat", {
|
||||||
current_temperature: 73,
|
current_temperature: 73,
|
||||||
min_temp: 45,
|
min_temp: 45,
|
||||||
@ -197,6 +202,15 @@ const CONFIGS = [
|
|||||||
- type: "lock-open-door"
|
- type: "lock-open-door"
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
heading: "Media player volume slider feature",
|
||||||
|
config: `
|
||||||
|
- type: tile
|
||||||
|
entity: media_player.living_room
|
||||||
|
features:
|
||||||
|
- type: "media-player-volume-slider"
|
||||||
|
`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
heading: "Vacuum commands feature",
|
heading: "Vacuum commands feature",
|
||||||
config: `
|
config: `
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
import type { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import { html, LitElement, nothing } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
|
import { stateActive } from "../../../common/entity/state_active";
|
||||||
|
import "../../../components/ha-control-slider";
|
||||||
|
import { isUnavailableState } from "../../../data/entity";
|
||||||
|
import type { HomeAssistant } from "../../../types";
|
||||||
|
import type { LovelaceCardFeature } from "../types";
|
||||||
|
import { cardFeatureStyles } from "./common/card-feature-styles";
|
||||||
|
import type { MediaPlayerVolumeSliderCardFeatureConfig } from "./types";
|
||||||
|
import { MediaPlayerEntityFeature } from "../../../data/media-player";
|
||||||
|
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||||
|
|
||||||
|
export const supportsMediaPlayerVolumeSliderCardFeature = (
|
||||||
|
stateObj: HassEntity
|
||||||
|
) => {
|
||||||
|
const domain = computeDomain(stateObj.entity_id);
|
||||||
|
return (
|
||||||
|
domain === "media_player" &&
|
||||||
|
supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_SET)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
@customElement("hui-media-player-volume-slider-card-feature")
|
||||||
|
class HuiMediaPlayerVolumeSliderCardFeature
|
||||||
|
extends LitElement
|
||||||
|
implements LovelaceCardFeature
|
||||||
|
{
|
||||||
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public stateObj?: HassEntity;
|
||||||
|
|
||||||
|
@state() private _config?: MediaPlayerVolumeSliderCardFeatureConfig;
|
||||||
|
|
||||||
|
static getStubConfig(): MediaPlayerVolumeSliderCardFeatureConfig {
|
||||||
|
return {
|
||||||
|
type: "media-player-volume-slider",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public setConfig(config: MediaPlayerVolumeSliderCardFeatureConfig): void {
|
||||||
|
if (!config) {
|
||||||
|
throw new Error("Invalid configuration");
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (
|
||||||
|
!this._config ||
|
||||||
|
!this.hass ||
|
||||||
|
!this.stateObj ||
|
||||||
|
!supportsMediaPlayerVolumeSliderCardFeature(this.stateObj)
|
||||||
|
) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
const position =
|
||||||
|
this.stateObj.attributes.volume_level != null
|
||||||
|
? Math.round(this.stateObj.attributes.volume_level * 100)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-control-slider
|
||||||
|
.value=${position}
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
.showHandle=${stateActive(this.stateObj)}
|
||||||
|
.disabled=${!this.stateObj || isUnavailableState(this.stateObj.state)}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
unit="%"
|
||||||
|
.locale=${this.hass.locale}
|
||||||
|
></ha-control-slider>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const value = ev.detail.value;
|
||||||
|
|
||||||
|
this.hass!.callService("media_player", "volume_set", {
|
||||||
|
entity_id: this.stateObj!.entity_id,
|
||||||
|
volume_level: value / 100,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return cardFeatureStyles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hui-media-player-volume-slider-card-feature": HuiMediaPlayerVolumeSliderCardFeature;
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,10 @@ export interface LockOpenDoorCardFeatureConfig {
|
|||||||
type: "lock-open-door";
|
type: "lock-open-door";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MediaPlayerVolumeSliderCardFeatureConfig {
|
||||||
|
type: "media-player-volume-slider";
|
||||||
|
}
|
||||||
|
|
||||||
export interface FanPresetModesCardFeatureConfig {
|
export interface FanPresetModesCardFeatureConfig {
|
||||||
type: "fan-preset-modes";
|
type: "fan-preset-modes";
|
||||||
style?: "dropdown" | "icons";
|
style?: "dropdown" | "icons";
|
||||||
@ -161,6 +165,7 @@ export type LovelaceCardFeatureConfig =
|
|||||||
| LightColorTempCardFeatureConfig
|
| LightColorTempCardFeatureConfig
|
||||||
| LockCommandsCardFeatureConfig
|
| LockCommandsCardFeatureConfig
|
||||||
| LockOpenDoorCardFeatureConfig
|
| LockOpenDoorCardFeatureConfig
|
||||||
|
| MediaPlayerVolumeSliderCardFeatureConfig
|
||||||
| NumericInputCardFeatureConfig
|
| NumericInputCardFeatureConfig
|
||||||
| SelectOptionsCardFeatureConfig
|
| SelectOptionsCardFeatureConfig
|
||||||
| TargetHumidityCardFeatureConfig
|
| TargetHumidityCardFeatureConfig
|
||||||
|
@ -17,6 +17,7 @@ import "../card-features/hui-light-brightness-card-feature";
|
|||||||
import "../card-features/hui-light-color-temp-card-feature";
|
import "../card-features/hui-light-color-temp-card-feature";
|
||||||
import "../card-features/hui-lock-commands-card-feature";
|
import "../card-features/hui-lock-commands-card-feature";
|
||||||
import "../card-features/hui-lock-open-door-card-feature";
|
import "../card-features/hui-lock-open-door-card-feature";
|
||||||
|
import "../card-features/hui-media-player-volume-slider-card-feature";
|
||||||
import "../card-features/hui-numeric-input-card-feature";
|
import "../card-features/hui-numeric-input-card-feature";
|
||||||
import "../card-features/hui-select-options-card-feature";
|
import "../card-features/hui-select-options-card-feature";
|
||||||
import "../card-features/hui-target-temperature-card-feature";
|
import "../card-features/hui-target-temperature-card-feature";
|
||||||
@ -51,6 +52,7 @@ const TYPES: Set<LovelaceCardFeatureConfig["type"]> = new Set([
|
|||||||
"light-color-temp",
|
"light-color-temp",
|
||||||
"lock-commands",
|
"lock-commands",
|
||||||
"lock-open-door",
|
"lock-open-door",
|
||||||
|
"media-player-volume-slider",
|
||||||
"numeric-input",
|
"numeric-input",
|
||||||
"select-options",
|
"select-options",
|
||||||
"target-humidity",
|
"target-humidity",
|
||||||
|
@ -38,6 +38,7 @@ import { supportsLightBrightnessCardFeature } from "../../card-features/hui-ligh
|
|||||||
import { supportsLightColorTempCardFeature } from "../../card-features/hui-light-color-temp-card-feature";
|
import { supportsLightColorTempCardFeature } from "../../card-features/hui-light-color-temp-card-feature";
|
||||||
import { supportsLockCommandsCardFeature } from "../../card-features/hui-lock-commands-card-feature";
|
import { supportsLockCommandsCardFeature } from "../../card-features/hui-lock-commands-card-feature";
|
||||||
import { supportsLockOpenDoorCardFeature } from "../../card-features/hui-lock-open-door-card-feature";
|
import { supportsLockOpenDoorCardFeature } from "../../card-features/hui-lock-open-door-card-feature";
|
||||||
|
import { supportsMediaPlayerVolumeSliderCardFeature } from "../../card-features/hui-media-player-volume-slider-card-feature";
|
||||||
import { supportsNumericInputCardFeature } from "../../card-features/hui-numeric-input-card-feature";
|
import { supportsNumericInputCardFeature } from "../../card-features/hui-numeric-input-card-feature";
|
||||||
import { supportsSelectOptionsCardFeature } from "../../card-features/hui-select-options-card-feature";
|
import { supportsSelectOptionsCardFeature } from "../../card-features/hui-select-options-card-feature";
|
||||||
import { supportsTargetHumidityCardFeature } from "../../card-features/hui-target-humidity-card-feature";
|
import { supportsTargetHumidityCardFeature } from "../../card-features/hui-target-humidity-card-feature";
|
||||||
@ -71,6 +72,7 @@ const UI_FEATURE_TYPES = [
|
|||||||
"light-color-temp",
|
"light-color-temp",
|
||||||
"lock-commands",
|
"lock-commands",
|
||||||
"lock-open-door",
|
"lock-open-door",
|
||||||
|
"media-player-volume-slider",
|
||||||
"numeric-input",
|
"numeric-input",
|
||||||
"select-options",
|
"select-options",
|
||||||
"target-humidity",
|
"target-humidity",
|
||||||
@ -123,6 +125,7 @@ const SUPPORTS_FEATURE_TYPES: Record<
|
|||||||
"light-color-temp": supportsLightColorTempCardFeature,
|
"light-color-temp": supportsLightColorTempCardFeature,
|
||||||
"lock-commands": supportsLockCommandsCardFeature,
|
"lock-commands": supportsLockCommandsCardFeature,
|
||||||
"lock-open-door": supportsLockOpenDoorCardFeature,
|
"lock-open-door": supportsLockOpenDoorCardFeature,
|
||||||
|
"media-player-volume-slider": supportsMediaPlayerVolumeSliderCardFeature,
|
||||||
"numeric-input": supportsNumericInputCardFeature,
|
"numeric-input": supportsNumericInputCardFeature,
|
||||||
"select-options": supportsSelectOptionsCardFeature,
|
"select-options": supportsSelectOptionsCardFeature,
|
||||||
"target-humidity": supportsTargetHumidityCardFeature,
|
"target-humidity": supportsTargetHumidityCardFeature,
|
||||||
|
@ -6599,6 +6599,9 @@
|
|||||||
"lock-open-door": {
|
"lock-open-door": {
|
||||||
"label": "Lock open door"
|
"label": "Lock open door"
|
||||||
},
|
},
|
||||||
|
"media-player-volume-slider": {
|
||||||
|
"label": "Media player volume slider"
|
||||||
|
},
|
||||||
"vacuum-commands": {
|
"vacuum-commands": {
|
||||||
"label": "Vacuum commands",
|
"label": "Vacuum commands",
|
||||||
"commands": "Commands",
|
"commands": "Commands",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user