Use enum for media player features (#15410)

This commit is contained in:
Paul Bottein 2023-02-13 17:48:18 +01:00 committed by GitHub
parent bf5eeba0a5
commit 74512298d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 129 additions and 111 deletions

View File

@ -8,7 +8,7 @@ import { getSignedPath } from "../../data/auth";
import { import {
MediaClassBrowserSettings, MediaClassBrowserSettings,
MediaPickedEvent, MediaPickedEvent,
SUPPORT_BROWSE_MEDIA, MediaPlayerEntityFeature,
} from "../../data/media-player"; } from "../../data/media-player";
import type { MediaSelector, MediaSelectorValue } from "../../data/selector"; import type { MediaSelector, MediaSelectorValue } from "../../data/selector";
import type { HomeAssistant } from "../../types"; import type { HomeAssistant } from "../../types";
@ -80,7 +80,8 @@ export class HaMediaSelector extends LitElement {
const supportsBrowse = const supportsBrowse =
!this.value?.entity_id || !this.value?.entity_id ||
(stateObj && supportsFeature(stateObj, SUPPORT_BROWSE_MEDIA)); (stateObj &&
supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA));
return html`<ha-entity-picker return html`<ha-entity-picker
.hass=${this.hass} .hass=${this.hass}

View File

@ -76,23 +76,28 @@ export interface MediaPlayerEntity extends HassEntityBase {
| "unknown"; | "unknown";
} }
export const SUPPORT_PAUSE = 1; export const enum MediaPlayerEntityFeature {
export const SUPPORT_SEEK = 2; PAUSE = 1,
export const SUPPORT_VOLUME_SET = 4; SEEK = 2,
export const SUPPORT_VOLUME_MUTE = 8; VOLUME_SET = 4,
export const SUPPORT_PREVIOUS_TRACK = 16; VOLUME_MUTE = 8,
export const SUPPORT_NEXT_TRACK = 32; PREVIOUS_TRACK = 16,
export const SUPPORT_TURN_ON = 128; NEXT_TRACK = 32,
export const SUPPORT_TURN_OFF = 256;
export const SUPPORT_PLAY_MEDIA = 512; TURN_ON = 128,
export const SUPPORT_VOLUME_BUTTONS = 1024; TURN_OFF = 256,
export const SUPPORT_SELECT_SOURCE = 2048; PLAY_MEDIA = 512,
export const SUPPORT_STOP = 4096; VOLUME_BUTTONS = 1024,
export const SUPPORT_PLAY = 16384; SELECT_SOURCE = 2048,
export const SUPPORT_REPEAT_SET = 262144; STOP = 4096,
export const SUPPORT_SELECT_SOUND_MODE = 65536; CLEAR_PLAYLIST = 8192,
export const SUPPORT_SHUFFLE_SET = 32768; PLAY = 16384,
export const SUPPORT_BROWSE_MEDIA = 131072; SHUFFLE_SET = 32768,
SELECT_SOUND_MODE = 65536,
BROWSE_MEDIA = 131072,
REPEAT_SET = 262144,
GROUPING = 524288,
}
export type MediaPlayerBrowseAction = "pick" | "play"; export type MediaPlayerBrowseAction = "pick" | "play";
@ -264,7 +269,7 @@ export const computeMediaControls = (
} }
if (state === "off") { if (state === "off") {
return supportsFeature(stateObj, SUPPORT_TURN_ON) return supportsFeature(stateObj, MediaPlayerEntityFeature.TURN_ON)
? [ ? [
{ {
icon: mdiPower, icon: mdiPower,
@ -276,7 +281,7 @@ export const computeMediaControls = (
const buttons: ControlButton[] = []; const buttons: ControlButton[] = [];
if (supportsFeature(stateObj, SUPPORT_TURN_OFF)) { if (supportsFeature(stateObj, MediaPlayerEntityFeature.TURN_OFF)) {
buttons.push({ buttons.push({
icon: mdiPower, icon: mdiPower,
action: "turn_off", action: "turn_off",
@ -288,7 +293,7 @@ export const computeMediaControls = (
if ( if (
(state === "playing" || state === "paused" || assumedState) && (state === "playing" || state === "paused" || assumedState) &&
supportsFeature(stateObj, SUPPORT_SHUFFLE_SET) && supportsFeature(stateObj, MediaPlayerEntityFeature.SHUFFLE_SET) &&
useExtendedControls useExtendedControls
) { ) {
buttons.push({ buttons.push({
@ -299,7 +304,7 @@ export const computeMediaControls = (
if ( if (
(state === "playing" || state === "paused" || assumedState) && (state === "playing" || state === "paused" || assumedState) &&
supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK) supportsFeature(stateObj, MediaPlayerEntityFeature.PREVIOUS_TRACK)
) { ) {
buttons.push({ buttons.push({
icon: mdiSkipPrevious, icon: mdiSkipPrevious,
@ -310,13 +315,13 @@ export const computeMediaControls = (
if ( if (
!assumedState && !assumedState &&
((state === "playing" && ((state === "playing" &&
(supportsFeature(stateObj, SUPPORT_PAUSE) || (supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE) ||
supportsFeature(stateObj, SUPPORT_STOP))) || supportsFeature(stateObj, MediaPlayerEntityFeature.STOP))) ||
((state === "paused" || state === "idle") && ((state === "paused" || state === "idle") &&
supportsFeature(stateObj, SUPPORT_PLAY)) || supportsFeature(stateObj, MediaPlayerEntityFeature.PLAY)) ||
(state === "on" && (state === "on" &&
(supportsFeature(stateObj, SUPPORT_PLAY) || (supportsFeature(stateObj, MediaPlayerEntityFeature.PLAY) ||
supportsFeature(stateObj, SUPPORT_PAUSE)))) supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE))))
) { ) {
buttons.push({ buttons.push({
icon: icon:
@ -324,33 +329,42 @@ export const computeMediaControls = (
? mdiPlayPause ? mdiPlayPause
: state !== "playing" : state !== "playing"
? mdiPlay ? mdiPlay
: supportsFeature(stateObj, SUPPORT_PAUSE) : supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE)
? mdiPause ? mdiPause
: mdiStop, : mdiStop,
action: action:
state !== "playing" state !== "playing"
? "media_play" ? "media_play"
: supportsFeature(stateObj, SUPPORT_PAUSE) : supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE)
? "media_pause" ? "media_pause"
: "media_stop", : "media_stop",
}); });
} }
if (assumedState && supportsFeature(stateObj, SUPPORT_PLAY)) { if (
assumedState &&
supportsFeature(stateObj, MediaPlayerEntityFeature.PLAY)
) {
buttons.push({ buttons.push({
icon: mdiPlay, icon: mdiPlay,
action: "media_play", action: "media_play",
}); });
} }
if (assumedState && supportsFeature(stateObj, SUPPORT_PAUSE)) { if (
assumedState &&
supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE)
) {
buttons.push({ buttons.push({
icon: mdiPause, icon: mdiPause,
action: "media_pause", action: "media_pause",
}); });
} }
if (assumedState && supportsFeature(stateObj, SUPPORT_STOP)) { if (
assumedState &&
supportsFeature(stateObj, MediaPlayerEntityFeature.STOP)
) {
buttons.push({ buttons.push({
icon: mdiStop, icon: mdiStop,
action: "media_stop", action: "media_stop",
@ -359,7 +373,7 @@ export const computeMediaControls = (
if ( if (
(state === "playing" || state === "paused" || assumedState) && (state === "playing" || state === "paused" || assumedState) &&
supportsFeature(stateObj, SUPPORT_NEXT_TRACK) supportsFeature(stateObj, MediaPlayerEntityFeature.NEXT_TRACK)
) { ) {
buttons.push({ buttons.push({
icon: mdiSkipNext, icon: mdiSkipNext,
@ -369,7 +383,7 @@ export const computeMediaControls = (
if ( if (
(state === "playing" || state === "paused" || assumedState) && (state === "playing" || state === "paused" || assumedState) &&
supportsFeature(stateObj, SUPPORT_REPEAT_SET) && supportsFeature(stateObj, MediaPlayerEntityFeature.REPEAT_SET) &&
useExtendedControls useExtendedControls
) { ) {
buttons.push({ buttons.push({

View File

@ -25,13 +25,8 @@ import {
handleMediaControlClick, handleMediaControlClick,
MediaPickedEvent, MediaPickedEvent,
MediaPlayerEntity, MediaPlayerEntity,
MediaPlayerEntityFeature,
mediaPlayerPlayMedia, mediaPlayerPlayMedia,
SUPPORT_BROWSE_MEDIA,
SUPPORT_SELECT_SOUND_MODE,
SUPPORT_SELECT_SOURCE,
SUPPORT_VOLUME_BUTTONS,
SUPPORT_VOLUME_MUTE,
SUPPORT_VOLUME_SET,
} from "../../../data/media-player"; } from "../../../data/media-player";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
@ -68,7 +63,7 @@ class MoreInfoMediaPlayer extends LitElement {
` `
)} )}
</div> </div>
${supportsFeature(stateObj, SUPPORT_BROWSE_MEDIA) ${supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA)
? html` ? html`
<mwc-button <mwc-button
.label=${this.hass.localize( .label=${this.hass.localize(
@ -85,12 +80,12 @@ class MoreInfoMediaPlayer extends LitElement {
` `
: ""} : ""}
</div> </div>
${(supportsFeature(stateObj, SUPPORT_VOLUME_SET) || ${(supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_SET) ||
supportsFeature(stateObj, SUPPORT_VOLUME_BUTTONS)) && supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_BUTTONS)) &&
![UNAVAILABLE, UNKNOWN, "off"].includes(stateObj.state) ![UNAVAILABLE, UNKNOWN, "off"].includes(stateObj.state)
? html` ? html`
<div class="volume"> <div class="volume">
${supportsFeature(stateObj, SUPPORT_VOLUME_MUTE) ${supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_MUTE)
? html` ? html`
<ha-icon-button <ha-icon-button
.path=${stateObj.attributes.is_volume_muted .path=${stateObj.attributes.is_volume_muted
@ -107,7 +102,10 @@ class MoreInfoMediaPlayer extends LitElement {
></ha-icon-button> ></ha-icon-button>
` `
: ""} : ""}
${supportsFeature(stateObj, SUPPORT_VOLUME_BUTTONS) ${supportsFeature(
stateObj,
MediaPlayerEntityFeature.VOLUME_BUTTONS
)
? html` ? html`
<ha-icon-button <ha-icon-button
action="volume_down" action="volume_down"
@ -127,7 +125,7 @@ class MoreInfoMediaPlayer extends LitElement {
></ha-icon-button> ></ha-icon-button>
` `
: ""} : ""}
${supportsFeature(stateObj, SUPPORT_VOLUME_SET) ${supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_SET)
? html` ? html`
<ha-slider <ha-slider
id="input" id="input"
@ -143,7 +141,7 @@ class MoreInfoMediaPlayer extends LitElement {
` `
: ""} : ""}
${![UNAVAILABLE, UNKNOWN, "off"].includes(stateObj.state) && ${![UNAVAILABLE, UNKNOWN, "off"].includes(stateObj.state) &&
supportsFeature(stateObj, SUPPORT_SELECT_SOURCE) && supportsFeature(stateObj, MediaPlayerEntityFeature.SELECT_SOURCE) &&
stateObj.attributes.source_list?.length stateObj.attributes.source_list?.length
? html` ? html`
<div class="source-input"> <div class="source-input">
@ -168,7 +166,7 @@ class MoreInfoMediaPlayer extends LitElement {
` `
: ""} : ""}
${![UNAVAILABLE, UNKNOWN, "off"].includes(stateObj.state) && ${![UNAVAILABLE, UNKNOWN, "off"].includes(stateObj.state) &&
supportsFeature(stateObj, SUPPORT_SELECT_SOUND_MODE) && supportsFeature(stateObj, MediaPlayerEntityFeature.SELECT_SOUND_MODE) &&
stateObj.attributes.sound_mode_list?.length stateObj.attributes.sound_mode_list?.length
? html` ? html`
<div class="sound-input"> <div class="sound-input">

View File

@ -14,7 +14,7 @@ import "../../../../components/ha-select";
import "../../../../components/ha-textarea"; import "../../../../components/ha-textarea";
import type { HaTextArea } from "../../../../components/ha-textarea"; import type { HaTextArea } from "../../../../components/ha-textarea";
import { showAutomationEditor } from "../../../../data/automation"; import { showAutomationEditor } from "../../../../data/automation";
import { SUPPORT_PLAY_MEDIA } from "../../../../data/media-player"; import { MediaPlayerEntityFeature } from "../../../../data/media-player";
import { convertTextToSpeech } from "../../../../data/tts"; import { convertTextToSpeech } from "../../../../data/tts";
import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box"; import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box";
import { haStyleDialog } from "../../../../resources/styles"; import { haStyleDialog } from "../../../../resources/styles";
@ -94,7 +94,7 @@ export class DialogTryTts extends LitElement {
.filter( .filter(
(entity) => (entity) =>
computeStateDomain(entity) === "media_player" && computeStateDomain(entity) === "media_player" &&
supportsFeature(entity, SUPPORT_PLAY_MEDIA) supportsFeature(entity, MediaPlayerEntityFeature.PLAY_MEDIA)
) )
.map( .map(
(entity) => html` (entity) => html`

View File

@ -31,10 +31,8 @@ import {
handleMediaControlClick, handleMediaControlClick,
MediaPickedEvent, MediaPickedEvent,
MediaPlayerEntity, MediaPlayerEntity,
MediaPlayerEntityFeature,
mediaPlayerPlayMedia, mediaPlayerPlayMedia,
SUPPORT_BROWSE_MEDIA,
SUPPORT_SEEK,
SUPPORT_TURN_ON,
} from "../../../data/media-player"; } from "../../../data/media-player";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import { findEntities } from "../common/find-entities"; import { findEntities } from "../common/find-entities";
@ -174,7 +172,8 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
const isOffState = entityState === "off"; const isOffState = entityState === "off";
const isUnavailable = const isUnavailable =
isUnavailableState(entityState) || isUnavailableState(entityState) ||
(entityState === "off" && !supportsFeature(stateObj, SUPPORT_TURN_ON)); (entityState === "off" &&
!supportsFeature(stateObj, MediaPlayerEntityFeature.TURN_ON));
const hasNoImage = !this._image; const hasNoImage = !this._image;
const controls = computeMediaControls(stateObj, false); const controls = computeMediaControls(stateObj, false);
const showControls = const showControls =
@ -282,7 +281,10 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
</ha-icon-button> </ha-icon-button>
` `
)} )}
${supportsFeature(stateObj, SUPPORT_BROWSE_MEDIA) ${supportsFeature(
stateObj,
MediaPlayerEntityFeature.BROWSE_MEDIA
)
? html` ? html`
<ha-icon-button <ha-icon-button
class="browse-media" class="browse-media"
@ -305,7 +307,10 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
style=${styleMap({ style=${styleMap({
"--mdc-theme-primary": "--mdc-theme-primary":
this._foregroundColor || "var(--accent-color)", this._foregroundColor || "var(--accent-color)",
cursor: supportsFeature(stateObj, SUPPORT_SEEK) cursor: supportsFeature(
stateObj,
MediaPlayerEntityFeature.SEEK
)
? "pointer" ? "pointer"
: "initial", : "initial",
})} })}
@ -522,7 +527,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
private _handleSeek(e: MouseEvent): void { private _handleSeek(e: MouseEvent): void {
const stateObj = this._stateObj!; const stateObj = this._stateObj!;
if (!supportsFeature(stateObj, SUPPORT_SEEK)) { if (!supportsFeature(stateObj, MediaPlayerEntityFeature.SEEK)) {
return; return;
} }

View File

@ -32,16 +32,7 @@ import {
computeMediaDescription, computeMediaDescription,
ControlButton, ControlButton,
MediaPlayerEntity, MediaPlayerEntity,
SUPPORT_NEXT_TRACK, MediaPlayerEntityFeature,
SUPPORT_PAUSE,
SUPPORT_PLAY,
SUPPORT_PREVIOUS_TRACK,
SUPPORT_STOP,
SUPPORT_TURN_OFF,
SUPPORT_TURN_ON,
SUPPORT_VOLUME_BUTTONS,
SUPPORT_VOLUME_MUTE,
SUPPORT_VOLUME_SET,
} from "../../../data/media-player"; } from "../../../data/media-player";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import { hasConfigOrEntityChanged } from "../common/has-changed"; import { hasConfigOrEntityChanged } from "../common/has-changed";
@ -115,7 +106,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
const buttons = html` const buttons = html`
${!this._narrow && ${!this._narrow &&
(entityState === "playing" || assumedState) && (entityState === "playing" || assumedState) &&
supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK) supportsFeature(stateObj, MediaPlayerEntityFeature.PREVIOUS_TRACK)
? html` ? html`
<ha-icon-button <ha-icon-button
.path=${mdiSkipPrevious} .path=${mdiSkipPrevious}
@ -128,13 +119,13 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
: ""} : ""}
${!assumedState && ${!assumedState &&
((entityState === "playing" && ((entityState === "playing" &&
(supportsFeature(stateObj, SUPPORT_PAUSE) || (supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE) ||
supportsFeature(stateObj, SUPPORT_STOP))) || supportsFeature(stateObj, MediaPlayerEntityFeature.STOP))) ||
((entityState === "paused" || entityState === "idle") && ((entityState === "paused" || entityState === "idle") &&
supportsFeature(stateObj, SUPPORT_PLAY)) || supportsFeature(stateObj, MediaPlayerEntityFeature.PLAY)) ||
(entityState === "on" && (entityState === "on" &&
(supportsFeature(stateObj, SUPPORT_PLAY) || (supportsFeature(stateObj, MediaPlayerEntityFeature.PLAY) ||
supportsFeature(stateObj, SUPPORT_PAUSE)))) supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE))))
? html` ? html`
<ha-icon-button <ha-icon-button
.path=${controlButton.icon} .path=${controlButton.icon}
@ -145,7 +136,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
></ha-icon-button> ></ha-icon-button>
` `
: ""} : ""}
${assumedState && supportsFeature(stateObj, SUPPORT_PLAY) ${assumedState && supportsFeature(stateObj, MediaPlayerEntityFeature.PLAY)
? html` ? html`
<ha-icon-button <ha-icon-button
.path=${mdiPlay} .path=${mdiPlay}
@ -154,7 +145,8 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
></ha-icon-button> ></ha-icon-button>
` `
: ""} : ""}
${assumedState && supportsFeature(stateObj, SUPPORT_PAUSE) ${assumedState &&
supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE)
? html` ? html`
<ha-icon-button <ha-icon-button
.path=${mdiPause} .path=${mdiPause}
@ -164,8 +156,8 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
` `
: ""} : ""}
${assumedState && ${assumedState &&
supportsFeature(stateObj, SUPPORT_STOP) && supportsFeature(stateObj, MediaPlayerEntityFeature.STOP) &&
!supportsFeature(stateObj, SUPPORT_VOLUME_SET) !supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_SET)
? html` ? html`
<ha-icon-button <ha-icon-button
.path=${mdiStop} .path=${mdiStop}
@ -175,8 +167,9 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
` `
: ""} : ""}
${(entityState === "playing" || ${(entityState === "playing" ||
(assumedState && !supportsFeature(stateObj, SUPPORT_VOLUME_SET))) && (assumedState &&
supportsFeature(stateObj, SUPPORT_NEXT_TRACK) !supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_SET))) &&
supportsFeature(stateObj, MediaPlayerEntityFeature.NEXT_TRACK)
? html` ? html`
<ha-icon-button <ha-icon-button
.path=${mdiSkipNext} .path=${mdiSkipNext}
@ -204,7 +197,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
)} )}
> >
<div class="controls"> <div class="controls">
${supportsFeature(stateObj, SUPPORT_TURN_ON) && ${supportsFeature(stateObj, MediaPlayerEntityFeature.TURN_ON) &&
entityState === "off" && entityState === "off" &&
!isUnavailableState(entityState) !isUnavailableState(entityState)
? html` ? html`
@ -214,11 +207,14 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
@click=${this._togglePower} @click=${this._togglePower}
></ha-icon-button> ></ha-icon-button>
` `
: !supportsFeature(stateObj, SUPPORT_VOLUME_SET) && : !supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_SET) &&
!supportsFeature(stateObj, SUPPORT_VOLUME_BUTTONS) !supportsFeature(
stateObj,
MediaPlayerEntityFeature.VOLUME_BUTTONS
)
? buttons ? buttons
: ""} : ""}
${supportsFeature(stateObj, SUPPORT_TURN_OFF) && ${supportsFeature(stateObj, MediaPlayerEntityFeature.TURN_OFF) &&
entityState !== "off" && entityState !== "off" &&
!isUnavailableState(entityState) !isUnavailableState(entityState)
? html` ? html`
@ -231,13 +227,16 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
: ""} : ""}
</div> </div>
</hui-generic-entity-row> </hui-generic-entity-row>
${(supportsFeature(stateObj, SUPPORT_VOLUME_SET) || ${(supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_SET) ||
supportsFeature(stateObj, SUPPORT_VOLUME_BUTTONS)) && supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_BUTTONS)) &&
![UNAVAILABLE, UNKNOWN, "off"].includes(entityState) ![UNAVAILABLE, UNKNOWN, "off"].includes(entityState)
? html` ? html`
<div class="flex"> <div class="flex">
<div class="volume"> <div class="volume">
${supportsFeature(stateObj, SUPPORT_VOLUME_MUTE) ${supportsFeature(
stateObj,
MediaPlayerEntityFeature.VOLUME_MUTE
)
? html` ? html`
<ha-icon-button <ha-icon-button
.path=${stateObj.attributes.is_volume_muted .path=${stateObj.attributes.is_volume_muted
@ -255,7 +254,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
` `
: ""} : ""}
${!this._veryNarrow && ${!this._veryNarrow &&
supportsFeature(stateObj, SUPPORT_VOLUME_SET) supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_SET)
? html` ? html`
<ha-slider <ha-slider
.dir=${computeRTLDirection(this.hass!)} .dir=${computeRTLDirection(this.hass!)}
@ -267,7 +266,10 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
></ha-slider> ></ha-slider>
` `
: !this._veryNarrow && : !this._veryNarrow &&
supportsFeature(stateObj, SUPPORT_VOLUME_BUTTONS) supportsFeature(
stateObj,
MediaPlayerEntityFeature.VOLUME_BUTTONS
)
? html` ? html`
<ha-icon-button <ha-icon-button
.path=${mdiVolumeMinus} .path=${mdiVolumeMinus}
@ -317,7 +319,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
? { icon: mdiPlayPause, action: "media_play_pause" } ? { icon: mdiPlayPause, action: "media_play_pause" }
: stateObj.state !== "playing" : stateObj.state !== "playing"
? { icon: mdiPlay, action: "media_play" } ? { icon: mdiPlay, action: "media_play" }
: supportsFeature(stateObj, SUPPORT_PAUSE) : supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE)
? { icon: mdiPause, action: "media_pause" } ? { icon: mdiPause, action: "media_pause" }
: { icon: mdiStop, action: "media_stop" }; : { icon: mdiStop, action: "media_stop" };
} }
@ -340,7 +342,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
const service = const service =
stateObj.state !== "playing" stateObj.state !== "playing"
? "media_play" ? "media_play"
: supportsFeature(stateObj, SUPPORT_PAUSE) : supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE)
? "media_pause" ? "media_pause"
: "media_stop"; : "media_stop";

View File

@ -1,10 +1,8 @@
import { import {
BROWSER_PLAYER, BROWSER_PLAYER,
MediaPlayerEntity, MediaPlayerEntity,
MediaPlayerEntityFeature,
MediaPlayerItem, MediaPlayerItem,
SUPPORT_PAUSE,
SUPPORT_PLAY,
SUPPORT_VOLUME_SET,
} from "../../data/media-player"; } from "../../data/media-player";
import { ResolvedMediaSource } from "../../data/media_source"; import { ResolvedMediaSource } from "../../data/media_source";
import { HomeAssistant } from "../../types"; import { HomeAssistant } from "../../types";
@ -96,8 +94,12 @@ export class BrowserMediaPlayer {
media_title: this.item.title, media_title: this.item.title,
entity_picture: this.item.thumbnail, entity_picture: this.item.thumbnail,
volume_level: this.player.volume, volume_level: this.player.volume,
supported_features:
// eslint-disable-next-line no-bitwise // eslint-disable-next-line no-bitwise
supported_features: SUPPORT_PLAY | SUPPORT_PAUSE | SUPPORT_VOLUME_SET, MediaPlayerEntityFeature.PLAY |
// eslint-disable-next-line no-bitwise
MediaPlayerEntityFeature.PAUSE |
MediaPlayerEntityFeature.VOLUME_SET,
}; };
if (this.player.duration) { if (this.player.duration) {

View File

@ -29,8 +29,8 @@ import { computeStateDomain } from "../../common/entity/compute_state_domain";
import { computeStateName } from "../../common/entity/compute_state_name"; import { computeStateName } from "../../common/entity/compute_state_name";
import { domainIcon } from "../../common/entity/domain_icon"; import { domainIcon } from "../../common/entity/domain_icon";
import { supportsFeature } from "../../common/entity/supports-feature"; import { supportsFeature } from "../../common/entity/supports-feature";
import "../../components/ha-button-menu";
import "../../components/ha-button"; import "../../components/ha-button";
import "../../components/ha-button-menu";
import "../../components/ha-circular-progress"; import "../../components/ha-circular-progress";
import "../../components/ha-icon-button"; import "../../components/ha-icon-button";
import { UNAVAILABLE } from "../../data/entity"; import { UNAVAILABLE } from "../../data/entity";
@ -45,13 +45,9 @@ import {
getCurrentProgress, getCurrentProgress,
handleMediaControlClick, handleMediaControlClick,
MediaPlayerEntity, MediaPlayerEntity,
MediaPlayerEntityFeature,
MediaPlayerItem, MediaPlayerItem,
setMediaPlayerVolume, setMediaPlayerVolume,
SUPPORT_BROWSE_MEDIA,
SUPPORT_PAUSE,
SUPPORT_PLAY,
SUPPORT_STOP,
SUPPORT_VOLUME_SET,
} from "../../data/media-player"; } from "../../data/media-player";
import { ResolvedMediaSource } from "../../data/media_source"; import { ResolvedMediaSource } from "../../data/media_source";
import { showAlertDialog } from "../../dialogs/generic/show-dialog-box"; import { showAlertDialog } from "../../dialogs/generic/show-dialog-box";
@ -184,13 +180,13 @@ export class BarMediaPlayer extends SubscribeMixin(LitElement) {
const controls: ControlButton[] | undefined = !this.narrow const controls: ControlButton[] | undefined = !this.narrow
? computeMediaControls(stateObj, true) ? computeMediaControls(stateObj, true)
: (stateObj.state === "playing" && : (stateObj.state === "playing" &&
(supportsFeature(stateObj, SUPPORT_PAUSE) || (supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE) ||
supportsFeature(stateObj, SUPPORT_STOP))) || supportsFeature(stateObj, MediaPlayerEntityFeature.STOP))) ||
((stateObj.state === "paused" || stateObj.state === "idle") && ((stateObj.state === "paused" || stateObj.state === "idle") &&
supportsFeature(stateObj, SUPPORT_PLAY)) || supportsFeature(stateObj, MediaPlayerEntityFeature.PLAY)) ||
(stateObj.state === "on" && (stateObj.state === "on" &&
(supportsFeature(stateObj, SUPPORT_PLAY) || (supportsFeature(stateObj, MediaPlayerEntityFeature.PLAY) ||
supportsFeature(stateObj, SUPPORT_PAUSE))) supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE)))
? [ ? [
{ {
icon: icon:
@ -198,13 +194,13 @@ export class BarMediaPlayer extends SubscribeMixin(LitElement) {
? mdiPlayPause ? mdiPlayPause
: stateObj.state !== "playing" : stateObj.state !== "playing"
? mdiPlay ? mdiPlay
: supportsFeature(stateObj, SUPPORT_PAUSE) : supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE)
? mdiPause ? mdiPause
: mdiStop, : mdiStop,
action: action:
stateObj.state !== "playing" stateObj.state !== "playing"
? "media_play" ? "media_play"
: supportsFeature(stateObj, SUPPORT_PAUSE) : supportsFeature(stateObj, MediaPlayerEntityFeature.PAUSE)
? "media_pause" ? "media_pause"
: "media_stop", : "media_stop",
}, },
@ -292,7 +288,7 @@ export class BarMediaPlayer extends SubscribeMixin(LitElement) {
${ ${
!this.narrow && !this.narrow &&
stateObj && stateObj &&
supportsFeature(stateObj, SUPPORT_VOLUME_SET) supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_SET)
? html` ? html`
<ha-button-menu corner="BOTTOM_START" y="0" x="76"> <ha-button-menu corner="BOTTOM_START" y="0" x="76">
<ha-icon-button <ha-icon-button
@ -470,7 +466,7 @@ export class BarMediaPlayer extends SubscribeMixin(LitElement) {
return Object.values(this.hass!.states).filter( return Object.values(this.hass!.states).filter(
(entity) => (entity) =>
computeStateDomain(entity) === "media_player" && computeStateDomain(entity) === "media_player" &&
supportsFeature(entity, SUPPORT_BROWSE_MEDIA) && supportsFeature(entity, MediaPlayerEntityFeature.BROWSE_MEDIA) &&
!this._hiddenEntities.has(entity.entity_id) !this._hiddenEntities.has(entity.entity_id)
); );
} }