>["data"]> = [];
const borderColor: string[] = [];
const backgroundColor: string[] = [];
diff --git a/src/panels/media-browser/ha-bar-media-player.ts b/src/panels/media-browser/ha-bar-media-player.ts
index 1a2f67d0e7..65a02e1fc6 100644
--- a/src/panels/media-browser/ha-bar-media-player.ts
+++ b/src/panels/media-browser/ha-bar-media-player.ts
@@ -115,7 +115,9 @@ class BarMediaPlayer extends LitElement {
protected render(): TemplateResult {
const isBrowser = this.entityId === BROWSER_PLAYER;
const stateObj = this._stateObj;
- const controls = !this.narrow
+ const controls = !stateObj
+ ? undefined
+ : !this.narrow
? computeMediaControls(stateObj)
: (stateObj.state === "playing" &&
(supportsFeature(stateObj, SUPPORT_PAUSE) ||
@@ -144,13 +146,16 @@ class BarMediaPlayer extends LitElement {
},
]
: [{}];
- const mediaDescription = computeMediaDescription(stateObj);
- const mediaDuration = formatMediaTime(stateObj!.attributes.media_duration!);
- const mediaTitleClean = cleanupMediaTitle(stateObj.attributes.media_title);
+ const mediaDescription = stateObj ? computeMediaDescription(stateObj) : "";
+ const mediaDuration = formatMediaTime(stateObj?.attributes.media_duration);
+ const mediaTitleClean = cleanupMediaTitle(
+ stateObj?.attributes.media_title || ""
+ );
- const mediaArt =
- stateObj.attributes.entity_picture_local ||
- stateObj.attributes.entity_picture;
+ const mediaArt = stateObj
+ ? stateObj.attributes.entity_picture_local ||
+ stateObj.attributes.entity_picture
+ : undefined;
return html`
this._updateProgressBar(),
@@ -296,21 +301,20 @@ class BarMediaPlayer extends LitElement {
);
} else if (
this._progressInterval &&
- (!this._showProgressBar || stateObj.state !== "playing")
+ (!this._showProgressBar || stateObj?.state !== "playing")
) {
clearInterval(this._progressInterval);
this._progressInterval = undefined;
}
}
- private get _stateObj(): MediaPlayerEntity {
- if (this._browserPlayer) {
- return this._browserPlayer.toStateObj();
+ private get _stateObj(): MediaPlayerEntity | undefined {
+ if (this.entityId === BROWSER_PLAYER) {
+ return this._browserPlayer
+ ? this._browserPlayer.toStateObj()
+ : BrowserMediaPlayer.idleStateObj();
}
- return (
- (this.hass!.states[this.entityId] as MediaPlayerEntity | undefined) ||
- BrowserMediaPlayer.idleStateObj()
- );
+ return this.hass!.states[this.entityId] as MediaPlayerEntity | undefined;
}
private _openMoreInfo() {
@@ -328,6 +332,7 @@ class BarMediaPlayer extends LitElement {
const stateObj = this._stateObj;
return (
+ stateObj &&
(stateObj.state === "playing" || stateObj.state === "paused") &&
"media_duration" in stateObj.attributes &&
"media_position" in stateObj.attributes
@@ -343,19 +348,21 @@ class BarMediaPlayer extends LitElement {
}
private _updateProgressBar(): void {
- if (!this._progressBar || !this._currentProgress) {
+ const stateObj = this._stateObj;
+
+ if (!this._progressBar || !this._currentProgress || !stateObj) {
return;
}
- if (!this._stateObj.attributes.media_duration) {
+ if (!stateObj.attributes.media_duration) {
this._progressBar.progress = 0;
this._currentProgress.innerHTML = "";
return;
}
- const currentProgress = getCurrentProgress(this._stateObj);
+ const currentProgress = getCurrentProgress(stateObj);
this._progressBar.progress =
- currentProgress / this._stateObj.attributes.media_duration;
+ currentProgress / stateObj.attributes.media_duration;
if (this._currentProgress) {
this._currentProgress.innerHTML = formatMediaTime(currentProgress);
diff --git a/src/panels/media-browser/ha-panel-media-browser.ts b/src/panels/media-browser/ha-panel-media-browser.ts
index ef8a9ba04a..95931759cb 100644
--- a/src/panels/media-browser/ha-panel-media-browser.ts
+++ b/src/panels/media-browser/ha-panel-media-browser.ts
@@ -28,6 +28,7 @@ import { haStyle } from "../../resources/styles";
import type { HomeAssistant, Route } from "../../types";
import "./ha-bar-media-player";
import { showWebBrowserPlayMediaDialog } from "./show-media-player-dialog";
+import { showAlertDialog } from "../../dialogs/generic/show-dialog-box";
@customElement("ha-panel-media-browser")
class PanelMediaBrowser extends LitElement {
@@ -112,6 +113,23 @@ class PanelMediaBrowser extends LitElement {
.split("/");
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;
}
diff --git a/src/resources/compatibility.ts b/src/resources/compatibility.ts
index 03a0b23fec..07f80f0ff8 100644
--- a/src/resources/compatibility.ts
+++ b/src/resources/compatibility.ts
@@ -1,3 +1,4 @@
+// Caution before editing - For latest builds, this module is replaced with emptiness and thus not imported (see build-scripts/bundle.js)
import "core-js";
import "regenerator-runtime/runtime";
import "lit/polyfill-support";
diff --git a/src/translations/en.json b/src/translations/en.json
index 672b952ef8..ba969edb2a 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -733,6 +733,7 @@
"cover": {
"door": "Door",
"garage": "Garage door",
+ "gate": "Gate",
"window": "Window"
}
},
@@ -1011,6 +1012,8 @@
"description": "You need to run the Home Assistant operating system to be able to check and install updates from the Home Assistant user interface."
},
"check_updates": "Check for updates",
+ "no_new_updates": "No new updates found",
+ "updates_refreshed": "Updates refreshed",
"title": "{count} {count, plural,\n one {update}\n other {updates}\n}",
"unable_to_fetch": "Unable to load updates",
"version_available": "Version {version_available} is available",
@@ -2205,18 +2208,18 @@
}
},
"devices": {
- "add_prompt": "No {name} have been added using this device yet. You can add one by clicking the + button above.",
+ "add_prompt": "No {name} have been added using this {type} yet. You can add one by clicking the + button above.",
"caption": "Devices",
"description": "Manage configured devices",
- "device_info": "Device info",
+ "device_info": "{type} info",
"edit_settings": "Edit settings",
- "unnamed_device": "Unnamed device",
+ "unnamed_device": "Unnamed {type}",
"unknown_error": "Unknown error",
"name": "Name",
"update": "Update",
"no_devices": "No devices",
- "enabled_label": "Enable device",
- "enabled_cause": "The device is disabled by {cause}.",
+ "enabled_label": "Enable {type}",
+ "enabled_cause": "The {type} is disabled by {cause}.",
"disabled_by": {
"user": "User",
"integration": "Integration",
@@ -2226,12 +2229,19 @@
"open_configuration_url_device": "Visit device",
"open_configuration_url_service": "Visit service",
"download_diagnostics": "Download diagnostics",
+ "type": {
+ "device_heading": "Device",
+ "device": "device",
+ "service_heading": "Service",
+ "service": "service"
+ },
"automation": {
- "automations": "Automations",
+ "automations_heading": "Automations",
+ "automations": "automations",
"no_automations": "No automations",
"unknown_automation": "Unknown automation",
- "create": "Create automation with device",
- "create_disable": "Can't create automation with disabled device",
+ "create": "Create automation with {type}",
+ "create_disable": "Can't create automation with disabled {type}",
"triggers": {
"caption": "Do something when…",
"no_triggers": "No triggers",
@@ -2250,19 +2260,21 @@
"no_device_automations": "There are no automations available for this device."
},
"script": {
- "scripts": "Scripts",
+ "scripts_heading": "Scripts",
+ "scripts": "scripts",
"no_scripts": "No scripts",
- "create": "Create script with device",
- "create_disable": "Can't create script with disabled device"
+ "create": "Create script with {type}",
+ "create_disable": "Can't create script with disabled {type}"
},
"scene": {
- "scenes": "Scenes",
+ "scenes_heading": "Scenes",
+ "scenes": "scenes",
"no_scenes": "No scenes",
- "create": "Create scene with device",
- "create_disable": "Can't create scene with disabled device"
+ "create": "Create scene with {type}",
+ "create_disable": "Can't create scene with disabled {type}"
},
"cant_edit": "You can only edit items that are created in the UI.",
- "device_not_found": "Device not found.",
+ "device_not_found": "Device / service not found.",
"entities": {
"entities": "Entities",
"control": "Controls",
@@ -2274,8 +2286,6 @@
"hide_disabled": "Hide disabled",
"disabled_entities": "+{count} {count, plural,\n one {disabled entity}\n other {disabled entities}\n}"
},
- "scripts": "Scripts",
- "scenes": "Scenes",
"confirm_rename_entity_ids": "Do you also want to rename the entity IDs of your entities?",
"confirm_rename_entity_ids_warning": "This will not change any configuration (like automations, scripts, scenes, dashboards) that is currently using these entities! You will have to update them yourself to use the new entity IDs!",
"confirm_disable_config_entry": "There are no more devices for the config entry {entry_name}, do you want to instead disable the config entry?",
@@ -3644,6 +3654,11 @@
"delete_prompt": "Delete this message?",
"delete_button": "Delete"
},
+ "media-browser": {
+ "error": {
+ "player_not_exist": "Media player {name} does not exist"
+ }
+ },
"map": {
"edit_zones": "Edit Zones"
},
@@ -4096,7 +4111,8 @@
"setup": {
"next": "Next",
"back": "Back",
- "done": "Show me my energy dashboard!"
+ "done": "Show me my energy dashboard!",
+ "step": "Step {step} of {steps}"
},
"charts": {
"stat_house_energy_meter": "Total energy consumption",
diff --git a/yarn.lock b/yarn.lock
index 4117444880..4c4a088a29 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1958,10 +1958,10 @@ __metadata:
languageName: node
linkType: hard
-"@lit/reactive-element@npm:1.0.1":
- version: 1.0.1
- resolution: "@lit/reactive-element@npm:1.0.1"
- checksum: 82f8eb195acb766413fa37dafab8dc853547e5fbb901318d9911b3f9410a15ceea37c9a4b0954ab37710e91140af243148af9f72ec3bd14fe71e1d03faaaad7a
+"@lit/reactive-element@npm:1.2.1":
+ version: 1.2.1
+ resolution: "@lit/reactive-element@npm:1.2.1"
+ checksum: 58f1b62c54b1899180b11cd44009ee91ac35099f9016259d3b9cc2f969fc920ab7e7ec32a816986ce89a27c632e25568542c93fdfed6730c19c850f7db0ba4cf
languageName: node
linkType: hard
@@ -9187,7 +9187,7 @@ fsevents@^1.2.7:
leaflet: ^1.7.1
leaflet-draw: ^1.0.4
lint-staged: ^11.1.2
- lit: ^2.0.2
+ lit: ^2.1.2
lit-analyzer: ^1.2.1
lit-vaadin-helpers: ^0.2.1
lodash.template: ^4.5.0
@@ -10776,22 +10776,22 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
-"lit-element@npm:3.0.1":
- version: 3.0.1
- resolution: "lit-element@npm:3.0.1"
+"lit-element@npm:3.1.2":
+ version: 3.1.2
+ resolution: "lit-element@npm:3.1.2"
dependencies:
- "@lit/reactive-element": ^1.0.0
- lit-html: ^2.0.0
- checksum: 3735cd1b96efb44f1ecdcb07406604d7c6feeab07f81cfc904a0f9ab806fab1211e8bf68827513b12e12e61448e3cd6508664d433abd3f0c5c4408b0a6b2d7a6
+ "@lit/reactive-element": ^1.1.0
+ lit-html: ^2.1.0
+ checksum: 56ae568369af7c51cfe7187136ffb0782308ed3a12aa664085bd6761ff89fb60d3ac2ef286ce15154a2eb179d89f8655f7adaa18b8c083091c03dc75dd2ebf16
languageName: node
linkType: hard
-"lit-html@npm:2.0.1":
- version: 2.0.1
- resolution: "lit-html@npm:2.0.1"
+"lit-html@npm:2.1.2":
+ version: 2.1.2
+ resolution: "lit-html@npm:2.1.2"
dependencies:
"@types/trusted-types": ^2.0.2
- checksum: 7ee9e909ec59009539d5b2d7bd07ceb6e182ed5c6535f36da5265dd2f5dc39f9e5f445e8272953a26948ff5724cf110836c792c439883527a2a3b46ecdbbb395
+ checksum: 0c87d83b3577dbb0a2c50743296b6600a6872eac2f23b48da7ba3e604b8c72a8b0e1e48cfe0e00dd6f4ca921ab57f97e20709756f2115077478ffb05efa6cea0
languageName: node
linkType: hard
@@ -10804,14 +10804,14 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
-"lit@npm:^2.0.2":
- version: 2.0.2
- resolution: "lit@npm:2.0.2"
+"lit@npm:^2.1.2":
+ version: 2.1.2
+ resolution: "lit@npm:2.1.2"
dependencies:
- "@lit/reactive-element": ^1.0.0
- lit-element: ^3.0.0
- lit-html: ^2.0.0
- checksum: 52a04b25164da1683c7295b305087794f175165cd1561e03f0c50ae998823f0e26101c82add05dea773e35472fbe3ed84486a4685294897f588d126fe8419e05
+ "@lit/reactive-element": ^1.1.0
+ lit-element: ^3.1.0
+ lit-html: ^2.1.0
+ checksum: dc3d6f30d508e48ad665a5777383c26055ae6514a7bd6a5745ac75cfeeeff8db49aa3b0f32db1a19e43bd7eec2bccd7db8523d5ed445ca0035fe37fddd9fb646
languageName: node
linkType: hard