mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 08:16:36 +00:00
Try to keep the browsing stack when changing players in media panel (#11681)
This commit is contained in:
parent
92db272759
commit
520896a3c2
@ -54,7 +54,14 @@ import "./ha-browse-media-tts";
|
|||||||
declare global {
|
declare global {
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
"media-picked": MediaPickedEvent;
|
"media-picked": MediaPickedEvent;
|
||||||
"media-browsed": { ids: MediaPlayerItemId[]; current?: MediaPlayerItem };
|
"media-browsed": {
|
||||||
|
// Items of the new browse stack
|
||||||
|
ids: MediaPlayerItemId[];
|
||||||
|
// Current fetched item for this browse stack
|
||||||
|
current?: MediaPlayerItem;
|
||||||
|
// If the new stack should replace the old stack
|
||||||
|
replace?: boolean;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,8 +440,8 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
|
|
||||||
if (changedProps.has("entityId")) {
|
if (changedProps.has("entityId")) {
|
||||||
this._setError(undefined);
|
this._setError(undefined);
|
||||||
}
|
} else if (!changedProps.has("navigateIds")) {
|
||||||
if (!changedProps.has("navigateIds")) {
|
// Neither entity ID or navigateIDs changed, nothing to fetch
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,6 +450,7 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
const oldNavigateIds = changedProps.get("navigateIds") as
|
const oldNavigateIds = changedProps.get("navigateIds") as
|
||||||
| this["navigateIds"]
|
| this["navigateIds"]
|
||||||
| undefined;
|
| undefined;
|
||||||
|
const navigateIds = this.navigateIds;
|
||||||
|
|
||||||
// We're navigating. Reset the shizzle.
|
// We're navigating. Reset the shizzle.
|
||||||
this._content?.scrollTo(0, 0);
|
this._content?.scrollTo(0, 0);
|
||||||
@ -451,11 +459,9 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
const oldParentItem = this._parentItem;
|
const oldParentItem = this._parentItem;
|
||||||
this._currentItem = undefined;
|
this._currentItem = undefined;
|
||||||
this._parentItem = undefined;
|
this._parentItem = undefined;
|
||||||
const currentId = this.navigateIds[this.navigateIds.length - 1];
|
const currentId = navigateIds[navigateIds.length - 1];
|
||||||
const parentId =
|
const parentId =
|
||||||
this.navigateIds.length > 1
|
navigateIds.length > 1 ? navigateIds[navigateIds.length - 2] : undefined;
|
||||||
? this.navigateIds[this.navigateIds.length - 2]
|
|
||||||
: undefined;
|
|
||||||
let currentProm: Promise<MediaPlayerItem> | undefined;
|
let currentProm: Promise<MediaPlayerItem> | undefined;
|
||||||
let parentProm: Promise<MediaPlayerItem> | undefined;
|
let parentProm: Promise<MediaPlayerItem> | undefined;
|
||||||
|
|
||||||
@ -464,9 +470,9 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
if (
|
if (
|
||||||
// Check if we navigated to a child
|
// Check if we navigated to a child
|
||||||
oldNavigateIds &&
|
oldNavigateIds &&
|
||||||
this.navigateIds.length > oldNavigateIds.length &&
|
navigateIds.length === oldNavigateIds.length + 1 &&
|
||||||
oldNavigateIds.every((oldVal, idx) => {
|
oldNavigateIds.every((oldVal, idx) => {
|
||||||
const curVal = this.navigateIds[idx];
|
const curVal = navigateIds[idx];
|
||||||
return (
|
return (
|
||||||
curVal.media_content_id === oldVal.media_content_id &&
|
curVal.media_content_id === oldVal.media_content_id &&
|
||||||
curVal.media_content_type === oldVal.media_content_type
|
curVal.media_content_type === oldVal.media_content_type
|
||||||
@ -477,8 +483,8 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
} else if (
|
} else if (
|
||||||
// Check if we navigated to a parent
|
// Check if we navigated to a parent
|
||||||
oldNavigateIds &&
|
oldNavigateIds &&
|
||||||
this.navigateIds.length < oldNavigateIds.length &&
|
navigateIds.length === oldNavigateIds.length - 1 &&
|
||||||
this.navigateIds.every((curVal, idx) => {
|
navigateIds.every((curVal, idx) => {
|
||||||
const oldVal = oldNavigateIds[idx];
|
const oldVal = oldNavigateIds[idx];
|
||||||
return (
|
return (
|
||||||
curVal.media_content_id === oldVal.media_content_id &&
|
curVal.media_content_id === oldVal.media_content_id &&
|
||||||
@ -501,11 +507,33 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
(item) => {
|
(item) => {
|
||||||
this._currentItem = item;
|
this._currentItem = item;
|
||||||
fireEvent(this, "media-browsed", {
|
fireEvent(this, "media-browsed", {
|
||||||
ids: this.navigateIds,
|
ids: navigateIds,
|
||||||
current: item,
|
current: item,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
(err) => this._setError(err)
|
(err) => {
|
||||||
|
// When we change entity ID, we will first try to see if the new entity is
|
||||||
|
// able to resolve the new path. If that results in an error, browse the root.
|
||||||
|
const isNewEntityWithSamePath =
|
||||||
|
oldNavigateIds &&
|
||||||
|
changedProps.has("entityId") &&
|
||||||
|
navigateIds.length === oldNavigateIds.length &&
|
||||||
|
oldNavigateIds.every(
|
||||||
|
(oldItem, idx) =>
|
||||||
|
navigateIds[idx].media_content_id === oldItem.media_content_id &&
|
||||||
|
navigateIds[idx].media_content_type === oldItem.media_content_type
|
||||||
|
);
|
||||||
|
if (isNewEntityWithSamePath) {
|
||||||
|
fireEvent(this, "media-browsed", {
|
||||||
|
ids: [
|
||||||
|
{ media_content_id: undefined, media_content_type: undefined },
|
||||||
|
],
|
||||||
|
replace: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this._setError(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
// Fetch parent
|
// Fetch parent
|
||||||
if (!parentProm && parentId !== undefined) {
|
if (!parentProm && parentId !== undefined) {
|
||||||
|
@ -25,7 +25,6 @@ import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
|||||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||||
import { domainIcon } from "../../common/entity/domain_icon";
|
import { domainIcon } from "../../common/entity/domain_icon";
|
||||||
import { supportsFeature } from "../../common/entity/supports-feature";
|
import { supportsFeature } from "../../common/entity/supports-feature";
|
||||||
import { navigate } from "../../common/navigate";
|
|
||||||
import "../../components/ha-button-menu";
|
import "../../components/ha-button-menu";
|
||||||
import "../../components/ha-icon-button";
|
import "../../components/ha-icon-button";
|
||||||
import { UNAVAILABLE_STATES } from "../../data/entity";
|
import { UNAVAILABLE_STATES } from "../../data/entity";
|
||||||
@ -47,6 +46,12 @@ import type { HomeAssistant } from "../../types";
|
|||||||
import "../lovelace/components/hui-marquee";
|
import "../lovelace/components/hui-marquee";
|
||||||
import { BrowserMediaPlayer } from "./browser-media-player";
|
import { BrowserMediaPlayer } from "./browser-media-player";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HASSDomEvents {
|
||||||
|
"player-picked": { entityId: string };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@customElement("ha-bar-media-player")
|
@customElement("ha-bar-media-player")
|
||||||
class BarMediaPlayer extends LitElement {
|
class BarMediaPlayer extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
@ -399,7 +404,7 @@ class BarMediaPlayer extends LitElement {
|
|||||||
|
|
||||||
private _selectPlayer(ev: CustomEvent): void {
|
private _selectPlayer(ev: CustomEvent): void {
|
||||||
const entityId = (ev.currentTarget as any).player;
|
const entityId = (ev.currentTarget as any).player;
|
||||||
navigate(`/media-browser/${entityId}`, { replace: true });
|
fireEvent(this, "player-picked", { entityId });
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
|
@ -43,6 +43,16 @@ import {
|
|||||||
isCameraMediaSource,
|
isCameraMediaSource,
|
||||||
} from "../../data/camera";
|
} from "../../data/camera";
|
||||||
|
|
||||||
|
const createMediaPanelUrl = (entityId: string, items: MediaPlayerItemId[]) => {
|
||||||
|
let path = `/media-browser/${entityId}`;
|
||||||
|
for (const item of items.slice(1)) {
|
||||||
|
path +=
|
||||||
|
"/" +
|
||||||
|
encodeURIComponent(`${item.media_content_type},${item.media_content_id}`);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
};
|
||||||
|
|
||||||
@customElement("ha-panel-media-browser")
|
@customElement("ha-panel-media-browser")
|
||||||
class PanelMediaBrowser extends LitElement {
|
class PanelMediaBrowser extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
@ -120,6 +130,7 @@ class PanelMediaBrowser extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.entityId=${this._entityId}
|
.entityId=${this._entityId}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
|
@player-picked=${this._playerPicked}
|
||||||
></ha-bar-media-player>
|
></ha-bar-media-player>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -179,7 +190,9 @@ class PanelMediaBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _goBack() {
|
private _goBack() {
|
||||||
history.back();
|
navigate(
|
||||||
|
createMediaPanelUrl(this._entityId, this._navigateIds.slice(0, -1))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _mediaBrowsed(ev: { detail: HASSDomEvents["media-browsed"] }) {
|
private _mediaBrowsed(ev: { detail: HASSDomEvents["media-browsed"] }) {
|
||||||
@ -188,15 +201,9 @@ class PanelMediaBrowser extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = "";
|
navigate(createMediaPanelUrl(this._entityId, ev.detail.ids), {
|
||||||
for (const item of ev.detail.ids.slice(1)) {
|
replace: ev.detail.replace,
|
||||||
path +=
|
});
|
||||||
"/" +
|
|
||||||
encodeURIComponent(
|
|
||||||
`${item.media_content_type},${item.media_content_id}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
navigate(`/media-browser/${this._entityId}${path}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _mediaPicked(
|
private async _mediaPicked(
|
||||||
@ -239,6 +246,14 @@ class PanelMediaBrowser extends LitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _playerPicked(ev) {
|
||||||
|
const entityId: string = ev.detail.entityId;
|
||||||
|
if (entityId === this._entityId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
navigate(createMediaPanelUrl(entityId, this._navigateIds));
|
||||||
|
}
|
||||||
|
|
||||||
private async _startUpload() {
|
private async _startUpload() {
|
||||||
const input = document.createElement("input");
|
const input = document.createElement("input");
|
||||||
input.type = "file";
|
input.type = "file";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user