mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
Some fixes for media panel (#11485)
This commit is contained in:
parent
182ffccd0c
commit
58ba3e5c22
@ -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 {
|
||||||
|
@ -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 "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
});
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user