Some fixes for media panel (#11485)

This commit is contained in:
Paulus Schoutsen 2022-01-31 10:17:06 -08:00 committed by GitHub
parent 182ffccd0c
commit 58ba3e5c22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 33 deletions

View File

@ -30,7 +30,6 @@ import { debounce } from "../../common/util/debounce";
import { getSignedPath } from "../../data/auth"; import { getSignedPath } from "../../data/auth";
import type { MediaPlayerItem } from "../../data/media-player"; import type { MediaPlayerItem } from "../../data/media-player";
import { import {
browseLocalMediaPlayer,
browseMediaPlayer, browseMediaPlayer,
BROWSER_PLAYER, BROWSER_PLAYER,
MediaClassBrowserSettings, MediaClassBrowserSettings,
@ -50,6 +49,7 @@ import "../ha-circular-progress";
import "../ha-icon-button"; import "../ha-icon-button";
import "../ha-svg-icon"; import "../ha-svg-icon";
import "../ha-fab"; import "../ha-fab";
import { browseLocalMediaPlayer } from "../../data/media_source";
declare global { declare global {
interface HASSDomEvents { interface HASSDomEvents {

View File

@ -185,15 +185,6 @@ export const browseMediaPlayer = (
media_content_type: mediaContentType, media_content_type: mediaContentType,
}); });
export const browseLocalMediaPlayer = (
hass: HomeAssistant,
mediaContentId?: string
): Promise<MediaPlayerItem> =>
hass.callWS<MediaPlayerItem>({
type: "media_source/browse_media",
media_content_id: mediaContentId,
});
export const getCurrentProgress = (stateObj: MediaPlayerEntity): number => { export const getCurrentProgress = (stateObj: MediaPlayerEntity): number => {
let progress = stateObj.attributes.media_position!; let progress = stateObj.attributes.media_position!;
@ -321,8 +312,8 @@ export const computeMediaControls = (
return buttons.length > 0 ? buttons : undefined; return buttons.length > 0 ? buttons : undefined;
}; };
export const formatMediaTime = (seconds: number): string => { export const formatMediaTime = (seconds: number | undefined): string => {
if (!seconds) { if (seconds === undefined) {
return ""; return "";
} }

View File

@ -1,4 +1,5 @@
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import { MediaPlayerItem } from "./media-player";
export interface ResolvedMediaSource { export interface ResolvedMediaSource {
url: string; url: string;
@ -13,3 +14,12 @@ export const resolveMediaSource = (
type: "media_source/resolve_media", type: "media_source/resolve_media",
media_content_id, media_content_id,
}); });
export const browseLocalMediaPlayer = (
hass: HomeAssistant,
mediaContentId?: string
): Promise<MediaPlayerItem> =>
hass.callWS<MediaPlayerItem>({
type: "media_source/browse_media",
media_content_id: mediaContentId,
});

View File

@ -115,7 +115,9 @@ class BarMediaPlayer extends LitElement {
protected render(): TemplateResult { protected render(): TemplateResult {
const isBrowser = this.entityId === BROWSER_PLAYER; const isBrowser = this.entityId === BROWSER_PLAYER;
const stateObj = this._stateObj; const stateObj = this._stateObj;
const controls = !this.narrow const controls = !stateObj
? undefined
: !this.narrow
? computeMediaControls(stateObj) ? computeMediaControls(stateObj)
: (stateObj.state === "playing" && : (stateObj.state === "playing" &&
(supportsFeature(stateObj, SUPPORT_PAUSE) || (supportsFeature(stateObj, SUPPORT_PAUSE) ||
@ -144,13 +146,16 @@ class BarMediaPlayer extends LitElement {
}, },
] ]
: [{}]; : [{}];
const mediaDescription = computeMediaDescription(stateObj); const mediaDescription = stateObj ? computeMediaDescription(stateObj) : "";
const mediaDuration = formatMediaTime(stateObj!.attributes.media_duration!); const mediaDuration = formatMediaTime(stateObj?.attributes.media_duration);
const mediaTitleClean = cleanupMediaTitle(stateObj.attributes.media_title); const mediaTitleClean = cleanupMediaTitle(
stateObj?.attributes.media_title || ""
);
const mediaArt = const mediaArt = stateObj
stateObj.attributes.entity_picture_local || ? stateObj.attributes.entity_picture_local ||
stateObj.attributes.entity_picture; stateObj.attributes.entity_picture
: undefined;
return html` return html`
<div <div
@ -216,7 +221,7 @@ class BarMediaPlayer extends LitElement {
slot="trigger" slot="trigger"
.label=${this.narrow .label=${this.narrow
? "" ? ""
: `${computeStateName(stateObj)} : `${stateObj ? computeStateName(stateObj) : this.entityId}
`} `}
> >
<ha-svg-icon <ha-svg-icon
@ -288,7 +293,7 @@ class BarMediaPlayer extends LitElement {
if ( if (
!this._progressInterval && !this._progressInterval &&
this._showProgressBar && this._showProgressBar &&
stateObj.state === "playing" stateObj?.state === "playing"
) { ) {
this._progressInterval = window.setInterval( this._progressInterval = window.setInterval(
() => this._updateProgressBar(), () => this._updateProgressBar(),
@ -296,21 +301,20 @@ class BarMediaPlayer extends LitElement {
); );
} else if ( } else if (
this._progressInterval && this._progressInterval &&
(!this._showProgressBar || stateObj.state !== "playing") (!this._showProgressBar || stateObj?.state !== "playing")
) { ) {
clearInterval(this._progressInterval); clearInterval(this._progressInterval);
this._progressInterval = undefined; this._progressInterval = undefined;
} }
} }
private get _stateObj(): MediaPlayerEntity { private get _stateObj(): MediaPlayerEntity | undefined {
if (this._browserPlayer) { if (this.entityId === BROWSER_PLAYER) {
return this._browserPlayer.toStateObj(); return this._browserPlayer
? this._browserPlayer.toStateObj()
: BrowserMediaPlayer.idleStateObj();
} }
return ( return this.hass!.states[this.entityId] as MediaPlayerEntity | undefined;
(this.hass!.states[this.entityId] as MediaPlayerEntity | undefined) ||
BrowserMediaPlayer.idleStateObj()
);
} }
private _openMoreInfo() { private _openMoreInfo() {
@ -328,6 +332,7 @@ class BarMediaPlayer extends LitElement {
const stateObj = this._stateObj; const stateObj = this._stateObj;
return ( return (
stateObj &&
(stateObj.state === "playing" || stateObj.state === "paused") && (stateObj.state === "playing" || stateObj.state === "paused") &&
"media_duration" in stateObj.attributes && "media_duration" in stateObj.attributes &&
"media_position" in stateObj.attributes "media_position" in stateObj.attributes
@ -343,19 +348,21 @@ class BarMediaPlayer extends LitElement {
} }
private _updateProgressBar(): void { private _updateProgressBar(): void {
if (!this._progressBar || !this._currentProgress) { const stateObj = this._stateObj;
if (!this._progressBar || !this._currentProgress || !stateObj) {
return; return;
} }
if (!this._stateObj.attributes.media_duration) { if (!stateObj.attributes.media_duration) {
this._progressBar.progress = 0; this._progressBar.progress = 0;
this._currentProgress.innerHTML = ""; this._currentProgress.innerHTML = "";
return; return;
} }
const currentProgress = getCurrentProgress(this._stateObj); const currentProgress = getCurrentProgress(stateObj);
this._progressBar.progress = this._progressBar.progress =
currentProgress / this._stateObj.attributes.media_duration; currentProgress / stateObj.attributes.media_duration;
if (this._currentProgress) { if (this._currentProgress) {
this._currentProgress.innerHTML = formatMediaTime(currentProgress); this._currentProgress.innerHTML = formatMediaTime(currentProgress);

View File

@ -28,6 +28,7 @@ import { haStyle } from "../../resources/styles";
import type { HomeAssistant, Route } from "../../types"; import type { HomeAssistant, Route } from "../../types";
import "./ha-bar-media-player"; import "./ha-bar-media-player";
import { showWebBrowserPlayMediaDialog } from "./show-media-player-dialog"; import { showWebBrowserPlayMediaDialog } from "./show-media-player-dialog";
import { showAlertDialog } from "../../dialogs/generic/show-dialog-box";
@customElement("ha-panel-media-browser") @customElement("ha-panel-media-browser")
class PanelMediaBrowser extends LitElement { class PanelMediaBrowser extends LitElement {
@ -112,6 +113,23 @@ class PanelMediaBrowser extends LitElement {
.split("/"); .split("/");
if (routePlayer !== this._entityId) { if (routePlayer !== this._entityId) {
// Detect if picked player doesn't exist (anymore)
// Can happen if URL bookmarked or stored in local storage
if (
routePlayer !== BROWSER_PLAYER &&
this.hass.states[routePlayer] === undefined
) {
navigate(`/media-browser/${BROWSER_PLAYER}`, { replace: true });
showAlertDialog(this, {
text: this.hass.localize(
"ui.panel.media-browser.error.player_not_exist",
{
name: routePlayer,
}
),
});
return;
}
this._entityId = routePlayer; this._entityId = routePlayer;
} }

View File

@ -3654,6 +3654,11 @@
"delete_prompt": "Delete this message?", "delete_prompt": "Delete this message?",
"delete_button": "Delete" "delete_button": "Delete"
}, },
"media-browser": {
"error": {
"player_not_exist": "Media player {name} does not exist"
}
},
"map": { "map": {
"edit_zones": "Edit Zones" "edit_zones": "Edit Zones"
}, },