Skip to content

Commit

Permalink
feat(media-player): add media info options (#315)
Browse files Browse the repository at this point in the history
* feat(media-player): add options to show media info instead of name/state

* feat(media-player): add options to use media artwork instead of icon
  • Loading branch information
piitaya committed Apr 15, 2022
1 parent d9235dc commit 471ed71
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 40 deletions.
6 changes: 5 additions & 1 deletion src/cards/media-player-card/media-player-card-config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ActionConfig, LovelaceCardConfig } from "custom-card-helpers";
import { array, assign, enums, object, optional, string } from "superstruct";
import { array, assign, boolean, enums, object, optional, string } from "superstruct";
import { actionConfigStruct } from "../../utils/action-struct";
import { baseLovelaceCardConfig } from "../../utils/editor-styles";
import { Layout, layoutStruct } from "../../utils/layout";
Expand Down Expand Up @@ -27,6 +27,8 @@ export interface MediaPlayerCardConfig extends LovelaceCardConfig {
entity?: string;
name?: string;
icon?: string;
show_media_info?: boolean;
use_media_artwork?: boolean;
volume_controls?: MediaPlayerVolumeControl[];
media_controls?: MediaPlayerMediaControl[];
layout?: Layout;
Expand All @@ -41,6 +43,8 @@ export const mediaPlayerCardConfigStruct = assign(
entity: optional(string()),
icon: optional(string()),
name: optional(string()),
show_media_info: optional(boolean()),
use_media_artwork: optional(boolean()),
volume_controls: optional(array(enums(MEDIA_PLAYER_VOLUME_CONTROLS))),
media_controls: optional(array(enums(MEDIA_LAYER_MEDIA_CONTROLS))),
layout: optional(layoutStruct),
Expand Down
15 changes: 14 additions & 1 deletion src/cards/media-player-card/media-player-card-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ import {
MEDIA_PLAYER_VOLUME_CONTROLS,
} from "./media-player-card-config";

export const MEDIA_FIELDS = ["media_controls", "volume_controls"];
export const MEDIA_FIELDS = [
"show_media_info",
"use_media_artwork",
"media_controls",
"volume_controls",
];

const computeSchema = memoizeOne((localize: LocalizeFunc, icon?: string): HaFormSchema[] => [
{ name: "entity", selector: { entity: { domain: MEDIA_PLAYER_ENTITY_DOMAINS } } },
Expand All @@ -32,6 +37,14 @@ const computeSchema = memoizeOne((localize: LocalizeFunc, icon?: string): HaForm
name: "",
schema: [{ name: "layout", selector: { "mush-layout": {} } }],
},
{
type: "grid",
name: "",
schema: [
{ name: "show_media_info", selector: { boolean: {} } },
{ name: "use_media_artwork", selector: { boolean: {} } },
],
},
{
type: "grid",
name: "",
Expand Down
39 changes: 26 additions & 13 deletions src/cards/media-player-card/media-player-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ 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";
import { computeMediaIcon, computeMediaNameDisplay, computeMediaStateDisplay } from "./utils";
import "../../shared/badge-icon";
import "../../shared/card";
import "../../shared/shape-avatar";
import "../../shared/shape-icon";

type MediaPlayerCardControl = "media_control" | "volume_control";

Expand Down Expand Up @@ -135,17 +139,18 @@ export class MediaPlayerCard extends LitElement implements LovelaceCard {
const entity_id = this._config.entity;
const entity = this.hass.states[entity_id] as MediaPlayerEntity;

const icon = computeIcon(this._config, entity);
const icon = computeMediaIcon(this._config, entity);
const layout = getLayoutFromConfig(this._config);
const active = isActive(entity);

let iconStyle = {};

let nameDisplay = getCardName(this._config, entity);
let stateDisplay = getStateDisplay(entity, this.hass);
let nameDisplay = computeMediaNameDisplay(this._config, entity);
let stateDisplay = computeMediaStateDisplay(this._config, entity, this.hass);

const rtl = computeRTL(this.hass);

const artwork = this._config.use_media_artwork
? entity.attributes.entity_picture
: undefined;

return html`
<mushroom-card .layout=${layout} ?rtl=${rtl}>
<mushroom-state-item
Expand All @@ -157,12 +162,20 @@ export class MediaPlayerCard extends LitElement implements LovelaceCard {
hasDoubleClick: hasAction(this._config.double_tap_action),
})}
>
<mushroom-shape-icon
slot="icon"
.disabled=${!active}
.icon="${icon}"
style=${styleMap(iconStyle)}
></mushroom-shape-icon>
${artwork
? html`
<mushroom-shape-avatar
slot="icon"
.picture_url=${artwork}
></mushroom-shape-avatar>
`
: html`
<mushroom-shape-icon
slot="icon"
.icon=${icon}
.disabled=${!isActive(entity)}
></mushroom-shape-icon>
`}
${entity.state === "unavailable"
? html`
<mushroom-badge-icon
Expand Down
58 changes: 33 additions & 25 deletions src/cards/media-player-card/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,26 @@ export function callService(
});
}

export function getCardName(config: MediaPlayerCardConfig, entity: MediaPlayerEntity): string {
export function computeMediaNameDisplay(
config: MediaPlayerCardConfig,
entity: MediaPlayerEntity
): string {
let name = config.name || entity.attributes.friendly_name || "";
if (![UNAVAILABLE, UNKNOWN, OFF].includes(entity.state)) {
if (![UNAVAILABLE, UNKNOWN, OFF].includes(entity.state) && config.show_media_info) {
if (entity.attributes.media_title) {
name = entity.attributes.media_title;
}
}
return name;
}

export function getStateDisplay(entity: MediaPlayerEntity, hass: HomeAssistant): string {
export function computeMediaStateDisplay(
config: MediaPlayerCardConfig,
entity: MediaPlayerEntity,
hass: HomeAssistant
): string {
let state = computeStateDisplay(hass.localize, entity, hass.locale);
if (![UNAVAILABLE, UNKNOWN, OFF].includes(entity.state)) {
if (![UNAVAILABLE, UNKNOWN, OFF].includes(entity.state) && config.show_media_info) {
return computeMediaDescription(entity) || state;
}
return state;
Expand All @@ -54,30 +61,31 @@ export function getVolumeLevel(entity: MediaPlayerEntity) {
: undefined;
}

export function computeIcon(config: MediaPlayerCardConfig, entity: MediaPlayerEntity): string {
export function computeMediaIcon(config: MediaPlayerCardConfig, entity: MediaPlayerEntity): string {
var icon = config.icon || stateIcon(entity);

if (!entity.attributes.app_name) return icon;

var app = entity.attributes.app_name.toLowerCase();
switch (app) {
case "spotify":
return "mdi:spotify";
case "google podcasts":
return "mdi:google-podcast";
case "plex":
return "mdi:plex";
case "soundcloud":
return "mdi:soundcloud";
case "youtube":
return "mdi:youtube";
case "oto music":
return "mdi:music-circle";
case "netflix":
return "mdi:netflix";
default:
return icon;
if (![UNAVAILABLE, UNKNOWN, OFF].includes(entity.state) && config.show_media_info) {
var app = entity.attributes.app_name?.toLowerCase();
switch (app) {
case "spotify":
return "mdi:spotify";
case "google podcasts":
return "mdi:google-podcast";
case "plex":
return "mdi:plex";
case "soundcloud":
return "mdi:soundcloud";
case "youtube":
return "mdi:youtube";
case "oto music":
return "mdi:music-circle";
case "netflix":
return "mdi:netflix";
default:
return icon;
}
}
return icon;
}

export interface ControlButton {
Expand Down
2 changes: 2 additions & 0 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@
"commands": "Commands"
},
"media-player": {
"show_media_info": "Show media info",
"use_media_artwork": "Use media artwork",
"media_controls": "Media controls",
"media_controls_list": {
"on_off": "Turn on/off",
Expand Down
2 changes: 2 additions & 0 deletions src/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@
"commands": "Commandes"
},
"media-player": {
"show_media_info": "Montrer les informations sur le media",
"use_media_artwork": "Utiliser l'illustration du media",
"media_controls": "Contrôles du media",
"media_controls_list": {
"on_off": "Allumer/Éteindre",
Expand Down

0 comments on commit 471ed71

Please sign in to comment.