Skip to content

Commit

Permalink
refactor(media-player): rename commands to media_controls
Browse files Browse the repository at this point in the history
  • Loading branch information
piitaya committed Apr 15, 2022
1 parent 8ac2213 commit d9235dc
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ import { computeRTL, HomeAssistant } from "custom-card-helpers";
import { html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js";
import { MediaPlayerEntity } from "../../../ha/data/media-player";
import { MediaPlayerCommand } from "../media-player-card-config";
import { MediaPlayerMediaControl } from "../media-player-card-config";
import { computeMediaControls, handleMediaControlClick } from "../utils";

export const isCommandsControlVisible = (
export const isMediaControlVisible = (
entity: MediaPlayerEntity,
commands: MediaPlayerCommand[]
) => computeMediaControls(entity, commands).length > 0;
controls?: MediaPlayerMediaControl[]
) => computeMediaControls(entity, controls ?? []).length > 0;

@customElement("mushroom-media-player-commands-control")
export class MediaPlayerCommandsControl extends LitElement {
@customElement("mushroom-media-player-media-control")
export class MediaPlayerMediaControls extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@property({ attribute: false }) public entity!: MediaPlayerEntity;

@property({ attribute: false }) public commands!: MediaPlayerCommand[];
@property({ attribute: false }) public controls!: MediaPlayerMediaControl[];

@property() public fill: boolean = false;

Expand All @@ -29,7 +29,7 @@ export class MediaPlayerCommandsControl extends LitElement {
protected render(): TemplateResult {
const rtl = computeRTL(this.hass);

const controls = computeMediaControls(this.entity, this.commands);
const controls = computeMediaControls(this.entity, this.controls);

return html`
<mushroom-button-group .fill=${this.fill} ?rtl=${rtl}>
Expand Down
22 changes: 10 additions & 12 deletions src/cards/media-player-card/controls/media-player-volume-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,28 @@ import {
MEDIA_PLAYER_SUPPORT_VOLUME_MUTE,
MEDIA_PLAYER_SUPPORT_VOLUME_SET,
} from "../../../ha/data/media-player";
import { MediaPlayerVolumeControlMode } from "../media-player-card-config";
import { MediaPlayerVolumeControl } from "../media-player-card-config";
import { getVolumeLevel, handleMediaControlClick } from "../utils";

export const isVolumeControlVisible = (
entity: MediaPlayerEntity,
volume_controls?: MediaPlayerVolumeControlMode[]
controls?: MediaPlayerVolumeControl[]
) =>
(volume_controls?.includes("volume_buttons") &&
(controls?.includes("volume_buttons") &&
supportsFeature(entity, MEDIA_PLAYER_SUPPORT_VOLUME_BUTTONS)) ||
(volume_controls?.includes("volume_mute") &&
(controls?.includes("volume_mute") &&
supportsFeature(entity, MEDIA_PLAYER_SUPPORT_VOLUME_MUTE)) ||
(volume_controls?.includes("volume_set") &&
supportsFeature(entity, MEDIA_PLAYER_SUPPORT_VOLUME_SET));
(controls?.includes("volume_set") && supportsFeature(entity, MEDIA_PLAYER_SUPPORT_VOLUME_SET));

@customElement("mushroom-media-player-volume-control")
export class MediaPlayerVolumeControlComponent extends LitElement {
export class MediaPlayerVolumeControls extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@property({ attribute: false }) public entity!: MediaPlayerEntity;

@property() public fill: boolean = false;

@property({ attribute: false }) public volume_controls!: MediaPlayerVolumeControlMode[];
@property({ attribute: false }) public controls!: MediaPlayerVolumeControl[];

private handleSliderChange(e: CustomEvent<{ value: number }>): void {
const value = e.detail.value;
Expand All @@ -44,7 +43,6 @@ export class MediaPlayerVolumeControlComponent extends LitElement {
private handleClick(e: MouseEvent): void {
e.stopPropagation();
const action = (e.target! as any).action as string;
console.log(action);
handleMediaControlClick(this.hass, this.entity, action!);
}

Expand All @@ -56,15 +54,15 @@ export class MediaPlayerVolumeControlComponent extends LitElement {
const rtl = computeRTL(this.hass);

const displayVolumeSet =
this.volume_controls?.includes("volume_set") &&
this.controls?.includes("volume_set") &&
supportsFeature(this.entity, MEDIA_PLAYER_SUPPORT_VOLUME_SET);

const displayVolumeMute =
this.volume_controls?.includes("volume_mute") &&
this.controls?.includes("volume_mute") &&
supportsFeature(this.entity, MEDIA_PLAYER_SUPPORT_VOLUME_MUTE);

const displayVolumeButtons =
this.volume_controls?.includes("volume_buttons") &&
this.controls?.includes("volume_buttons") &&
supportsFeature(this.entity, MEDIA_PLAYER_SUPPORT_VOLUME_BUTTONS);

return html`
Expand Down
14 changes: 7 additions & 7 deletions src/cards/media-player-card/media-player-card-config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ActionConfig, LovelaceCardConfig } from "custom-card-helpers";
import { array, assign, boolean, enums, object, optional, string } from "superstruct";
import { array, assign, enums, object, optional, string } from "superstruct";
import { actionConfigStruct } from "../../utils/action-struct";
import { baseLovelaceCardConfig } from "../../utils/editor-styles";
import { Layout, layoutStruct } from "../../utils/layout";

export const MEDIA_PLAYER_COMMANDS = [
export const MEDIA_LAYER_MEDIA_CONTROLS = [
"on_off",
"shuffle",
"previous",
Expand All @@ -13,22 +13,22 @@ export const MEDIA_PLAYER_COMMANDS = [
"repeat",
] as const;

export type MediaPlayerCommand = typeof MEDIA_PLAYER_COMMANDS[number];
export type MediaPlayerMediaControl = typeof MEDIA_LAYER_MEDIA_CONTROLS[number];

export const MEDIA_PLAYER_VOLUME_CONTROLS = [
"volume_mute",
"volume_set",
"volume_buttons",
] as const;

export type MediaPlayerVolumeControlMode = typeof MEDIA_PLAYER_VOLUME_CONTROLS[number];
export type MediaPlayerVolumeControl = typeof MEDIA_PLAYER_VOLUME_CONTROLS[number];

export interface MediaPlayerCardConfig extends LovelaceCardConfig {
entity?: string;
name?: string;
icon?: string;
volume_controls?: MediaPlayerVolumeControlMode[];
commands?: MediaPlayerCommand[];
volume_controls?: MediaPlayerVolumeControl[];
media_controls?: MediaPlayerMediaControl[];
layout?: Layout;
tap_action?: ActionConfig;
hold_action?: ActionConfig;
Expand All @@ -42,7 +42,7 @@ export const mediaPlayerCardConfigStruct = assign(
icon: optional(string()),
name: optional(string()),
volume_controls: optional(array(enums(MEDIA_PLAYER_VOLUME_CONTROLS))),
commands: optional(array(enums(MEDIA_PLAYER_COMMANDS))),
media_controls: optional(array(enums(MEDIA_LAYER_MEDIA_CONTROLS))),
layout: optional(layoutStruct),
tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct),
Expand Down
14 changes: 8 additions & 6 deletions src/cards/media-player-card/media-player-card-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import { MEDIA_PLAYER_CARD_EDITOR_NAME, MEDIA_PLAYER_ENTITY_DOMAINS } from "./co
import {
MediaPlayerCardConfig,
mediaPlayerCardConfigStruct,
MEDIA_PLAYER_COMMANDS,
MEDIA_LAYER_MEDIA_CONTROLS,
MEDIA_PLAYER_VOLUME_CONTROLS,
} from "./media-player-card-config";

export const MEDIA_FIELDS = ["commands", "volume_controls"];
export const MEDIA_FIELDS = ["media_controls", "volume_controls"];

const computeSchema = memoizeOne((localize: LocalizeFunc, icon?: string): HaFormSchema[] => [
{ name: "entity", selector: { entity: { domain: MEDIA_PLAYER_ENTITY_DOMAINS } } },
Expand Down Expand Up @@ -52,12 +52,14 @@ const computeSchema = memoizeOne((localize: LocalizeFunc, icon?: string): HaForm
},
},
{
name: "commands",
name: "media_controls",
selector: {
select: {
options: MEDIA_PLAYER_COMMANDS.map((command) => ({
value: command,
label: localize(`editor.card.media-player.commands_list.${command}`),
options: MEDIA_LAYER_MEDIA_CONTROLS.map((control) => ({
value: control,
label: localize(
`editor.card.media-player.media_controls_list.${control}`
),
})),
mode: "list",
multiple: true,
Expand Down
37 changes: 15 additions & 22 deletions src/cards/media-player-card/media-player-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,8 @@ import {
import { css, CSSResultGroup, html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { styleMap } from "lit/directives/style-map.js";
import { supportsFeature } from "../../ha/common/entity/supports-feature";
import { isActive } from "../../ha/data/entity";
import {
MediaPlayerEntity,
MEDIA_PLAYER_SUPPORT_VOLUME_BUTTONS,
MEDIA_PLAYER_SUPPORT_VOLUME_MUTE,
MEDIA_PLAYER_SUPPORT_VOLUME_SET,
} from "../../ha/data/media-player";
import { MediaPlayerEntity } from "../../ha/data/media-player";
import { cardStyle } from "../../utils/card-styles";
import { registerCustomCard } from "../../utils/custom-cards";
import { actionHandler } from "../../utils/directives/action-handler-directive";
Expand All @@ -27,17 +21,17 @@ import {
MEDIA_PLAYER_CARD_NAME,
MEDIA_PLAYER_ENTITY_DOMAINS,
} from "./const";
import "./controls/media-player-commands-control";
import { isCommandsControlVisible } from "./controls/media-player-commands-control";
import "./controls/media-player-media-control";
import { isMediaControlVisible } from "./controls/media-player-media-control";
import "./controls/media-player-volume-control";
import { isVolumeControlVisible } from "./controls/media-player-volume-control";
import { MediaPlayerCardConfig } from "./media-player-card-config";
import { computeIcon, getCardName, getStateDisplay } from "./utils";

type MediaPlayerCardControl = "commands_control" | "volume_control";
type MediaPlayerCardControl = "media_control" | "volume_control";

const CONTROLS_ICONS: Record<MediaPlayerCardControl, string> = {
commands_control: "mdi:play-pause",
media_control: "mdi:play-pause",
volume_control: "mdi:volume-high",
};

Expand Down Expand Up @@ -110,14 +104,13 @@ export class MediaPlayerCard extends LitElement implements LovelaceCard {

const entity_id = this._config.entity;
const entity = this.hass.states[entity_id] as MediaPlayerEntity;
const commands = this._config?.commands ?? [];

if (!entity) return;

const controls: MediaPlayerCardControl[] = [];

if (isCommandsControlVisible(entity, commands)) {
controls.push("commands_control");
if (isMediaControlVisible(entity, this._config?.media_controls)) {
controls.push("media_control");
}
if (isVolumeControlVisible(entity, this._config.volume_controls)) {
controls.push("volume_control");
Expand Down Expand Up @@ -213,26 +206,26 @@ export class MediaPlayerCard extends LitElement implements LovelaceCard {
}

private renderActiveControl(entity: MediaPlayerEntity, layout: Layout): TemplateResult | null {
const commands = this._config?.commands ?? [];
const volume_controls = this._config?.volume_controls ?? "none";
const media_controls = this._config?.media_controls ?? [];
const volume_controls = this._config?.volume_controls ?? [];

switch (this._activeControl) {
case "commands_control":
case "media_control":
return html`
<mushroom-media-player-commands-control
<mushroom-media-player-media-control
.hass=${this.hass}
.entity=${entity}
.commands=${commands}
.controls=${media_controls}
.fill=${layout !== "horizontal"}
>
</mushroom-media-player-commands-control>
</mushroom-media-player-media-control>
`;
case "volume_control":
return html`
<mushroom-media-player-volume-control
.hass=${this.hass}
.entity=${entity}
.volume_controls=${volume_controls}
.controls=${volume_controls}
.fill=${layout !== "horizontal"}
/>
`;
Expand All @@ -248,7 +241,7 @@ export class MediaPlayerCard extends LitElement implements LovelaceCard {
mushroom-state-item {
cursor: pointer;
}
mushroom-media-player-commands-control,
mushroom-media-player-media-control,
mushroom-media-player-volume-control {
flex: 1;
}
Expand Down
25 changes: 12 additions & 13 deletions src/cards/media-player-card/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
MEDIA_PLAYER_SUPPORT_TURN_ON,
MEDIA_PLAYER_SUPPORT_VOLUME_SET,
} from "../../ha/data/media-player";
import { MediaPlayerCardConfig, MediaPlayerCommand } from "./media-player-card-config";
import { MediaPlayerCardConfig, MediaPlayerMediaControl } from "./media-player-card-config";

export function callService(
e: MouseEvent,
Expand Down Expand Up @@ -87,7 +87,7 @@ export interface ControlButton {

export const computeMediaControls = (
stateObj: MediaPlayerEntity,
commands: MediaPlayerCommand[]
controls: MediaPlayerMediaControl[]
): ControlButton[] => {
if (!stateObj) {
return [];
Expand All @@ -97,7 +97,7 @@ export const computeMediaControls = (

if (state === "off") {
return supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_TURN_ON) &&
commands.includes("on_off")
controls.includes("on_off")
? [
{
icon: "mdi:power",
Expand All @@ -109,7 +109,7 @@ export const computeMediaControls = (

const buttons: ControlButton[] = [];

if (supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_TURN_OFF) && commands.includes("on_off")) {
if (supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_TURN_OFF) && controls.includes("on_off")) {
buttons.push({
icon: "mdi:power",
action: "turn_off",
Expand All @@ -122,7 +122,7 @@ export const computeMediaControls = (
if (
(state === "playing" || state === "paused" || assumedState) &&
supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_SHUFFLE_SET) &&
commands.includes("shuffle")
controls.includes("shuffle")
) {
buttons.push({
icon: stateAttr.shuffle === true ? "mdi:shuffle" : "mdi:shuffle-disabled",
Expand All @@ -133,7 +133,7 @@ export const computeMediaControls = (
if (
(state === "playing" || state === "paused" || assumedState) &&
supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_PREVIOUS_TRACK) &&
commands.includes("previous")
controls.includes("previous")
) {
buttons.push({
icon: "mdi:skip-previous",
Expand All @@ -151,7 +151,7 @@ export const computeMediaControls = (
(state === "on" &&
(supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_PLAY) ||
supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_PAUSE)))) &&
commands.includes("play_pause_stop")
controls.includes("play_pause_stop")
) {
buttons.push({
icon:
Expand All @@ -174,7 +174,7 @@ export const computeMediaControls = (
if (
assumedState &&
supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_PLAY) &&
commands.includes("play_pause_stop")
controls.includes("play_pause_stop")
) {
buttons.push({
icon: "mdi:play",
Expand All @@ -185,7 +185,7 @@ export const computeMediaControls = (
if (
assumedState &&
supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_PAUSE) &&
commands.includes("play_pause_stop")
controls.includes("play_pause_stop")
) {
buttons.push({
icon: "mdi:pause",
Expand All @@ -196,7 +196,7 @@ export const computeMediaControls = (
if (
assumedState &&
supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_STOP) &&
commands.includes("play_pause_stop")
controls.includes("play_pause_stop")
) {
buttons.push({
icon: "mdi:stop",
Expand All @@ -207,7 +207,7 @@ export const computeMediaControls = (
if (
(state === "playing" || state === "paused" || assumedState) &&
supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_NEXT_TRACK) &&
commands.includes("next")
controls.includes("next")
) {
buttons.push({
icon: "mdi:skip-next",
Expand All @@ -218,7 +218,7 @@ export const computeMediaControls = (
if (
(state === "playing" || state === "paused" || assumedState) &&
supportsFeature(stateObj, MEDIA_PLAYER_SUPPORT_REPEAT_SET) &&
commands.includes("repeat")
controls.includes("repeat")
) {
buttons.push({
icon:
Expand Down Expand Up @@ -293,7 +293,6 @@ export const handleMediaControlClick = (
};
}

console.log(action, parameters);
hass.callService("media_player", action, {
entity_id: stateObj!.entity_id,
...parameters,
Expand Down
Loading

0 comments on commit d9235dc

Please sign in to comment.