feat: Add live.microphone.auto_mute / auto_unmute (#2482)

This commit is contained in:
Dermot Duffy
2026-06-30 17:45:12 -07:00
committed by dermotduffy
parent 9eb503deff
commit a68b665f03
16 changed files with 874 additions and 48 deletions
+47 -1
View File
@@ -1,8 +1,17 @@
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import {
CSSResultGroup,
html,
LitElement,
PropertyValues,
TemplateResult,
unsafeCSS,
} from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { CameraManager } from '../../camera-manager/manager.js';
import { MicrophoneManager } from '../../card-controller/microphone-manager.js';
import { MicrophoneState } from '../../card-controller/types.js';
import { ViewManagerEpoch } from '../../card-controller/view/types.js';
import { MicrophoneActionsController } from '../../components-lib/live/microphone-actions-controller.js';
import '../../components-lib/live/types.js';
import { LiveConfig } from '../../config/schema/live.js';
import { CardWideConfig } from '../../config/schema/types.js';
@@ -28,12 +37,49 @@ export class AdvancedCameraCardLive extends LitElement {
@property({ attribute: false })
public cardWideConfig?: CardWideConfig;
@property({ attribute: false })
public microphoneManager?: MicrophoneManager;
@property({ attribute: false })
public microphoneState?: MicrophoneState;
@property({ attribute: false, hasChanged: contentsChanged })
public triggeredCameraIDs?: Set<string>;
private _microphoneActionsController = new MicrophoneActionsController();
public connectedCallback(): void {
super.connectedCallback();
this._microphoneActionsController.setRoot(this);
}
public disconnectedCallback(): void {
this._microphoneActionsController.destroy();
super.disconnectedCallback();
}
protected willUpdate(changedProps: PropertyValues): void {
if (changedProps.has('liveConfig') || changedProps.has('microphoneManager')) {
this._microphoneActionsController.setOptions({
microphoneManager: this.microphoneManager,
autoMuteConditions: this.liveConfig?.microphone.auto_mute,
autoUnmuteConditions: this.liveConfig?.microphone.auto_unmute,
});
}
if (changedProps.has('viewManagerEpoch')) {
// The live element is also rendered (and this willUpdate runs) when
// `live.preload` is true even while the user is on gallery/viewer/
// timeline. `view.camera` is set across all views, so without this gate
// `auto_unmute: ['selected']` would prompt for / open the microphone
// from a hidden live view. Treat the live view as having no selected
// camera unless it is the active view.
const view = this.viewManagerEpoch?.manager.getView();
this._microphoneActionsController.setSelectedCamera(
view?.is('live') ? view.camera ?? null : null,
);
}
}
protected render(): TemplateResult | void {
if (!this.hass || !this.cameraManager) {
return;
+5
View File
@@ -11,6 +11,7 @@ import { classMap } from 'lit/directives/class-map.js';
import { CameraManager } from '../camera-manager/manager.js';
import { FoldersManager } from '../card-controller/folders/manager.js';
import { IssuePresence } from '../card-controller/issues/types.js';
import { MicrophoneManager } from '../card-controller/microphone-manager.js';
import { MicrophoneState } from '../card-controller/types.js';
import { ViewItemManager } from '../card-controller/view/item-manager.js';
import { ViewManagerEpoch } from '../card-controller/view/types.js';
@@ -60,6 +61,9 @@ export class AdvancedCameraCardViews extends LitElement {
@property({ attribute: false })
public hide?: boolean;
@property({ attribute: false })
public microphoneManager?: MicrophoneManager;
@property({ attribute: false })
public microphoneState?: MicrophoneState;
@@ -230,6 +234,7 @@ export class AdvancedCameraCardViews extends LitElement {
.liveConfig=${this.config.live}
.cameraManager=${this.cameraManager}
.cardWideConfig=${this.cardWideConfig}
.microphoneManager=${this.microphoneManager}
.microphoneState=${this.microphoneState}
.triggeredCameraIDs=${this.triggeredCameraIDs}
class="${classMap(liveClasses)}"