mirror of
https://github.com/home-assistant/frontend.git
synced 2026-06-05 16:01:46 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0725ce2053 |
@@ -5,6 +5,7 @@ in core bundle slows things down and causes duplicate registration.
|
||||
This is the entry point for providing external app stuff from app entrypoint.
|
||||
*/
|
||||
|
||||
import type { HASSDomEvent } from "../common/dom/fire_event";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { mainWindow } from "../common/dom/get_main_window";
|
||||
import { navigate } from "../common/navigate";
|
||||
@@ -15,6 +16,7 @@ import type {
|
||||
EMIncomingMessageBarCodeScanResult,
|
||||
EMIncomingMessageCommands,
|
||||
ImprovDiscoveredDevice,
|
||||
MatterCommissionFinish,
|
||||
} from "./external_messaging";
|
||||
|
||||
const barCodeListeners = new Set<
|
||||
@@ -91,6 +93,8 @@ export const handleExternalMessage = (
|
||||
fireEvent(window, "improv-discovered-device", msg.payload);
|
||||
} else if (msg.command === "improv/device_setup_done") {
|
||||
fireEvent(window, "improv-device-setup-done");
|
||||
} else if (msg.command === "matter/commission/finish") {
|
||||
fireEvent(window, "matter-commission-finish", msg.payload);
|
||||
} else if (msg.command === "bar_code/scan_result") {
|
||||
barCodeListeners.forEach((listener) => listener(msg));
|
||||
} else if (msg.command === "bar_code/aborted") {
|
||||
@@ -115,5 +119,10 @@ declare global {
|
||||
interface HASSDomEvents {
|
||||
"improv-discovered-device": ImprovDiscoveredDevice;
|
||||
"improv-device-setup-done": undefined;
|
||||
"matter-commission-finish": MatterCommissionFinish;
|
||||
}
|
||||
|
||||
interface GlobalEventHandlersEventMap {
|
||||
"matter-commission-finish": HASSDomEvent<MatterCommissionFinish>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,6 +320,18 @@ export interface EMIncomingMessageKioskModeSet {
|
||||
};
|
||||
}
|
||||
|
||||
export interface MatterCommissionFinish {
|
||||
name: string | null;
|
||||
success: boolean;
|
||||
}
|
||||
|
||||
export interface EMIncomingMessageMatterCommissionFinish extends EMMessage {
|
||||
id: number;
|
||||
type: "command";
|
||||
command: "matter/commission/finish";
|
||||
payload: MatterCommissionFinish;
|
||||
}
|
||||
|
||||
export type EMIncomingMessageCommands =
|
||||
| EMIncomingMessageRestart
|
||||
| EMIncomingMessageNavigate
|
||||
@@ -331,6 +343,7 @@ export type EMIncomingMessageCommands =
|
||||
| EMIncomingMessageBarCodeScanAborted
|
||||
| EMIncomingMessageImprovDeviceDiscovered
|
||||
| EMIncomingMessageImprovDeviceSetupDone
|
||||
| EMIncomingMessageMatterCommissionFinish
|
||||
| EMIncomingMessageKioskModeSet;
|
||||
|
||||
type EMIncomingMessage =
|
||||
@@ -346,6 +359,7 @@ export interface ExternalConfig {
|
||||
canWriteTag?: boolean;
|
||||
hasExoPlayer?: boolean;
|
||||
canCommissionMatter?: boolean;
|
||||
hasMatterStatusReport?: boolean;
|
||||
canImportThreadCredentials?: boolean;
|
||||
canTransferThreadCredentialsToKeychain?: boolean;
|
||||
hasAssist?: boolean;
|
||||
|
||||
+62
-1
@@ -2,6 +2,7 @@ import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { dynamicElement } from "../../../../../common/dom/dynamic-element-directive";
|
||||
import type { HASSDomEvent } from "../../../../../common/dom/fire_event";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { computeDomain } from "../../../../../common/entity/compute_domain";
|
||||
import { computeDeviceName } from "../../../../../common/entity/compute_device_name";
|
||||
@@ -10,6 +11,7 @@ import "../../../../../components/ha-dialog-footer";
|
||||
import "../../../../../components/ha-icon-button-arrow-prev";
|
||||
import "../../../../../components/ha-button";
|
||||
import "../../../../../components/ha-dialog";
|
||||
import type { MatterCommissionFinish } from "../../../../../external_app/external_messaging";
|
||||
import {
|
||||
commissionMatterDevice,
|
||||
watchForNewMatterDevice,
|
||||
@@ -82,6 +84,10 @@ class DialogMatterAddDevice extends LitElement {
|
||||
|
||||
@state() private _mainEntity?: ExtEntityRegistryEntry;
|
||||
|
||||
@state() private _proposedDeviceName?: string;
|
||||
|
||||
@state() private _commissioningFinished = false;
|
||||
|
||||
@state() private _deviceAddedState: {
|
||||
name: string;
|
||||
area: string | undefined;
|
||||
@@ -104,15 +110,63 @@ class DialogMatterAddDevice extends LitElement {
|
||||
// make sure a refresh of the page will navigate to the device page, old iOS apps will refresh the webview when commissioning is done
|
||||
setRefreshUrl(`/config/devices/device/${device.id}`);
|
||||
this._newDevice = device;
|
||||
this._step = "device_added";
|
||||
this._fetchMainEntity();
|
||||
this._maybeShowDeviceAdded();
|
||||
});
|
||||
if (this._waitForCommissioningFinish) {
|
||||
window.addEventListener(
|
||||
"matter-commission-finish",
|
||||
this._handleCommissionFinish
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this._open = false;
|
||||
}
|
||||
|
||||
private get _waitForCommissioningFinish(): boolean {
|
||||
// When the app supports reporting Matter commissioning status, defer
|
||||
// advancing past the spinner until we receive matter/commission/finish.
|
||||
return !!this.hass.auth.external?.config.hasMatterStatusReport;
|
||||
}
|
||||
|
||||
private _maybeShowDeviceAdded(): void {
|
||||
if (!this._newDevice) {
|
||||
return;
|
||||
}
|
||||
if (this._waitForCommissioningFinish && !this._commissioningFinished) {
|
||||
return;
|
||||
}
|
||||
this._step = "device_added";
|
||||
}
|
||||
|
||||
private _handleCommissionFinish = (
|
||||
ev: HASSDomEvent<MatterCommissionFinish>
|
||||
) => {
|
||||
const { name, success } = ev.detail;
|
||||
if (!success) {
|
||||
if (this._newDevice) {
|
||||
// Device already showed up in the registry — ignore the failure signal
|
||||
// and let the user finish the rename flow.
|
||||
return;
|
||||
}
|
||||
showToast(this, {
|
||||
message: this.hass.localize(
|
||||
"ui.dialogs.matter-add-device.add_device_failed"
|
||||
),
|
||||
duration: 2000,
|
||||
});
|
||||
this.closeDialog();
|
||||
return;
|
||||
}
|
||||
this._commissioningFinished = true;
|
||||
if (name) {
|
||||
this._proposedDeviceName = name;
|
||||
}
|
||||
this._maybeShowDeviceAdded();
|
||||
};
|
||||
|
||||
protected updated(changedProps: Map<string, unknown>): void {
|
||||
// Retry fetching main entity when hass updates (entities may not be available immediately)
|
||||
if (
|
||||
@@ -160,6 +214,8 @@ class DialogMatterAddDevice extends LitElement {
|
||||
this._newDevice = undefined;
|
||||
this._mainEntity = undefined;
|
||||
this._mainEntityFetched = false;
|
||||
this._proposedDeviceName = undefined;
|
||||
this._commissioningFinished = false;
|
||||
this._deviceAddedState = {
|
||||
name: "",
|
||||
area: undefined,
|
||||
@@ -168,6 +224,10 @@ class DialogMatterAddDevice extends LitElement {
|
||||
};
|
||||
this._unsub?.();
|
||||
this._unsub = undefined;
|
||||
window.removeEventListener(
|
||||
"matter-commission-finish",
|
||||
this._handleCommissionFinish
|
||||
);
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
@@ -211,6 +271,7 @@ class DialogMatterAddDevice extends LitElement {
|
||||
hass: this.hass,
|
||||
device: this._newDevice,
|
||||
mainEntity: this._mainEntity,
|
||||
proposedName: this._proposedDeviceName,
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
|
||||
+16
-2
@@ -36,6 +36,8 @@ class MatterAddDeviceDeviceAdded extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public mainEntity?: ExtEntityRegistryEntry;
|
||||
|
||||
@property({ attribute: false }) public proposedName?: string;
|
||||
|
||||
@state() private _deviceName = "";
|
||||
|
||||
@state() private _area: string | undefined;
|
||||
@@ -49,8 +51,18 @@ class MatterAddDeviceDeviceAdded extends LitElement {
|
||||
protected willUpdate(changedProps: PropertyValues) {
|
||||
if (!this._initialized && this.device) {
|
||||
this._initialized = true;
|
||||
this._deviceName = computeDeviceName(this.device) ?? "";
|
||||
this._deviceName =
|
||||
this.proposedName || (computeDeviceName(this.device) ?? "");
|
||||
this._area = this.device.area_id ?? undefined;
|
||||
} else if (
|
||||
changedProps.has("proposedName") &&
|
||||
this.proposedName &&
|
||||
this.device &&
|
||||
this._deviceName === (computeDeviceName(this.device) ?? "")
|
||||
) {
|
||||
// proposedName arrived after we initialized, and the user hasn't
|
||||
// changed the name yet — adopt it
|
||||
this._deviceName = this.proposedName;
|
||||
}
|
||||
if (
|
||||
!this._deviceClassInitialized &&
|
||||
@@ -158,7 +170,9 @@ class MatterAddDeviceDeviceAdded extends LitElement {
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
<div class="device-name">
|
||||
<span>${computeDeviceName(this.device)}</span>
|
||||
<span
|
||||
>${this.proposedName || computeDeviceName(this.device)}</span
|
||||
>
|
||||
<span class="secondary">Matter</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user