Handle media browser errors (#6813)

Co-authored-by: Joakim Sørensen <joasoe@gmail.com>
This commit is contained in:
Bram Kragten 2020-09-07 20:39:26 +02:00 committed by GitHub
parent 5339fe6e06
commit 046f7b5153
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -68,6 +68,8 @@ export class HaMediaPlayerBrowse extends LitElement {
@internalProperty() private _loading = false; @internalProperty() private _loading = false;
@internalProperty() private _error?: { message: string; code: string };
@internalProperty() private _mediaPlayerItems: MediaPlayerItem[] = []; @internalProperty() private _mediaPlayerItems: MediaPlayerItem[] = [];
private _resizeObserver?: ResizeObserver; private _resizeObserver?: ResizeObserver;
@ -92,11 +94,55 @@ export class HaMediaPlayerBrowse extends LitElement {
this._navigate(item); this._navigate(item);
} }
private _renderError(err: { message: string; code: string }) {
if (err.message === "Media directory does not exist.") {
return html`
<h2>No local media found.</h2>
<p>
It looks like you have not yet created a media directory.
<br />Create a directory with the name <b>"media"</b> in the
configuration directory of Home Assistant
(${this.hass.config.config_dir}). <br />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.
</p>
<p>
Check the
<a
href="https://www.home-assistant.io/integrations/media_source/#local-media"
target="_blank"
rel="noreferrer"
>documentation</a
>
for more info
</p>
`;
}
return err.message;
}
protected render(): TemplateResult { protected render(): TemplateResult {
if (this._loading) { if (this._loading) {
return html`<ha-circular-progress active></ha-circular-progress>`; return html`<ha-circular-progress active></ha-circular-progress>`;
} }
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`<div class="container error">
${this._renderError(this._error)}
</div>`;
}
}
if (!this._mediaPlayerItems.length) { if (!this._mediaPlayerItems.length) {
return html``; return html``;
} }
@ -216,7 +262,11 @@ export class HaMediaPlayerBrowse extends LitElement {
` `
: ""} : ""}
</div> </div>
${currentItem.children?.length ${this._error
? html`<div class="container error">
${this._renderError(this._error)}
</div>`
: currentItem.children?.length
? hasExpandableChildren ? hasExpandableChildren
? html` ? html`
<div class="children"> <div class="children">
@ -316,7 +366,9 @@ export class HaMediaPlayerBrowse extends LitElement {
)} )}
</mwc-list> </mwc-list>
` `
: this.hass.localize("ui.components.media-browser.no_items")} : html`<div class="container">
${this.hass.localize("ui.components.media-browser.no_items")}
</div>`}
`; `;
} }
@ -342,15 +394,22 @@ export class HaMediaPlayerBrowse extends LitElement {
return; return;
} }
this._fetchData(this.mediaContentId, this.mediaContentType).then( if (changedProps.has("entityId")) {
(itemData) => { this._error = undefined;
this._mediaPlayerItems = [];
}
this._fetchData(this.mediaContentId, this.mediaContentType)
.then((itemData) => {
if (!itemData) { if (!itemData) {
return; return;
} }
this._mediaPlayerItems = [itemData]; this._mediaPlayerItems = [itemData];
} })
); .catch((err) => {
this._error = err;
});
} }
private _actionClicked(ev: MouseEvent): void { private _actionClicked(ev: MouseEvent): void {
@ -381,12 +440,22 @@ export class HaMediaPlayerBrowse extends LitElement {
} }
private async _navigate(item: MediaPlayerItem) { private async _navigate(item: MediaPlayerItem) {
const itemData = await this._fetchData( this._error = undefined;
item.media_content_id,
item.media_content_type
);
if (!itemData) { let itemData: MediaPlayerItem;
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; return;
} }
@ -397,33 +466,23 @@ export class HaMediaPlayerBrowse extends LitElement {
private async _fetchData( private async _fetchData(
mediaContentId?: string, mediaContentId?: string,
mediaContentType?: string mediaContentType?: string
): Promise<MediaPlayerItem | undefined> { ): Promise<MediaPlayerItem> {
let itemData: MediaPlayerItem | undefined; const itemData =
try { this.entityId !== BROWSER_SOURCE
itemData = ? await browseMediaPlayer(
this.entityId !== BROWSER_SOURCE this.hass,
? await browseMediaPlayer( this.entityId,
this.hass, mediaContentId,
this.entityId, mediaContentType
mediaContentId, )
mediaContentType : await browseLocalMediaPlayer(this.hass, mediaContentId);
) itemData.children = itemData.children?.sort((first, second) =>
: await browseLocalMediaPlayer(this.hass, mediaContentId); !first.can_expand && second.can_expand
itemData.children = itemData.children?.sort((first, second) => ? 1
!first.can_expand && second.can_expand : first.can_expand && !second.can_expand
? 1 ? -1
: first.can_expand && !second.can_expand : compare(first.title, second.title)
? -1 );
: compare(first.title, second.title)
);
} catch (error) {
showAlertDialog(this, {
title: this.hass.localize(
"ui.components.media-browser.media_browsing_error"
),
text: error.message,
});
}
return itemData; return itemData;
} }
@ -451,8 +510,8 @@ export class HaMediaPlayerBrowse extends LitElement {
this._resizeObserver.observe(this); this._resizeObserver.observe(this);
} }
private _hasExpandableChildren = memoizeOne((children) => private _hasExpandableChildren = memoizeOne((children?: MediaPlayerItem[]) =>
children.find((item: MediaPlayerItem) => item.can_expand) children?.find((item: MediaPlayerItem) => item.can_expand)
); );
private _closeDialogAction(): void { private _closeDialogAction(): void {
@ -471,6 +530,10 @@ export class HaMediaPlayerBrowse extends LitElement {
flex-direction: column; flex-direction: column;
} }
.container {
padding: 16px;
}
.header { .header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;