Repository: dermotduffy/frigate-hass-card
Pull request #1535 (2024-09-15 15:47:20)

docs: Typo in Profiles configuration page
Mentions `low-profile` mode inside the `low-performance` profile section, so I'm assuming it is a typo and supposed to be `low-performance` instead.


Patch:
diff --git a/.github/workflows/semantic-prs.yml b/.github/workflows/semantic-prs.yml
new file mode 100644
index 00000000..c6a9c862
--- /dev/null
+++ b/.github/workflows/semantic-prs.yml
@@ -0,0 +1,22 @@
+---
+name: Semantic PR
+
+on:
+  pull_request_target:
+    types:
+      - opened
+      - edited
+      - synchronize
+      - reopened
+
+permissions:
+  pull-requests: read
+
+jobs:
+  main:
+    name: Validate PR title
+    runs-on: ubuntu-latest
+    steps:
+      - uses: amannn/action-semantic-pull-request@v5
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/semantic-release.yml b/.github/workflows/semantic-release.yml
index 4ad40ffe..29379a71 100644
--- a/.github/workflows/semantic-release.yml
+++ b/.github/workflows/semantic-release.yml
@@ -1,17 +1,17 @@
 ---
 name: Semantic Release
 
-permissions:
-  contents: write # To be able to publish a GitHub release
-  issues: write # To be able to comment on released issues
-  pull-requests: write # To be able to comment on released pull requests
-
 on:
   push:
     branches:
       - main
   workflow_dispatch:
 
+permissions:
+  contents: write # To be able to publish a GitHub release
+  issues: write # To be able to comment on released issues
+  pull-requests: write # To be able to comment on released pull requests
+
 jobs:
   get-next-version:
     runs-on: ubuntu-latest
diff --git a/docs/configuration/actions/custom/README.md b/docs/configuration/actions/custom/README.md
index 4f7d1b67..c269922d 100644
--- a/docs/configuration/actions/custom/README.md
+++ b/docs/configuration/actions/custom/README.md
@@ -248,6 +248,15 @@ action: custom:frigate-card-action
 frigate_card_action: menu_toggle
 ```
 
+## `microphone_disconnect`
+
+Disconnect the microphone during [2-way audio](../../../usage/2-way-audio.md).
+
+```yaml
+action: custom:frigate-card-action
+frigate_card_action: microphone_disconnect
+```
+
 ## `microphone_mute`
 
 Mute the microphone during [2-way audio](../../../usage/2-way-audio.md).
diff --git a/docs/configuration/dimensions.md b/docs/configuration/dimensions.md
index a499c558..f9731286 100644
--- a/docs/configuration/dimensions.md
+++ b/docs/configuration/dimensions.md
@@ -13,12 +13,11 @@ dimensions:
   # [...]
 ```
 
-| Option              | Default   | Description                                                                                                                                                                                                                                                            |
-| ------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `aspect_ratio_mode` | `dynamic` | The aspect ratio mode to use. Acceptable values: `dynamic`, `static`, `unconstrained`. See below.                                                                                                                                                                      |
-| `aspect_ratio`      | `16:9`    | The aspect ratio to use. Acceptable values: `[W]:[H]` or `[W]/[H]`. See below.                                                                                                                                                                                         |
-| `max_height`        | `100vh`   | The maximum allowable height for the card. Specified in [CSS units](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units). Generally users should not need to change this setting unless they have set an `unconstrained` aspect ratio. |
-| `min_height`        | `100px`   | The minimum allowable height for the card. Specified in [CSS units](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units). Generally users should not need to change this setting.                                                      |
+| Option              | Default   | Description                                                                                                                                                                             |
+| ------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `aspect_ratio_mode` | `dynamic` | The aspect ratio mode to use. Acceptable values: `dynamic`, `static`, `unconstrained`. See below.                                                                                       |
+| `aspect_ratio`      | `16:9`    | The aspect ratio to use. Acceptable values: `[W]:[H]` or `[W]/[H]`. See below.                                                                                                          |
+| `height`            | `auto`    | The height for the card. Specified in [CSS units](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units). Generally users should not need to change this. |
 
 ### `aspect_ratio_mode`
 
