From 58ba3e5c22eb190e001750bc311e26b2ba0a58c8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 31 Jan 2022 10:17:06 -0800 Subject: [PATCH] Some fixes for media panel (#11485) --- .../media-player/ha-media-player-browse.ts | 2 +- src/data/media-player.ts | 13 +---- src/data/media_source.ts | 10 ++++ .../media-browser/ha-bar-media-player.ts | 49 +++++++++++-------- .../media-browser/ha-panel-media-browser.ts | 18 +++++++ src/translations/en.json | 5 ++ 6 files changed, 64 insertions(+), 33 deletions(-) diff --git a/src/components/media-player/ha-media-player-browse.ts b/src/components/media-player/ha-media-player-browse.ts index 4910271298..f939e23bc8 100644 --- a/src/components/media-player/ha-media-player-browse.ts +++ b/src/components/media-player/ha-media-player-browse.ts @@ -30,7 +30,6 @@ import { debounce } from "../../common/util/debounce"; import { getSignedPath } from "../../data/auth"; import type { MediaPlayerItem } from "../../data/media-player"; import { - browseLocalMediaPlayer, browseMediaPlayer, BROWSER_PLAYER, MediaClassBrowserSettings, @@ -50,6 +49,7 @@ import "../ha-circular-progress"; import "../ha-icon-button"; import "../ha-svg-icon"; import "../ha-fab"; +import { browseLocalMediaPlayer } from "../../data/media_source"; declare global { interface HASSDomEvents { diff --git a/src/data/media-player.ts b/src/data/media-player.ts index ee15481785..48f3351dbb 100644 --- a/src/data/media-player.ts +++ b/src/data/media-player.ts @@ -185,15 +185,6 @@ export const browseMediaPlayer = ( media_content_type: mediaContentType, }); -export const browseLocalMediaPlayer = ( - hass: HomeAssistant, - mediaContentId?: string -): Promise => - hass.callWS({ - type: "media_source/browse_media", - media_content_id: mediaContentId, - }); - export const getCurrentProgress = (stateObj: MediaPlayerEntity): number => { let progress = stateObj.attributes.media_position!; @@ -321,8 +312,8 @@ export const computeMediaControls = ( return buttons.length > 0 ? buttons : undefined; }; -export const formatMediaTime = (seconds: number): string => { - if (!seconds) { +export const formatMediaTime = (seconds: number | undefined): string => { + if (seconds === undefined) { return ""; } diff --git a/src/data/media_source.ts b/src/data/media_source.ts index 0b2b70b989..759be2a7d3 100644 --- a/src/data/media_source.ts +++ b/src/data/media_source.ts @@ -1,4 +1,5 @@ import { HomeAssistant } from "../types"; +import { MediaPlayerItem } from "./media-player"; export interface ResolvedMediaSource { url: string; @@ -13,3 +14,12 @@ export const resolveMediaSource = ( type: "media_source/resolve_media", media_content_id, }); + +export const browseLocalMediaPlayer = ( + hass: HomeAssistant, + mediaContentId?: string +): Promise => + hass.callWS({ + type: "media_source/browse_media", + media_content_id: mediaContentId, + }); diff --git a/src/panels/media-browser/ha-bar-media-player.ts b/src/panels/media-browser/ha-bar-media-player.ts index 1a2f67d0e7..65a02e1fc6 100644 --- a/src/panels/media-browser/ha-bar-media-player.ts +++ b/src/panels/media-browser/ha-bar-media-player.ts @@ -115,7 +115,9 @@ class BarMediaPlayer extends LitElement { protected render(): TemplateResult { const isBrowser = this.entityId === BROWSER_PLAYER; const stateObj = this._stateObj; - const controls = !this.narrow + const controls = !stateObj + ? undefined + : !this.narrow ? computeMediaControls(stateObj) : (stateObj.state === "playing" && (supportsFeature(stateObj, SUPPORT_PAUSE) || @@ -144,13 +146,16 @@ class BarMediaPlayer extends LitElement { }, ] : [{}]; - const mediaDescription = computeMediaDescription(stateObj); - const mediaDuration = formatMediaTime(stateObj!.attributes.media_duration!); - const mediaTitleClean = cleanupMediaTitle(stateObj.attributes.media_title); + const mediaDescription = stateObj ? computeMediaDescription(stateObj) : ""; + const mediaDuration = formatMediaTime(stateObj?.attributes.media_duration); + const mediaTitleClean = cleanupMediaTitle( + stateObj?.attributes.media_title || "" + ); - const mediaArt = - stateObj.attributes.entity_picture_local || - stateObj.attributes.entity_picture; + const mediaArt = stateObj + ? stateObj.attributes.entity_picture_local || + stateObj.attributes.entity_picture + : undefined; return html`
this._updateProgressBar(), @@ -296,21 +301,20 @@ class BarMediaPlayer extends LitElement { ); } else if ( this._progressInterval && - (!this._showProgressBar || stateObj.state !== "playing") + (!this._showProgressBar || stateObj?.state !== "playing") ) { clearInterval(this._progressInterval); this._progressInterval = undefined; } } - private get _stateObj(): MediaPlayerEntity { - if (this._browserPlayer) { - return this._browserPlayer.toStateObj(); + private get _stateObj(): MediaPlayerEntity | undefined { + if (this.entityId === BROWSER_PLAYER) { + return this._browserPlayer + ? this._browserPlayer.toStateObj() + : BrowserMediaPlayer.idleStateObj(); } - return ( - (this.hass!.states[this.entityId] as MediaPlayerEntity | undefined) || - BrowserMediaPlayer.idleStateObj() - ); + return this.hass!.states[this.entityId] as MediaPlayerEntity | undefined; } private _openMoreInfo() { @@ -328,6 +332,7 @@ class BarMediaPlayer extends LitElement { const stateObj = this._stateObj; return ( + stateObj && (stateObj.state === "playing" || stateObj.state === "paused") && "media_duration" in stateObj.attributes && "media_position" in stateObj.attributes @@ -343,19 +348,21 @@ class BarMediaPlayer extends LitElement { } private _updateProgressBar(): void { - if (!this._progressBar || !this._currentProgress) { + const stateObj = this._stateObj; + + if (!this._progressBar || !this._currentProgress || !stateObj) { return; } - if (!this._stateObj.attributes.media_duration) { + if (!stateObj.attributes.media_duration) { this._progressBar.progress = 0; this._currentProgress.innerHTML = ""; return; } - const currentProgress = getCurrentProgress(this._stateObj); + const currentProgress = getCurrentProgress(stateObj); this._progressBar.progress = - currentProgress / this._stateObj.attributes.media_duration; + currentProgress / stateObj.attributes.media_duration; if (this._currentProgress) { this._currentProgress.innerHTML = formatMediaTime(currentProgress); diff --git a/src/panels/media-browser/ha-panel-media-browser.ts b/src/panels/media-browser/ha-panel-media-browser.ts index ef8a9ba04a..95931759cb 100644 --- a/src/panels/media-browser/ha-panel-media-browser.ts +++ b/src/panels/media-browser/ha-panel-media-browser.ts @@ -28,6 +28,7 @@ import { haStyle } from "../../resources/styles"; import type { HomeAssistant, Route } from "../../types"; import "./ha-bar-media-player"; import { showWebBrowserPlayMediaDialog } from "./show-media-player-dialog"; +import { showAlertDialog } from "../../dialogs/generic/show-dialog-box"; @customElement("ha-panel-media-browser") class PanelMediaBrowser extends LitElement { @@ -112,6 +113,23 @@ class PanelMediaBrowser extends LitElement { .split("/"); 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; } diff --git a/src/translations/en.json b/src/translations/en.json index cf675c55a6..ba969edb2a 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3654,6 +3654,11 @@ "delete_prompt": "Delete this message?", "delete_button": "Delete" }, + "media-browser": { + "error": { + "player_not_exist": "Media player {name} does not exist" + } + }, "map": { "edit_zones": "Edit Zones" },