diff --git a/src/components/media-player/ha-media-player-browse.ts b/src/components/media-player/ha-media-player-browse.ts
index df10572558a8..8f54e1204c4f 100644
--- a/src/components/media-player/ha-media-player-browse.ts
+++ b/src/components/media-player/ha-media-player-browse.ts
@@ -68,6 +68,8 @@ export class HaMediaPlayerBrowse extends LitElement {
@internalProperty() private _loading = false;
+ @internalProperty() private _error?: { message: string; code: string };
+
@internalProperty() private _mediaPlayerItems: MediaPlayerItem[] = [];
private _resizeObserver?: ResizeObserver;
@@ -92,11 +94,55 @@ export class HaMediaPlayerBrowse extends LitElement {
this._navigate(item);
}
+ private _renderError(err: { message: string; code: string }) {
+ if (err.message === "Media directory does not exist.") {
+ return html`
+
No local media found.
+
+ It looks like you have not yet created a media directory.
+
Create a directory with the name "media" in the
+ configuration directory of Home Assistant
+ (${this.hass.config.config_dir}).
Place your video, audio and
+ image files in this directory to be able to browse and play them in
+ the browser or on supported media players.
+
+
+
+ Check the
+ documentation
+ for more info
+
+ `;
+ }
+ return err.message;
+ }
+
protected render(): TemplateResult {
if (this._loading) {
return html``;
}
+ if (this._error && !this._mediaPlayerItems.length) {
+ if (this.dialog) {
+ this._closeDialogAction();
+ showAlertDialog(this, {
+ title: this.hass.localize(
+ "ui.components.media-browser.media_browsing_error"
+ ),
+ text: this._renderError(this._error),
+ });
+ } else {
+ return html`
+ ${this._renderError(this._error)}
+
`;
+ }
+ }
+
if (!this._mediaPlayerItems.length) {
return html``;
}
@@ -216,7 +262,11 @@ export class HaMediaPlayerBrowse extends LitElement {
`
: ""}
- ${currentItem.children?.length
+ ${this._error
+ ? html`
+ ${this._renderError(this._error)}
+
`
+ : currentItem.children?.length
? hasExpandableChildren
? html`
@@ -316,7 +366,9 @@ export class HaMediaPlayerBrowse extends LitElement {
)}
`
- : this.hass.localize("ui.components.media-browser.no_items")}
+ : html`
+ ${this.hass.localize("ui.components.media-browser.no_items")}
+
`}
`;
}
@@ -342,15 +394,22 @@ export class HaMediaPlayerBrowse extends LitElement {
return;
}
- this._fetchData(this.mediaContentId, this.mediaContentType).then(
- (itemData) => {
+ if (changedProps.has("entityId")) {
+ this._error = undefined;
+ this._mediaPlayerItems = [];
+ }
+
+ this._fetchData(this.mediaContentId, this.mediaContentType)
+ .then((itemData) => {
if (!itemData) {
return;
}
this._mediaPlayerItems = [itemData];
- }
- );
+ })
+ .catch((err) => {
+ this._error = err;
+ });
}
private _actionClicked(ev: MouseEvent): void {
@@ -381,12 +440,22 @@ export class HaMediaPlayerBrowse extends LitElement {
}
private async _navigate(item: MediaPlayerItem) {
- const itemData = await this._fetchData(
- item.media_content_id,
- item.media_content_type
- );
+ this._error = undefined;
+
+ let itemData: MediaPlayerItem;
- if (!itemData) {
+ try {
+ itemData = await this._fetchData(
+ item.media_content_id,
+ item.media_content_type
+ );
+ } catch (err) {
+ showAlertDialog(this, {
+ title: this.hass.localize(
+ "ui.components.media-browser.media_browsing_error"
+ ),
+ text: this._renderError(err),
+ });
return;
}
@@ -397,33 +466,23 @@ export class HaMediaPlayerBrowse extends LitElement {
private async _fetchData(
mediaContentId?: string,
mediaContentType?: string
- ): Promise
{
- let itemData: MediaPlayerItem | undefined;
- try {
- itemData =
- this.entityId !== BROWSER_SOURCE
- ? await browseMediaPlayer(
- this.hass,
- this.entityId,
- mediaContentId,
- mediaContentType
- )
- : await browseLocalMediaPlayer(this.hass, mediaContentId);
- itemData.children = itemData.children?.sort((first, second) =>
- !first.can_expand && second.can_expand
- ? 1
- : first.can_expand && !second.can_expand
- ? -1
- : compare(first.title, second.title)
- );
- } catch (error) {
- showAlertDialog(this, {
- title: this.hass.localize(
- "ui.components.media-browser.media_browsing_error"
- ),
- text: error.message,
- });
- }
+ ): Promise {
+ const itemData =
+ this.entityId !== BROWSER_SOURCE
+ ? await browseMediaPlayer(
+ this.hass,
+ this.entityId,
+ mediaContentId,
+ mediaContentType
+ )
+ : await browseLocalMediaPlayer(this.hass, mediaContentId);
+ itemData.children = itemData.children?.sort((first, second) =>
+ !first.can_expand && second.can_expand
+ ? 1
+ : first.can_expand && !second.can_expand
+ ? -1
+ : compare(first.title, second.title)
+ );
return itemData;
}
@@ -451,8 +510,8 @@ export class HaMediaPlayerBrowse extends LitElement {
this._resizeObserver.observe(this);
}
- private _hasExpandableChildren = memoizeOne((children) =>
- children.find((item: MediaPlayerItem) => item.can_expand)
+ private _hasExpandableChildren = memoizeOne((children?: MediaPlayerItem[]) =>
+ children?.find((item: MediaPlayerItem) => item.can_expand)
);
private _closeDialogAction(): void {
@@ -471,6 +530,10 @@ export class HaMediaPlayerBrowse extends LitElement {
flex-direction: column;
}
+ .container {
+ padding: 16px;
+ }
+
.header {
display: flex;
justify-content: space-between;
diff --git a/src/dialogs/generic/dialog-box.ts b/src/dialogs/generic/dialog-box.ts
index b8fcea9a706b..7d63d3dd5322 100644
--- a/src/dialogs/generic/dialog-box.ts
+++ b/src/dialogs/generic/dialog-box.ts
@@ -5,19 +5,19 @@ import {
CSSResult,
customElement,
html,
+ internalProperty,
LitElement,
property,
- internalProperty,
TemplateResult,
} from "lit-element";
import { classMap } from "lit-html/directives/class-map";
+import { fireEvent } from "../../common/dom/fire_event";
import "../../components/ha-dialog";
import "../../components/ha-switch";
import { PolymerChangedEvent } from "../../polymer-types";
import { haStyleDialog } from "../../resources/styles";
import { HomeAssistant } from "../../types";
import { DialogParams } from "./show-dialog-box";
-import { fireEvent } from "../../common/dom/fire_event";
@customElement("dialog-box")
class DialogBox extends LitElement {
@@ -114,8 +114,8 @@ class DialogBox extends LitElement {
}
private _dismiss(): void {
- if (this._params!.cancel) {
- this._params!.cancel();
+ if (this._params?.cancel) {
+ this._params.cancel();
}
this._close();
}