@@ -42,6 +41,5 @@ dimensions:
 dimensions:
   aspect_ratio_mode: dynamic
   aspect_ratio: 16:9
-  max_height: 100vh
-  min_height: 100px
+  height: auto
 ```
diff --git a/docs/configuration/profiles.md b/docs/configuration/profiles.md
index a3b3a845..ac4441b3 100644
--- a/docs/configuration/profiles.md
+++ b/docs/configuration/profiles.md
@@ -23,7 +23,7 @@ the user.
 
 For low end devices, the `low-performance` profile will adjust card defaults to attempt to increase performance.
 
-Principles used in the selection of options set by `low-profile` profile mode:
+Principles used in the selection of options set by `low-performance` profile mode:
 
 - Get 'out of the box' performance similar to the basic "Home Assistant Picture Glance" card.
 - Do not break the visual aesthetic of the card.
diff --git a/docs/usage/url-actions.md b/docs/usage/url-actions.md
index fa5a5ea0..8595d030 100644
--- a/docs/usage/url-actions.md
+++ b/docs/usage/url-actions.md
@@ -46,31 +46,31 @@ unless the action is targeted with a `CARD_ID` as shown above.
 
 Only a subset of all [actions](../configuration/actions/README.md) are supported in URL form.
 
-| Action                                 | Supported in URL         | Explanation                                                                                                         |
-| -------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------- |
-| `camera_select`                        | :white_check_mark:       |                                                                                                                     |
-| `camera_ui`                            | :white_check_mark:       |                                                                                                                     |
-| `clip`                                 | :white_check_mark:       |                                                                                                                     |
-| `clips`                                | :white_check_mark:       |                                                                                                                     |
-| `default`                              | :white_check_mark:       |                                                                                                                     |
-| `download`                             | :heavy_multiplication_x: | Latest media information is not available on initial render.                                                        |
-| `expand`                               | :white_check_mark:       |                                                                                                                     |
-| `fullscreen`                           | :heavy_multiplication_x: | Javascript does not support activating fullscreen without direct human interaction. Use `expand` as an alternative. |
-| `image`                                | :white_check_mark:       |                                                                                                                     |
-| `live_substream_select`                | :white_check_mark:       |                                                                                                                     |
-| `live`                                 | :white_check_mark:       |                                                                                                                     |
-| `media_player`                         | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this.                         |
-| `menu_toggle`                          | :white_check_mark:       |                                                                                                                     |
-| `microphone_mute`, `microphone_unmute` | :heavy_multiplication_x: |                                                                                                                     |
-| `mute`, `unmute`                       | :heavy_multiplication_x: |                                                                                                                     |
-| `play`, `pause`                        | :heavy_multiplication_x: |                                                                                                                     |
-| `ptz`                                  | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this.                         |
-| `recording`                            | :white_check_mark:       |                                                                                                                     |
-| `recordings`                           | :white_check_mark:       |                                                                                                                     |
-| `screenshot`                           | :heavy_multiplication_x: | Latest media information is not available on initial render.                                                        |
-| `ptz_controls`                         | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this.                         |
-| `snapshot`                             | :white_check_mark:       |                                                                                                                     |
-| `snapshots`                            | :white_check_mark:       |                                                                                                                     |
+| Action                                                          | Supported in URL         | Explanation                                                                                                         |
+| --------------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------- |
+| `camera_select`                                                 | :white_check_mark:       |                                                                                                                     |
+| `camera_ui`                                                     | :white_check_mark:       |                                                                                                                     |
+| `clip`                                                          | :white_check_mark:       |                                                                                                                     |
+| `clips`                                                         | :white_check_mark:       |                                                                                                                     |
+| `default`                                                       | :white_check_mark:       |                                                                                                                     |
+| `download`                                                      | :heavy_multiplication_x: | Latest media information is not available on initial render.                                                        |
+| `expand`                                                        | :white_check_mark:       |                                                                                                                     |
+| `fullscreen`                                                    | :heavy_multiplication_x: | Javascript does not support activating fullscreen without direct human interaction. Use `expand` as an alternative. |
+| `image`                                                         | :white_check_mark:       |                                                                                                                     |
+| `live_substream_select`                                         | :white_check_mark:       |                                                                                                                     |
+| `live`                                                          | :white_check_mark:       |                                                                                                                     |
+| `media_player`                                                  | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this.                         |
+| `menu_toggle`                                                   | :white_check_mark:       |                                                                                                                     |
+| `microphone_disconnect`, `microphone_mute`, `microphone_unmute` | :heavy_multiplication_x: |                                                                                                                     |
+| `mute`, `unmute`                                                | :heavy_multiplication_x: |                                                                                                                     |
+| `play`, `pause`                                                 | :heavy_multiplication_x: |                                                                                                                     |
+| `ptz`                                                           | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this.                         |
+| `recording`                                                     | :white_check_mark:       |                                                                                                                     |
+| `recordings`                                                    | :white_check_mark:       |                                                                                                                     |
+| `screenshot`                                                    | :heavy_multiplication_x: | Latest media information is not available on initial render.                                                        |
+| `ptz_controls`                                                  | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this.                         |
+| `snapshot`                                                      | :white_check_mark:       |                                                                                                                     |
+| `snapshots`                                                     | :white_check_mark:       |                                                                                                                     |
 
 ## Examples
 
diff --git a/src/card-controller/actions/actions/microphone-disconnect.ts b/src/card-controller/actions/actions/microphone-disconnect.ts
new file mode 100644
index 00000000..f6771a60
--- /dev/null
+++ b/src/card-controller/actions/actions/microphone-disconnect.ts
@@ -0,0 +1,9 @@
+import { GeneralActionConfig } from '../../../config/types';
+import { CardActionsAPI } from '../../types';
+import { FrigateCardAction } from './base';
+
+export class MicrophoneDisconnectAction extends FrigateCardAction<GeneralActionConfig> {
+  public async execute(api: CardActionsAPI): Promise<void> {
+    api.getMicrophoneManager().disconnect();
+  }
+}
diff --git a/src/card-controller/actions/factory.ts b/src/card-controller/actions/factory.ts
index 21d36c77..e67d831b 100644
--- a/src/card-controller/actions/factory.ts
+++ b/src/card-controller/actions/factory.ts
@@ -13,6 +13,7 @@ import { GenericAction } from './actions/generic';
 import { LogAction } from './actions/log';
 import { MediaPlayerAction } from './actions/media-player';
 import { MenuToggleAction } from './actions/menu-toggle';
+import { MicrophoneDisconnectAction } from './actions/microphone-disconnect';
 import { MicrophoneMuteAction } from './actions/microphone-mute';
 import { MicrophoneUnmuteAction } from './actions/microphone-unmute';
 import { MuteAction } from './actions/mute';
@@ -96,6 +97,12 @@ export class ActionFactory {
         return new SubstreamOnAction(context, frigateCardAction, options?.config);
       case 'media_player':
         return new MediaPlayerAction(context, frigateCardAction, options?.config);
+      case 'microphone_disconnect':
+        return new MicrophoneDisconnectAction(
+          context,
+          frigateCardAction,
+          options?.config,
+        );
       case 'microphone_mute':
         return new MicrophoneMuteAction(context, frigateCardAction, options?.config);
       case 'microphone_unmute':
diff --git a/src/card-controller/style-manager.ts b/src/card-controller/style-manager.ts
index ff3245fd..e959e0f3 100644
--- a/src/card-controller/style-manager.ts
+++ b/src/card-controller/style-manager.ts
@@ -62,8 +62,7 @@ export class StyleManager {
     const config = this._api.getConfigManager().getConfig();
     if (config) {
       const card = this._api.getCardElementManager().getElement();
-      card.style.setProperty('--frigate-card-min-height', config.dimensions.min_height);
-      card.style.setProperty('--frigate-card-max-height', config.dimensions.max_height);
+      card.style.setProperty('--frigate-card-height', config.dimensions.height);
     }
   }
 
diff --git a/src/config/management.ts b/src/config/management.ts
index 570b0f91..93a5e40c 100644
--- a/src/config/management.ts
+++ b/src/config/management.ts
@@ -11,6 +11,7 @@ import {
   CONF_CAMERAS_GLOBAL_JSMPEG,
   CONF_CAMERAS_GLOBAL_PTZ,
   CONF_CAMERAS_GLOBAL_WEBRTC_CARD,
+  CONF_DIMENSIONS_HEIGHT,
   CONF_ELEMENTS,
   CONF_LIVE_CONTROLS_THUMBNAILS_EVENTS_MEDIA_TYPE,
   CONF_LIVE_CONTROLS_TIMELINE_EVENTS_MEDIA_TYPE,
@@ -878,4 +879,6 @@ const UPGRADES = [
       typeof data === 'object' && data ? (data as RawFrigateCardConfig) : {},
     );
   },
+  upgradeMoveToWithOverrides('dimensions.max_height', CONF_DIMENSIONS_HEIGHT),
+  deleteWithOverrides('dimensions.min_height'),
 ];
diff --git a/src/config/types.ts b/src/config/types.ts
index 4a6f3056..0250a9b9 100644
--- a/src/config/types.ts
+++ b/src/config/types.ts
@@ -270,6 +270,7 @@ const FRIGATE_CARD_GENERAL_ACTIONS = [
   'live_substream_off',
   'live_substream_on',
   'menu_toggle',
+  'microphone_disconnect',
   'microphone_mute',
   'microphone_unmute',
   'mute',
@@ -1856,8 +1857,7 @@ export type GalleryConfig = z.infer<typeof galleryConfigSchema>;
 const dimensionsConfigDefault = {
   aspect_ratio_mode: 'dynamic' as const,
   aspect_ratio: [16, 9],
-  max_height: '100vh',
-  min_height: '100px',
+  height: 'auto',
 };
 
 export const dimensionsConfigSchema = z
@@ -1866,8 +1866,7 @@ export const dimensionsConfigSchema = z
       .enum(['dynamic', 'static', 'unconstrained'])
       .default(dimensionsConfigDefault.aspect_ratio_mode),
     aspect_ratio: aspectRatioSchema.default(dimensionsConfigDefault.aspect_ratio),
-    max_height: z.string().default(dimensionsConfigDefault.max_height),
-    min_height: z.string().default(dimensionsConfigDefault.min_height),
+    height: z.string().default(dimensionsConfigDefault.height),
   })
   .default(dimensionsConfigDefault);
 
diff --git a/src/const.ts b/src/const.ts
index c9b1eb9f..2b851ffa 100644
--- a/src/const.ts
+++ b/src/const.ts
@@ -346,8 +346,7 @@ const CONF_DIMENSIONS = 'dimensions' as const;
 export const CONF_DIMENSIONS_ASPECT_RATIO = `${CONF_DIMENSIONS}.aspect_ratio` as const;
 export const CONF_DIMENSIONS_ASPECT_RATIO_MODE =
   `${CONF_DIMENSIONS}.aspect_ratio_mode` as const;
-export const CONF_DIMENSIONS_MAX_HEIGHT = `${CONF_DIMENSIONS}.max_height` as const;
-export const CONF_DIMENSIONS_MIN_HEIGHT = `${CONF_DIMENSIONS}.min_height` as const;
+export const CONF_DIMENSIONS_HEIGHT = `${CONF_DIMENSIONS}.height` as const;
 
 export const CONF_OVERRIDES = 'overrides' as const;
 
diff --git a/src/editor.ts b/src/editor.ts
index 8b9c0da3..194fce21 100644
--- a/src/editor.ts
+++ b/src/editor.ts
@@ -86,8 +86,7 @@ import {
   CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL,
   CONF_DIMENSIONS_ASPECT_RATIO,
   CONF_DIMENSIONS_ASPECT_RATIO_MODE,
-  CONF_DIMENSIONS_MAX_HEIGHT,
-  CONF_DIMENSIONS_MIN_HEIGHT,
+  CONF_DIMENSIONS_HEIGHT,
   CONF_IMAGE_ENTITY,
   CONF_IMAGE_ENTITY_PARAMETERS,
   CONF_IMAGE_MODE,
@@ -2805,8 +2804,7 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
                 this._aspectRatioModes,
               )}
               ${this._renderStringInput(CONF_DIMENSIONS_ASPECT_RATIO)}
-              ${this._renderStringInput(CONF_DIMENSIONS_MAX_HEIGHT)}
-              ${this._renderStringInput(CONF_DIMENSIONS_MIN_HEIGHT)}
+              ${this._renderStringInput(CONF_DIMENSIONS_HEIGHT)}
             </div>`
           : ''}
         ${this._renderOptionSetHeader(
diff --git a/src/localize/languages/ca.json b/src/localize/languages/ca.json
index 01521890..56c21ac0 100644
--- a/src/localize/languages/ca.json
+++ b/src/localize/languages/ca.json
@@ -267,8 +267,7 @@
         "static": "Relació d'aspecte estàtica",
         "unconstrained": "Relació d'aspecte sense restriccions"
       },
-      "max_height": "Alçada màxima de la targeta en unitats CSS (p. ex., '100vh')",
-      "min_height": "Alçada mínima de la targeta en unitats CSS (p. ex., '100 px')"
+      "height": ""
     },
     "live": {
       "auto_mute": "Silencia automàticament les càmeres en directe",
diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json
index 692edddf..334ad7f6 100644
--- a/src/localize/languages/en.json
+++ b/src/localize/languages/en.json
@@ -267,8 +267,7 @@
         "static": "Static aspect ratio",
         "unconstrained": "Unconstrained aspect ratio"
       },
