diff --git a/build-scripts/list-plugins-and-polyfills.js b/build-scripts/list-plugins-and-polyfills.js new file mode 100755 index 0000000000..a0978e6dba --- /dev/null +++ b/build-scripts/list-plugins-and-polyfills.js @@ -0,0 +1,59 @@ +#!/usr/bin/env node +// Script to print Babel plugins and Core JS polyfills that will be used by browserslist environments + +import { version as babelVersion } from "@babel/core"; +import presetEnv from "@babel/preset-env"; +import compilationTargets from "@babel/helper-compilation-targets"; +import coreJSCompat from "core-js-compat"; +import { logPlugin } from "@babel/preset-env/lib/debug.js"; +import { babelOptions } from "./bundle.cjs"; + +const detailsOpen = (heading) => + `
\n

${heading}

\n`; +const detailsClose = "
\n"; + +const dummyAPI = { + version: babelVersion, + assertVersion: () => {}, + caller: (callback) => + callback({ + name: "Dummy Bundler", + supportsStaticESM: true, + supportsDynamicImport: true, + supportsTopLevelAwait: true, + supportsExportNamespaceFrom: true, + }), + targets: () => ({}), +}; + +for (const buildType of ["Modern", "Legacy"]) { + const browserslistEnv = buildType.toLowerCase(); + const babelOpts = babelOptions({ latestBuild: browserslistEnv === "modern" }); + const presetEnvOpts = babelOpts.presets[0][1]; + + // Invoking preset-env in debug mode will log the included plugins + console.log(detailsOpen(`${buildType} Build Babel Plugins`)); + presetEnv.default(dummyAPI, { + ...presetEnvOpts, + browserslistEnv, + debug: true, + }); + console.log(detailsClose); + + // Manually log the Core-JS polyfills using the same technique + if (presetEnvOpts.useBuiltIns) { + console.log(detailsOpen(`${buildType} Build Core-JS Polyfills`)); + const targets = compilationTargets.default(babelOpts?.targets, { + browserslistEnv, + }); + const polyfillList = coreJSCompat({ targets }).list; + console.log( + "The following %i polyfills may be injected by Babel:\n", + polyfillList.length + ); + for (const polyfill of polyfillList) { + logPlugin(polyfill, targets, coreJSCompat.data); + } + console.log(detailsClose); + } +} diff --git a/build-scripts/list-preset-env-plugins.js b/build-scripts/list-preset-env-plugins.js deleted file mode 100755 index 5e869a4ef1..0000000000 --- a/build-scripts/list-preset-env-plugins.js +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env node -// Script to print Babel plugins that will be used by browserslist environments - -import { version as babelVersion } from "@babel/core"; -import presetEnv from "@babel/preset-env"; -import { babelOptions } from "./bundle.cjs"; - -const dummyAPI = { - version: babelVersion, - assertVersion: () => {}, - caller: (callback) => - callback({ - name: "Dummy Bundler", - supportsStaticESM: true, - supportsDynamicImport: true, - supportsTopLevelAwait: true, - supportsExportNamespaceFrom: true, - }), - targets: () => ({}), -}; - -for (const browserslistEnv of ["modern", "legacy"]) { - console.log("\nBrowsersList Environment = %s\n", browserslistEnv); - presetEnv.default(dummyAPI, { - ...babelOptions({ latestBuild: browserslistEnv === "modern" }) - .presets[0][1], - browserslistEnv, - debug: true, - }); -} diff --git a/pyproject.toml b/pyproject.toml index bb03d7594a..38974e1400 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20230428.0" +version = "20230501.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" diff --git a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts index ae97087550..87ea70b4e5 100644 --- a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts +++ b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts @@ -401,6 +401,7 @@ export class HaVoiceCommandDialog extends LitElement { } }); } + this._stt_binary_handler_id = undefined; this._audioBuffer = []; const userMessage: Message = { who: "user", @@ -463,6 +464,7 @@ export class HaVoiceCommandDialog extends LitElement { } if (event.type === "run-end") { + this._stt_binary_handler_id = undefined; unsub(); } @@ -509,6 +511,7 @@ export class HaVoiceCommandDialog extends LitElement { } // Send empty message to indicate we're done streaming. this._sendAudioChunk(new Int16Array()); + this._stt_binary_handler_id = undefined; } this._audioBuffer = undefined; } diff --git a/src/panels/calendar/dialog-calendar-event-editor.ts b/src/panels/calendar/dialog-calendar-event-editor.ts index 35660d67ae..f6980ba76d 100644 --- a/src/panels/calendar/dialog-calendar-event-editor.ts +++ b/src/panels/calendar/dialog-calendar-event-editor.ts @@ -498,12 +498,22 @@ class DialogCalendarEventEditor extends LitElement { this._submitting = false; return; } + const eventData = this._calculateData(); + if (eventData.rrule && range === RecurrenceRange.THISEVENT) { + // Updates to a single instance of a recurring event by definition + // cannot change the recurrence rule and doing so would be invalid. + // It is difficult to detect if the user changed the recurrence rule + // since updating the date may change it implicitly (e.g. day of week + // of the event changes) so we just assume the users intent based on + // recurrence range and drop any other rrule changes. + eventData.rrule = undefined; + } try { await updateCalendarEvent( this.hass!, this._calendarId!, entry.uid!, - this._calculateData(), + eventData, entry.recurrence_id || "", range! ); diff --git a/src/panels/config/voice-assistants/dialog-voice-assistant-pipeline-detail.ts b/src/panels/config/voice-assistants/dialog-voice-assistant-pipeline-detail.ts index 89f1222fe8..aa221e8b66 100644 --- a/src/panels/config/voice-assistants/dialog-voice-assistant-pipeline-detail.ts +++ b/src/panels/config/voice-assistants/dialog-voice-assistant-pipeline-detail.ts @@ -49,10 +49,10 @@ export class DialogVoiceAssistantPipelineDetail extends LitElement { public showDialog(params: VoiceAssistantPipelineDetailsDialogParams): void { this._params = params; this._error = undefined; + this._cloudActive = this._params.cloudActiveSubscription; if (this._params.pipeline) { this._data = this._params.pipeline; this._preferred = this._params.preferred; - this._cloudActive = this._params.cloudActiveSubscription; } else { this._data = { language: ( diff --git a/src/panels/config/voice-assistants/entity-voice-settings.ts b/src/panels/config/voice-assistants/entity-voice-settings.ts index bc5a3b9a8d..b985447260 100644 --- a/src/panels/config/voice-assistants/entity-voice-settings.ts +++ b/src/panels/config/voice-assistants/entity-voice-settings.ts @@ -1,3 +1,4 @@ +import { mdiAlertCircle } from "@mdi/js"; import { css, CSSResultGroup, @@ -32,8 +33,8 @@ import { updateEntityRegistryEntry, } from "../../../data/entity_registry"; import { - GoogleEntity, fetchCloudGoogleEntity, + GoogleEntity, } from "../../../data/google_assistant"; import { exposeEntities, voiceAssistants } from "../../../data/voice"; import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; @@ -223,7 +224,8 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) { /> ${voiceAssistants[key].name} ${!supported - ? html`
+ ? html`
+ ${this.hass.localize( "ui.dialogs.voice-settings.unsupported" )} @@ -379,6 +381,15 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) { ha-checkbox { --mdc-checkbox-state-layer-size: 40px; } + .unsupported { + display: flex; + align-items: center; + } + .unsupported ha-svg-icon { + color: var(--error-color); + --mdc-icon-size: 16px; + margin-right: 4px; + } .header { margin-top: 8px; margin-bottom: 4px; diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index 6fda17d966..02b18b6122 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -1063,7 +1063,8 @@ class HUIRoot extends LitElement { padding-right: env(safe-area-inset-right); padding-bottom: env(safe-area-inset-bottom); } - hui-view { + hui-view, + hui-unused-entities { flex: 1 1 100%; max-width: 100%; } diff --git a/src/translations/en.json b/src/translations/en.json index 23506ac442..fa194a5049 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2761,7 +2761,7 @@ "alert_password_change_required": "You need to change your password before logging in.", "alert_email_confirm_necessary": "You need to confirm your email before logging in.", "cloud_pipeline_title": "Want to use Home Assistant Cloud for your voice assistant?", - "cloud_pipeline_text": "We created a new assistant for you, using the great text-to-speech and speech-to-text engines from Home Assistant Cloud. Would you like to set this assistant as the preferred assistant?" + "cloud_pipeline_text": "We created a new assistant for you, using the superior text-to-speech and speech-to-text engines from Home Assistant Cloud. Would you like to set this assistant as the preferred assistant?" }, "forgot_password": { "title": "Forgot password",