1
mirror of https://github.com/home-assistant/frontend synced 2024-08-30 01:56:15 +02:00

Allow uploading media (#11615)

* Allow uploading media

* Update path

* Use current item we already have

* Update src/panels/media-browser/ha-panel-media-browser.ts

Co-authored-by: Bram Kragten <mail@bramkragten.nl>

* Use alert dialog and use button for add media

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Paulus Schoutsen 2022-02-10 09:54:01 -08:00 committed by GitHub
parent cefa2ee183
commit d7a5921e7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 110 additions and 13 deletions

View File

@ -114,6 +114,19 @@ export class HaMediaPlayerBrowse extends LitElement {
}
}
public async refresh() {
const currentId = this.navigateIds[this.navigateIds.length - 1];
try {
this._currentItem = await this._fetchData(
this.entityId,
currentId.media_content_id,
currentId.media_content_type
);
} catch (err) {
this._setError(err);
}
}
public play(): void {
if (this._currentItem?.can_play) {
this._runAction(this._currentItem);

View File

@ -23,3 +23,29 @@ export const browseLocalMediaPlayer = (
type: "media_source/browse_media",
media_content_id: mediaContentId,
});
export const isLocalMediaSourceContentId = (mediaId: string) =>
mediaId.startsWith("media-source://media_source");
export const uploadLocalMedia = async (
hass: HomeAssistant,
media_content_id: string,
file: File
) => {
const fd = new FormData();
fd.append("media_content_id", media_content_id);
fd.append("file", file);
const resp = await hass.fetchWithAuth(
"/api/media_source/local_source/upload",
{
method: "POST",
body: fd,
}
);
if (resp.status === 413) {
throw new Error("Uploaded image is too large");
} else if (resp.status !== 200) {
throw new Error("Unknown error");
}
return resp.json();
};

View File

@ -1,6 +1,7 @@
import { mdiArrowLeft } from "@mdi/js";
import { mdiArrowLeft, mdiUpload } from "@mdi/js";
import "@polymer/app-layout/app-header/app-header";
import "@polymer/app-layout/app-toolbar/app-toolbar";
import "@material/mwc-button";
import {
css,
CSSResultGroup,
@ -9,20 +10,28 @@ import {
PropertyValues,
TemplateResult,
} from "lit";
import { customElement, property } from "lit/decorators";
import { customElement, property, query, state } from "lit/decorators";
import { LocalStorage } from "../../common/decorators/local-storage";
import { fireEvent, HASSDomEvent } from "../../common/dom/fire_event";
import { navigate } from "../../common/navigate";
import "../../components/ha-menu-button";
import "../../components/ha-icon-button";
import "../../components/ha-svg-icon";
import "../../components/media-player/ha-media-player-browse";
import type { MediaPlayerItemId } from "../../components/media-player/ha-media-player-browse";
import type {
HaMediaPlayerBrowse,
MediaPlayerItemId,
} from "../../components/media-player/ha-media-player-browse";
import {
BROWSER_PLAYER,
MediaPickedEvent,
MediaPlayerItem,
} from "../../data/media-player";
import { resolveMediaSource } from "../../data/media_source";
import {
isLocalMediaSourceContentId,
resolveMediaSource,
uploadLocalMedia,
} from "../../data/media_source";
import "../../layouts/ha-app-layout";
import { haStyle } from "../../resources/styles";
import type { HomeAssistant, Route } from "../../types";
@ -43,7 +52,7 @@ class PanelMediaBrowser extends LitElement {
@property() public route!: Route;
@property() _currentItem?: MediaPlayerItem;
@state() _currentItem?: MediaPlayerItem;
private _navigateIds: MediaPlayerItemId[] = [
{
@ -55,6 +64,8 @@ class PanelMediaBrowser extends LitElement {
@LocalStorage("mediaBrowseEntityId", true, false)
private _entityId = BROWSER_PLAYER;
@query("ha-media-player-browse") private _browser!: HaMediaPlayerBrowse;
protected render(): TemplateResult {
return html`
<ha-app-layout>
@ -73,15 +84,28 @@ class PanelMediaBrowser extends LitElement {
.narrow=${this.narrow}
></ha-menu-button>
`}
<div main-title class="heading">
<div>
${!this._currentItem
? this.hass.localize(
"ui.components.media-browser.media-player-browser"
)
: this._currentItem.title}
</div>
<div main-title>
${!this._currentItem
? this.hass.localize(
"ui.components.media-browser.media-player-browser"
)
: this._currentItem.title}
</div>
${this._currentItem &&
isLocalMediaSourceContentId(
this._currentItem.media_content_id || ""
)
? html`
<mwc-button
.label=${this.hass.localize(
"ui.components.media-browser.file_management.add_media"
)}
@click=${this._startUpload}
>
<ha-svg-icon .path=${mdiUpload} slot="icon"></ha-svg-icon>
</mwc-button>
`
: ""}
</app-toolbar>
</app-header>
<ha-media-player-browse
@ -215,6 +239,32 @@ class PanelMediaBrowser extends LitElement {
});
}
private async _startUpload() {
const input = document.createElement("input");
input.type = "file";
input.addEventListener("change", async () => {
try {
await uploadLocalMedia(
this.hass,
this._currentItem!.media_content_id!,
input.files![0]
);
} catch (err: any) {
showAlertDialog(this, {
text: this.hass.localize(
"ui.components.media-browser.file_management.upload_failed",
{
reason: err.message || err,
}
),
});
return;
}
await this._browser.refresh();
});
input.click();
}
static get styles(): CSSResultGroup {
return [
haStyle,
@ -237,6 +287,10 @@ class PanelMediaBrowser extends LitElement {
left: 0;
right: 0;
}
ha-svg-icon[slot="icon"] {
vertical-align: middle;
}
`,
];
}

View File

@ -524,6 +524,10 @@
"no_local_media_found": "No local media found",
"no_media_folder": "It looks like you have not yet created a media directory.",
"setup_local_help": "Check the {documentation} on how to setup local media.",
"file_management": {
"upload_failed": "Upload failed: {reason}",
"add_media": "Add Media"
},
"class": {
"album": "Album",
"app": "App",