-      "max_height": "Maximum card height in CSS units (e.g. '100vh')",
-      "min_height": "Minimum card height in CSS units (e.g. '100px')"
+      "height": "Card height in CSS units (e.g. '500px')"
     },
     "live": {
       "auto_mute": "Automatically mute live cameras",
diff --git a/src/localize/languages/fr.json b/src/localize/languages/fr.json
index 981d9524..4a78b072 100644
--- a/src/localize/languages/fr.json
+++ b/src/localize/languages/fr.json
@@ -267,8 +267,7 @@
         "static": "Rapport hauteur/largeur statique",
         "unconstrained": "Rapport hauteur/largeur sans contrainte"
       },
-      "max_height": "Hauteur maximale de la carte en unités CSS (par exemple '100vh')",
-      "min_height": "Hauteur minimale de la carte en unités CSS (par exemple « 100 px »)"
+      "height": ""
     },
     "live": {
       "auto_mute": "Couper automatiquement le son des caméras en direct",
diff --git a/src/localize/languages/it.json b/src/localize/languages/it.json
index b0a0a09e..506b75ed 100644
--- a/src/localize/languages/it.json
+++ b/src/localize/languages/it.json
@@ -267,8 +267,7 @@
         "static": "Proporzioni statiche",
         "unconstrained": "Proporzioni non vincolate"
       },
-      "max_height": "",
-      "min_height": ""
+      "height": ""
     },
     "live": {
       "auto_mute": "Muta automaticamente le telecamere in diretta",
diff --git a/src/localize/languages/pt-BR.json b/src/localize/languages/pt-BR.json
index c54f68fe..f06c7c59 100644
--- a/src/localize/languages/pt-BR.json
+++ b/src/localize/languages/pt-BR.json
@@ -267,8 +267,7 @@
         "static": "Proporção estática",
         "unconstrained": "Proporção irrestrita"
       },
-      "max_height": "",
-      "min_height": ""
+      "height": ""
     },
     "live": {
       "auto_mute": "Silenciar câmeras ao vivo automaticamente",
diff --git a/src/localize/languages/pt-PT.json b/src/localize/languages/pt-PT.json
index 10655859..f2015709 100644
--- a/src/localize/languages/pt-PT.json
+++ b/src/localize/languages/pt-PT.json
@@ -267,8 +267,7 @@
         "static": "Proporção estática",
         "unconstrained": "Proporção irrestrita"
       },
-      "max_height": "",
-      "min_height": ""
+      "height": ""
     },
     "live": {
       "auto_mute": "Silenciar câmeras ao vivo automaticamente",
diff --git a/src/scss/card.scss b/src/scss/card.scss
index dc37e1fb..1005e734 100644
--- a/src/scss/card.scss
+++ b/src/scss/card.scss
@@ -12,11 +12,7 @@
   // keeping the background-color within the radius.
   border-radius: var(--ha-card-border-radius, 4px);
 
-  // Necessary to ensure children adhere to height of outer container (without
-  // this gallery surround is not correctly positioned in the middle of the
-  // card, but rather the middle of the scrolling gallery container).
-  max-height: var(--frigate-card-max-height);
-  min-height: var(--frigate-card-min-height);
+  height: var(--frigate-card-height);
 
   // Ensure all clicks at the top level work.
   pointer-events: all;
@@ -30,8 +26,7 @@
   --frigate-card-expand-height: none;
   --frigate-card-expand-aspect-ratio: unset;
 
-  --frigate-card-max-height: none;
-  --frigate-card-min-height: none;
+  --frigate-card-height: auto;
 }
 
 :host([dark]) {
diff --git a/src/scss/gallery.scss b/src/scss/gallery.scss
index 9f12b3be..958bf332 100644
--- a/src/scss/gallery.scss
+++ b/src/scss/gallery.scss
@@ -5,8 +5,9 @@
 }
 
 frigate-card-surround-basic {
-  // This must be re-specified (in addition to on the top card element) to
-  // ensure the filter 'tab' on the gallery drawer is correctly included on the
-  // non-scrolling part of the gallery.
-  max-height: var(--frigate-card-max-height);
+  // The gallery will grow indefinitely in the `unconstrained` aspect ratio
+  // modes, the surround height needs to be limited to something reasonable in
+  // order for the media filter to still display somewhere the user can
+  // easily/continually access.
+  max-height: 100dvh;
 }


Test patch:
diff --git a/tests/card-controller/actions/actions/microphone-disconnect.test.ts b/tests/card-controller/actions/actions/microphone-disconnect.test.ts
new file mode 100644
index 00000000..fe0d20e1
--- /dev/null
+++ b/tests/card-controller/actions/actions/microphone-disconnect.test.ts
@@ -0,0 +1,18 @@
+import { expect, it } from 'vitest';
+import { MicrophoneDisconnectAction } from '../../../../src/card-controller/actions/actions/microphone-disconnect';
+import { createCardAPI } from '../../../test-utils';
+
+it('should handle microphone_disconnect action', async () => {
+  const api = createCardAPI();
+  const action = new MicrophoneDisconnectAction(
+    {},
+    {
+      action: 'fire-dom-event',
+      frigate_card_action: 'microphone_disconnect',
+    },
+  );
+
+  await action.execute(api);
+
+  expect(api.getMicrophoneManager().disconnect).toBeCalled();
+});
diff --git a/tests/card-controller/actions/factory.test.ts b/tests/card-controller/actions/factory.test.ts
index 7352cd05..9b2cc022 100644
--- a/tests/card-controller/actions/factory.test.ts
+++ b/tests/card-controller/actions/factory.test.ts
@@ -10,6 +10,7 @@ import { GenericAction } from '../../../src/card-controller/actions/actions/gene
 import { LogAction } from '../../../src/card-controller/actions/actions/log';
 import { MediaPlayerAction } from '../../../src/card-controller/actions/actions/media-player';
 import { MenuToggleAction } from '../../../src/card-controller/actions/actions/menu-toggle';
+import { MicrophoneDisconnectAction } from '../../../src/card-controller/actions/actions/microphone-disconnect';
 import { MicrophoneMuteAction } from '../../../src/card-controller/actions/actions/microphone-mute';
 import { MicrophoneUnmuteAction } from '../../../src/card-controller/actions/actions/microphone-unmute';
 import { MuteAction } from '../../../src/card-controller/actions/actions/mute';
@@ -103,6 +104,10 @@ describe('ActionFactory', () => {
         MediaPlayerAction,
       ],
       [{ frigate_card_action: 'menu_toggle' as const }, MenuToggleAction],
+      [
+        { frigate_card_action: 'microphone_disconnect' as const },
+        MicrophoneDisconnectAction,
+      ],
       [{ frigate_card_action: 'microphone_mute' as const }, MicrophoneMuteAction],
       [{ frigate_card_action: 'microphone_unmute' as const }, MicrophoneUnmuteAction],
       [{ frigate_card_action: 'mute' as const }, MuteAction],
diff --git a/tests/card-controller/style-manager.test.ts b/tests/card-controller/style-manager.test.ts
index c2920b70..f8323058 100644
--- a/tests/card-controller/style-manager.test.ts
+++ b/tests/card-controller/style-manager.test.ts
@@ -209,8 +209,7 @@ describe('StyleManager', () => {
       vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
         createConfig({
           dimensions: {
-            max_height: '800px',
-            min_height: '400px',
+            height: '800px',
           },
         }),
       );
@@ -218,8 +217,7 @@ describe('StyleManager', () => {
 
       manager.setMinMaxHeight();
 
-      expect(element.style.getPropertyValue('--frigate-card-min-height')).toBe('400px');
-      expect(element.style.getPropertyValue('--frigate-card-max-height')).toBe('800px');
+      expect(element.style.getPropertyValue('--frigate-card-height')).toBe('800px');
     });
   });
 
diff --git a/tests/config/management.test.ts b/tests/config/management.test.ts
index e819b80b..1c4bd532 100644
--- a/tests/config/management.test.ts
+++ b/tests/config/management.test.ts
@@ -1,4 +1,7 @@
-import { CallServiceActionConfig } from '@dermotduffy/custom-card-helpers';
+import {
+  CallServiceActionConfig,
+  PerformActionActionConfig,
+} from '@dermotduffy/custom-card-helpers';
 import { describe, expect, it } from 'vitest';
 import {
   copyConfig,
@@ -21,7 +24,6 @@ import {
 import { PTZControlAction } from '../../src/config/ptz';
 import {
   Actions,
-  PerformActionActionConfig,
   RawFrigateCardConfig,
   frigateCardConfigSchema,
 } from '../../src/config/types';
@@ -3313,7 +3315,7 @@ describe('should handle version specific upgrades', () => {
       });
     });
 
-    it('call-service -> perform-action', () => {
+    it('rename call-service -> perform-action', () => {
       const config = {
         type: 'custom:frigate-card',
         cameras: [{ camera_entity: 'camera.office' }],
@@ -3367,5 +3369,41 @@ describe('should handle version specific upgrades', () => {
       });
       postUpgradeChecks(config);
     });
+
+    it('rename dimensions.max_height -> dimensions.height', () => {
+      const config = {
+        type: 'custom:frigate-card',
+        cameras: [{ camera_entity: 'camera.office' }],
+        dimensions: {
+          max_height: '500px',
+        },
+      };
+      expect(upgradeConfig(config)).toBeTruthy();
+      expect(config).toEqual({
+        type: 'custom:frigate-card',
+        cameras: [{ camera_entity: 'camera.office' }],
+        dimensions: {
+          height: '500px',
+        },
+      });
+      postUpgradeChecks(config);
+    });
+
+    it('delete dimensions.min_height', () => {
+      const config = {
+        type: 'custom:frigate-card',
+        cameras: [{ camera_entity: 'camera.office' }],
+        dimensions: {
+          min_height: '100px',
+        },
+      };
+      expect(upgradeConfig(config)).toBeTruthy();
+      expect(config).toEqual({
+        type: 'custom:frigate-card',
+        cameras: [{ camera_entity: 'camera.office' }],
+        dimensions: {},
+      });
+      postUpgradeChecks(config);
+    });
   });
 });
diff --git a/tests/config/types.test.ts b/tests/config/types.test.ts
index 6d7dadd2..23db7608 100644
--- a/tests/config/types.test.ts
+++ b/tests/config/types.test.ts
@@ -55,8 +55,7 @@ describe('config defaults', () => {
       dimensions: {
         aspect_ratio: [16, 9],
         aspect_ratio_mode: 'dynamic',
-        max_height: '100vh',
-        min_height: '100px',
+        height: 'auto',
       },
       image: {
         mode: 'auto',