refactor: Replace Rollup with Vite (#2656)

This is a high risk change: every byte the card ships is emitted by a
different bundler, minified by a different minifier, and every
stylesheet is compiled by a different sass. The intent is that the
card's behaviour is unchanged.

**Significant development win**: Build time drops from 24s to 1.1s 🎉 

Also adds a test suite ('dist') that runs against the built bundle.
This commit is contained in:
Dermot Duffy
2026-08-04 15:00:13 -07:00
committed by GitHub
parent 06bcfd58ba
commit 80ec92e3b2
105 changed files with 1273 additions and 1719 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
"Bash(yarn prettier *)", "Bash(yarn prettier *)",
"Bash(npx tsc --noEmit *)", "Bash(npx tsc --noEmit *)",
"Bash(npx eslint *)", "Bash(npx eslint *)",
"Bash(npx rollup -c *)", "Bash(npx vite build *)",
"Read(~/.claude/projects/**)" "Read(~/.claude/projects/**)"
] ]
} }
+4 -1
View File
@@ -11,10 +11,13 @@
"workspaceFolder": "${localWorkspaceFolder}", "workspaceFolder": "${localWorkspaceFolder}",
"initializeCommand": [".devcontainer/scripts/devcontainer_initialize.sh"], "initializeCommand": [".devcontainer/scripts/devcontainer_initialize.sh"],
"postCreateCommand": ["yarn", "install"], "postCreateCommand": ["yarn", "install"],
"postAttachCommand": {
"preview": "yarn build && yarn preview"
},
"forwardPorts": [10001, "homeassistant:8123", "frigate:5000"], "forwardPorts": [10001, "homeassistant:8123", "frigate:5000"],
"portsAttributes": { "portsAttributes": {
"10001": { "10001": {
"label": "Rollup", "label": "Vite",
"onAutoForward": "silent" "onAutoForward": "silent"
}, },
"homeassistant:8123": { "homeassistant:8123": {
+80 -13
View File
@@ -12,8 +12,8 @@ on:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
check: check-code:
name: Check name: Check / Code
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
@@ -37,7 +37,25 @@ jobs:
- name: Check formatting - name: Check formatting
run: yarn run format-check run: yarn run format-check
test: # Validates the repository's own metadata, which needs neither the card built
# nor Node installed.
check-hacs:
name: Check / HACS
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: HACS validation
uses: 'hacs/action@22.5.0'
with:
category: 'plugin'
# Don't attempt to load into HACS (as it loads the release, not the
# build).
ignore: 'hacs'
test-unit:
name: Test / Unit name: Test / Unit
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -53,7 +71,7 @@ jobs:
- name: Test & Coverage - name: Test & Coverage
run: yarn run coverage run: yarn run coverage
browser-test: test-browser:
name: Test / Browser / ${{ matrix.name }} name: Test / Browser / ${{ matrix.name }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -107,6 +125,64 @@ jobs:
path: .vitest/ path: .vitest/
if-no-files-found: ignore if-no-files-found: ignore
test-dist:
name: Test / Dist / ${{ matrix.name }}
runs-on: ubuntu-latest
# Use Playwright's own image to avoid having to (slowly) install browsers
# and dependencies. The tag has to name the `playwright` version in
# package.json .
container:
image: mcr.microsoft.com/playwright:v1.62.0-noble
# As the image's own user rather than root, which Firefox refuses to run
# as when the home directory belongs to somebody else.
#
# See https://playwright.dev/docs/ci#via-containers .
options: --user 1001
strategy:
# One browser failing does not invalidate the others.
fail-fast: false
matrix:
# `name` is only how the browser is written for a human: it titles the
# job, while `browser` is the name Playwright knows it by.
include:
- browser: chromium
name: Chromium
- browser: firefox
name: Firefox
- browser: webkit
name: WebKit
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup Node and Yarn
uses: volta-cli/action@v5
- name: Install dependencies
run: yarn install --immutable
# These tests read a build rather than making one.
- name: Build
run: yarn run build
- name: Test the built card
run: yarn run test:dist
env:
VITEST_BROWSER: ${{ matrix.browser }}
- name: Upload failures
if: failure()
uses: actions/upload-artifact@v6
with:
name: dist-test-failures-${{ matrix.browser }}
path: .vitest/
if-no-files-found: ignore
build: build:
name: Build name: Build
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -123,15 +199,6 @@ jobs:
- name: Build - name: Build
run: yarn run build run: yarn run build
- name: HACS build validation
uses: 'hacs/action@22.5.0'
with:
category: 'plugin'
# Don't attempt to load into HACS (as it loads the release, not the
# build).
ignore: 'hacs'
- name: Upload javascript - name: Upload javascript
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v7
with: with:
-2
View File
@@ -30,7 +30,6 @@ jobs:
outputs: outputs:
new-release-published: ${{ steps.get-next-version.outputs.new-release-published }} new-release-published: ${{ steps.get-next-version.outputs.new-release-published }}
new-release-version: ${{ steps.get-next-version.outputs.new-release-version }} new-release-version: ${{ steps.get-next-version.outputs.new-release-version }}
new-release-git-tag: ${{ steps.get-next-version.outputs.new-release-git-tag }}
release: release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -46,7 +45,6 @@ jobs:
- run: yarn run build - run: yarn run build
env: env:
RELEASE_VERSION: ${{ needs.get-next-version.outputs.new-release-version }} RELEASE_VERSION: ${{ needs.get-next-version.outputs.new-release-version }}
RELEASE_TAG: ${{ needs.get-next-version.outputs.new-release-git-tag }}
- uses: thedoctor0/zip-release@0.7.6 - uses: thedoctor0/zip-release@0.7.6
with: with:
type: zip type: zip
+1 -1
View File
@@ -7,7 +7,7 @@
"name": "Launch Chrome against Home Assistant", "name": "Launch Chrome against Home Assistant",
"url": "http://localhost:8123", "url": "http://localhost:8123",
"webRoot": "${workspaceFolder}/dist", "webRoot": "${workspaceFolder}/dist",
"preLaunchTask": "Rollup", "preLaunchTask": "Vite",
"resolveSourceMapLocations": ["http://localhost:1000/**"] "resolveSourceMapLocations": ["http://localhost:1000/**"]
} }
] ]
+3 -3
View File
@@ -2,7 +2,7 @@
"version": "2.0.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"label": "Rollup", "label": "Vite",
"type": "shell", "type": "shell",
"command": "yarn", "command": "yarn",
"args": ["start"], "args": ["start"],
@@ -17,8 +17,8 @@
], ],
"background": { "background": {
"activeOnStart": true, "activeOnStart": true,
"beginsPattern": "^bundles", "beginsPattern": "^build started",
"endsPattern": "^created" "endsPattern": "^built in"
} }
}, },
"isBackground": true, "isBackground": true,
-7
View File
@@ -1,7 +0,0 @@
# Patches
## `sass`
`sass` is patched to avoid printing out a noisy deprecation notice on every
build. `sass` is imported by `rollup-plugin-styler`, in a way that triggers this
message. The patch simply prevents this console spam.
@@ -1,13 +0,0 @@
diff --git a/sass.node.mjs b/sass.node.mjs
index f59a3d8987162a3cbc9787c34f67186fb0f09186..b154f46118ccc03989b9a1c11309954c85515539 100644
--- a/sass.node.mjs
+++ b/sass.node.mjs
@@ -40,7 +40,7 @@ export const NodePackageImporter = cjs.NodePackageImporter;
export const deprecations = cjs.deprecations;
export const Version = cjs.Version;
-let printedDefaultExportDeprecation = false;
+let printedDefaultExportDeprecation = true;
function defaultExportDeprecation() {
if (printedDefaultExportDeprecation) return;
printedDefaultExportDeprecation = true;
+1 -1
View File
@@ -2,7 +2,7 @@
## Stack & Workflow ## Stack & Workflow
TypeScript (strict), Lit v3, Zod, Vitest, Rollup, Yarn. TypeScript (strict), Lit v3, Zod, Vitest, Vite, Yarn.
Commands: `yarn install`, `yarn run build`, `yarn run test`, `yarn run coverage`, `yarn run format`, `yarn run lint`, `yarn run prune`, `yarn run docs-check-links`. Commands: `yarn install`, `yarn run build`, `yarn run test`, `yarn run coverage`, `yarn run format`, `yarn run lint`, `yarn run prune`, `yarn run docs-check-links`.
+10
View File
@@ -24,6 +24,16 @@ Resultant build entry file will be in `dist/advanced-camera-card.js`. This could
installed via the [manual installation installed via the [manual installation
instructions](advanced-installation.md?id=manual-installation). instructions](advanced-installation.md?id=manual-installation).
To rebuild as the source changes:
```sh
$ yarn start
```
This writes to `dist/` just like a normal build so that Home Assistant reading
the card from a path on disk picks each rebuild up. To have Home Assistant read
from a URL instead, use `yarn preview` which serves `dist/` on port 10001.
## Releasing ## Releasing
### Release Philosophy ### Release Philosophy
+5 -14
View File
@@ -55,13 +55,6 @@
"@eslint/eslintrc": "^3.3.6", "@eslint/eslintrc": "^3.3.6",
"@eslint/js": "^9.24.0", "@eslint/js": "^9.24.0",
"@ianvs/prettier-plugin-sort-imports": "^4.7.1", "@ianvs/prettier-plugin-sort-imports": "^4.7.1",
"@rollup/plugin-commonjs": "^26.0.1",
"@rollup/plugin-image": "^3.0.3",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.7",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^11.1.6",
"@semantic-release/github": "^10.3.3", "@semantic-release/github": "^10.3.3",
"@types/js-yaml": "^4", "@types/js-yaml": "^4",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
@@ -80,15 +73,13 @@
"msw": "^2.15.0", "msw": "^2.15.0",
"playwright": "1.62.0", "playwright": "1.62.0",
"prettier": "^3.3.2", "prettier": "^3.3.2",
"rollup": "^3.29.4",
"rollup-plugin-serve": "^1.1.1",
"rollup-plugin-styler": "^1.8.0",
"rollup-plugin-visualizer": "^5.12.0", "rollup-plugin-visualizer": "^5.12.0",
"sass": "patch:sass@npm%3A1.77.4#~/.yarn/patches/sass-npm-1.77.4-13b6910aea.patch", "sass-embedded": "^1.100.0",
"semantic-release": "^24.1.1", "semantic-release": "^24.1.1",
"semantic-release-export-data": "^1.1.0", "semantic-release-export-data": "^1.1.0",
"type-fest": "^4.41.0", "type-fest": "^4.41.0",
"typescript": "^5.8.3", "typescript": "^5.8.3",
"vite": "^8.1.5",
"vitest": "^4.1.10", "vitest": "^4.1.10",
"vitest-mock-extended": "^5.1.0" "vitest-mock-extended": "^5.1.0"
}, },
@@ -177,9 +168,10 @@
] ]
}, },
"scripts": { "scripts": {
"start": "rollup -c --watch", "start": "vite build --watch --mode development",
"preview": "vite preview",
"deployment-update": "./scripts/deployment-update-symlink.sh", "deployment-update": "./scripts/deployment-update-symlink.sh",
"build": "yarn run lint && yarn run rollup", "build": "vite build",
"docs": "docsify serve ./docs", "docs": "docsify serve ./docs",
"docs-check-links": "docker run --init --rm -v \"$(pwd):/input\" -w /input lycheeverse/lychee --config lychee.toml \"./docs/\"", "docs-check-links": "docker run --init --rm -v \"$(pwd):/input\" -w /input lycheeverse/lychee --config lychee.toml \"./docs/\"",
"docs-update-images": "./scripts/docs-update-images.sh", "docs-update-images": "./scripts/docs-update-images.sh",
@@ -189,7 +181,6 @@
"typecheck": "tsc --noEmit -p tsconfig.json", "typecheck": "tsc --noEmit -p tsconfig.json",
"format": "prettier --write .", "format": "prettier --write .",
"format-check": "prettier --check .", "format-check": "prettier --check .",
"rollup": "rollup -c",
"prune": "knip", "prune": "knip",
"test": "vitest run", "test": "vitest run",
"test:browser": "vitest run --config vitest.browser.config.ts", "test:browser": "vitest run --config vitest.browser.config.ts",
-141
View File
@@ -1,141 +0,0 @@
import commonjs from '@rollup/plugin-commonjs';
import image from '@rollup/plugin-image';
import json from '@rollup/plugin-json';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import terser from '@rollup/plugin-terser';
import typescript from '@rollup/plugin-typescript';
import serve from 'rollup-plugin-serve';
import styles from 'rollup-plugin-styler';
import { visualizer } from 'rollup-plugin-visualizer';
import { getBuildDefines } from './scripts/build-defines.js';
import { cleanDist } from './scripts/clean-dist-plugin.js';
import { svgPath } from './scripts/svg-path-plugin.js';
const watch = process.env.ROLLUP_WATCH === 'true' || process.env.ROLLUP_WATCH === '1';
const dev = watch || process.env.DEV === 'true' || process.env.DEV === '1';
// Opt-in dev server: `rollup -c --watch --environment SERVE`. Off by default
// for deployments that read output from the filesystem.
const serveEnabled = process.env.SERVE === 'true' || process.env.SERVE === '1';
/**
* @type {import('rollup-plugin-serve').ServeOptions}
*/
const serveopts = {
contentBase: ['./dist'],
host: '0.0.0.0',
port: 10001,
allowCrossOrigin: true,
headers: {
'Access-Control-Allow-Origin': '*',
},
};
/**
* @type {import('rollup').RollupOptions['plugins']}
*/
const plugins = [
cleanDist(),
styles({
modules: false,
// Behavior of inject mode, without actually injecting style
// into <head>.
mode: ['inject', () => undefined],
sass: {
includePaths: ['./node_modules/'],
},
}),
svgPath(),
image({ exclude: '**/*.svg' }),
nodeResolve({
browser: true,
}),
commonjs({
include: 'node_modules/**',
sourceMap: false,
}),
typescript({
sourceMap: dev,
inlineSources: dev,
exclude: ['dist/**', 'tests/**/*.test.ts'],
}),
json(),
replace({
preventAssignment: true,
values: {
'process.env.NODE_ENV': JSON.stringify(dev ? 'development' : 'production'),
...getBuildDefines({ dev, releaseVersion: process.env.RELEASE_VERSION }),
},
}),
serveEnabled && serve(serveopts),
!dev && terser(),
visualizer({
filename: 'visualizations/treemap.html',
template: 'treemap',
}),
];
const outputEntryTemplate = {
entryFileNames: 'advanced-camera-card.js',
dir: 'dist',
chunkFileNames: (chunk) => {
// Add "lang-" to the front of the language chunk names for readability.
if (
chunk.facadeModuleId &&
chunk.facadeModuleId.match(/localize\/languages\/.*\.json/)
) {
return 'lang-[name]-[hash].js';
}
if (chunk.facadeModuleId && chunk.facadeModuleId.match(/ha-nunjucks/)) {
return 'templates-[hash].js';
}
return '[name]-[hash].js';
},
format: 'es',
sourcemap: dev,
};
const CIRCULAR_DEPENDENCY_IGNORE_REGEXP = /(ha-nunjucks|ts-py-datetime|zod\/v4)/;
/**
* @type {import('rollup').RollupOptions}
*/
const config = {
input: 'src/card.ts',
// Specifically want a facade created as HACS will attach a hacstag
// queryparameter to the resource. Without a facade when chunks re-import the
// card chunk, they'll refer to a 'different' copy of the card chunk without
// the hacstag, causing a re-download of the same content and functionality
// problems.
preserveEntrySignatures: 'strict',
output: [
outputEntryTemplate,
// Continue to include the old file name for backwards compatibility.
{
...outputEntryTemplate,
entryFileNames: 'frigate-hass-card.js',
},
],
plugins: plugins,
// These files use `this` at the toplevel, which causes rollup warning spam on
// build: `this` has been rewritten to `undefined`.
moduleContext: {
'./node_modules/@formatjs/intl-utils/lib/src/diff.js': 'window',
'./node_modules/@formatjs/intl-utils/lib/src/resolve-locale.js': 'window',
},
// Ignore circular dependencies from underlying libraries.
onwarn: (warning, defaultHandler) => {
if (
warning.code === 'CIRCULAR_DEPENDENCY' &&
warning.ids.some((id) => id.match(CIRCULAR_DEPENDENCY_IGNORE_REGEXP))
) {
return;
}
defaultHandler(warning);
},
};
export default config;
+31 -27
View File
@@ -1,32 +1,36 @@
import { existsSync, readdirSync, rmSync } from 'node:fs'; import { readdirSync, rmSync } from 'node:fs';
import path from 'node:path';
/** /**
* Rollup plugin: deletes prior build artifacts from `dist/` (which otherwise * Vite plugin: removes build artifacts an earlier build left behind, which
* accumulate stale hashed chunks that can be served in place of fresh output). * otherwise accumulate indefinitely as the hashed names change.
* Deletes only top-level build artifacts by extension (no recursion), so
* anything unexpected in `dist/` survives. Cleans once per process: watch mode
* cleans at startup, not on every incremental rebuild.
* *
* @type {() => import('rollup').Plugin} * Runs once the new output is on disk, and keeps whatever this build just
* wrote, rather than emptying the directory beforehand. This ensures the card
* is never briefly missing from a directory Home Assistant is potentially
* serving out of. Only the build's own kind of file is removed, by extension
* and without recursing, so anything else there survives.
*
* @type {() => import('vite').Plugin}
*/ */
export const cleanDist = () => { export const cleanDist = () => ({
let cleaned = false; name: 'clean-dist',
return {
name: 'clean-dist', writeBundle(options, bundle) {
buildStart() { if (!options.dir) {
if (cleaned) { return;
return; }
const written = new Set(Object.keys(bundle));
for (const entry of readdirSync(options.dir, { withFileTypes: true })) {
if (
entry.isFile() &&
/\.js(\.map)?$/.test(entry.name) &&
!written.has(entry.name)
) {
rmSync(path.resolve(options.dir, entry.name));
} }
cleaned = true; }
const dist = new URL('../dist/', import.meta.url); },
if (!existsSync(dist)) { });
return;
}
for (const entry of readdirSync(dist, { withFileTypes: true })) {
if (entry.isFile() && /\.js(\.map)?$/.test(entry.name)) {
rmSync(new URL(entry.name, dist));
}
}
},
};
};
+57
View File
@@ -0,0 +1,57 @@
/**
* Emits the files a dashboard resource can name, each a re-export of the hashed
* chunk holding the actual card.
*
* HACS registers the card as a dashboard resource with a `hacstag` query
* parameter on the URL, and the browser treats a different URL as a different
* file. Were a chunk to import the untagged name, the card would be fetched and
* run a second time, and defining its elements twice will throw an error.
* Keeping the card itself in a hashed chunk that nothing outside can name is
* what prevents that, and the check below is what keeps it true.
*
* @type {(options: { publicFileNames: string[] }) => import('vite').Plugin}
*/
export const facadeEntry = ({ publicFileNames }) => ({
name: 'facade-entry',
generateBundle(_options, bundle) {
const entries = Object.values(bundle).filter(
(item) => item.type === 'chunk' && item.isEntry,
);
if (entries.length !== 1) {
throw new Error(`Expected exactly one entry chunk, found ${entries.length}`);
}
const [entry] = entries;
// A public name already in the bundle means the card was emitted under it
// rather than into a hashed chunk, which is the arrangement this plugin
// exists to prevent.
const alreadyEmitted = publicFileNames.filter((name) => name in bundle);
if (alreadyEmitted.length) {
throw new Error(
`The build should have emitted these under hashed names: ${alreadyEmitted.join(', ')}`,
);
}
const offenders = Object.values(bundle).flatMap((item) =>
item.type === 'chunk'
? [...item.imports, ...item.dynamicImports]
.filter((imported) => publicFileNames.includes(imported))
.map((imported) => `${item.fileName} -> ${imported}`)
: [],
);
if (offenders.length) {
throw new Error(
`Chunks should not import a public entry point: ${offenders.join(', ')}`,
);
}
for (const fileName of publicFileNames) {
this.emitFile({
type: 'asset',
fileName,
source: `export * from './${entry.fileName}';\n`,
});
}
},
});
+13
View File
@@ -0,0 +1,13 @@
/**
* The files a Home Assistant dashboard resource may list.
*
* Everything else the build emits is hashed, so this is the one name that has to
* stay put across releases.
*/
export const PUBLIC_ENTRY = 'advanced-camera-card.js';
/**
* Both names a dashboard resource can name: the current one, and the one the
* card shipped under previously, kept so an existing resource keeps working.
*/
export const PUBLIC_ENTRIES = [PUBLIC_ENTRY, 'frigate-hass-card.js'];
-26
View File
@@ -1,26 +0,0 @@
/**
* Vite plugin: `import style from './foo.scss'` gives the compiled CSS as a
* string, which is what the source tree passes to Lit's `unsafeCSS`. Left
* alone, Vite adds those styles to the page and the import returns nothing
* useful. Appending Vite's own `?inline` asks for the text instead, compiled by
* the same sass the build uses.
*
* The build's `rollup-plugin-styler` cannot be used here: Vite always handles
* `.scss` itself, so it would take that plugin's JavaScript output and hand it
* to sass, which rejects it.
*
* @type {() => import('vite').Plugin}
*/
export const scssString = () => ({
name: 'scss-string',
// Vite: run before its builtin CSS handling.
enforce: 'pre',
async resolveId(source, importer, options) {
if (!source.endsWith('.scss')) {
return null;
}
return await this.resolve(`${source}?inline`, importer, options);
},
});
+5 -5
View File
@@ -1,16 +1,16 @@
import { readFileSync } from 'node:fs'; import { readFileSync } from 'node:fs';
/** /**
* Rollup/Vite plugin: importing an SVG yields `{ path, viewBox }` extracted at * Vite plugin: importing an SVG yields `{ path, viewBox }` extracted at build
* build time, the shape a Home Assistant custom iconset serves. The SVG must * time, the shape a Home Assistant custom iconset serves. The SVG must be a
* be a single-path icon. * single-path icon.
* *
* @type {() => import('rollup').Plugin} * @type {() => import('vite').Plugin}
*/ */
export const svgPath = () => ({ export const svgPath = () => ({
name: 'svg-path', name: 'svg-path',
// Vite: run before its builtin asset handling. // Run before Vite's builtin asset handling.
enforce: 'pre', enforce: 'pre',
load(id) { load(id) {
+3 -1
View File
@@ -8,6 +8,9 @@ import type { HomeAssistant } from '../ha/types';
import { RecordingSegmentsCache } from './cache'; import { RecordingSegmentsCache } from './cache';
import type { CameraManagerEngine } from './engine'; import type { CameraManagerEngine } from './engine';
import { CameraNoEntityError } from './error'; import { CameraNoEntityError } from './error';
// Every other engine subclasses GenericCameraManagerEngine so it is loaded no
// matter what -- no lazy loading is useful.
import { GenericCameraManagerEngine } from './generic/engine-generic';
import { CameraManagerRequestCache, Engine, type CameraEventCallback } from './types'; import { CameraManagerRequestCache, Engine, type CameraEventCallback } from './types';
import { getCameraEntityFromConfig } from './utils/camera-entity-from-config'; import { getCameraEntityFromConfig } from './utils/camera-entity-from-config';
@@ -36,7 +39,6 @@ export class CameraManagerEngineFactory {
let cameraManagerEngine: CameraManagerEngine; let cameraManagerEngine: CameraManagerEngine;
switch (engine) { switch (engine) {
case Engine.Generic: case Engine.Generic:
const { GenericCameraManagerEngine } = await import('./generic/engine-generic');
cameraManagerEngine = new GenericCameraManagerEngine( cameraManagerEngine = new GenericCameraManagerEngine(
options.hassManager, options.hassManager,
this._entityRegistryManager, this._entityRegistryManager,
+1 -1
View File
@@ -62,7 +62,7 @@ import { REPO_URL } from './const.js';
import { registerCustomIconset } from './ha/custom-icons.js'; import { registerCustomIconset } from './ha/custom-icons.js';
import type { HomeAssistant, LovelaceCardEditor } from './ha/types.js'; import type { HomeAssistant, LovelaceCardEditor } from './ha/types.js';
import { localize } from './localize/localize.js'; import { localize } from './localize/localize.js';
import cardStyle from './scss/card.scss'; import cardStyle from './scss/card.scss?inline';
import type { MediaLoadedInfoEventDetail } from './types.js'; import type { MediaLoadedInfoEventDetail } from './types.js';
import { hasAction } from './utils/action.js'; import { hasAction } from './utils/action.js';
import { getReleaseVersion } from './utils/build-info.js'; import { getReleaseVersion } from './utils/build-info.js';
+1 -1
View File
@@ -13,7 +13,7 @@ import { dispatchActionExecutionRequest } from '../card-controller/actions/utils
import type { MicrophoneState } from '../card-controller/types.js'; import type { MicrophoneState } from '../card-controller/types.js';
import type { ActionConfig } from '../config/schema/actions/types.js'; import type { ActionConfig } from '../config/schema/actions/types.js';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import callControlsStyle from '../scss/call-controls.scss'; import callControlsStyle from '../scss/call-controls.scss?inline';
import { import {
createCallAnswerAction, createCallAnswerAction,
createCallEndAction, createCallEndAction,
+1 -1
View File
@@ -10,7 +10,7 @@ import { customElement, property } from 'lit/decorators.js';
import { createRef, ref, type Ref } from 'lit/directives/ref.js'; import { createRef, ref, type Ref } from 'lit/directives/ref.js';
import type { TransitionEffect } from '../config/schema/common/transition-effect'; import type { TransitionEffect } from '../config/schema/common/transition-effect';
import carouselStyle from '../scss/carousel.scss'; import carouselStyle from '../scss/carousel.scss?inline';
import { import {
CarouselController, CarouselController,
type CarouselDirection, type CarouselDirection,
+1 -1
View File
@@ -9,7 +9,7 @@ import { customElement, property } from 'lit/decorators.js';
import { createRef, ref, type Ref } from 'lit/directives/ref.js'; import { createRef, ref, type Ref } from 'lit/directives/ref.js';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import datePickerStyle from '../scss/date-picker.scss'; import datePickerStyle from '../scss/date-picker.scss?inline';
import { stopEventFromActivatingCardWideActions } from '../utils/action'; import { stopEventFromActivatingCardWideActions } from '../utils/action';
import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event'; import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event';
+1 -1
View File
@@ -13,7 +13,7 @@ import type { RawAdvancedCameraCardConfig } from '../config/types';
import type { DeviceRegistryManager } from '../ha/registry/device'; import type { DeviceRegistryManager } from '../ha/registry/device';
import type { HomeAssistant } from '../ha/types'; import type { HomeAssistant } from '../ha/types';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import basicBlockStyle from '../scss/basic-block.scss'; import basicBlockStyle from '../scss/basic-block.scss?inline';
import { getDiagnostics } from '../utils/diagnostics'; import { getDiagnostics } from '../utils/diagnostics';
import { renderNotificationBlockFromText } from './notification/block'; import { renderNotificationBlockFromText } from './notification/block';
+2 -2
View File
@@ -13,8 +13,8 @@ import 'side-drawer';
import type { SideDrawer } from 'side-drawer'; import type { SideDrawer } from 'side-drawer';
import drawerInjectStyle from '../scss/drawer-inject.scss'; import drawerInjectStyle from '../scss/drawer-inject.scss?inline';
import drawerStyle from '../scss/drawer.scss'; import drawerStyle from '../scss/drawer.scss?inline';
import { stopEventFromActivatingCardWideActions } from '../utils/action.js'; import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
import { import {
contentsChanged, contentsChanged,
+1 -1
View File
@@ -20,7 +20,7 @@ import { CONF_CAMERAS } from '../../config/const';
import type { EditorMode } from '../../config/schema/editor'; import type { EditorMode } from '../../config/schema/editor';
import type { HomeAssistant } from '../../ha/types'; import type { HomeAssistant } from '../../ha/types';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import editorExpanderBodyStyle from '../../scss/editor-expander-body.scss'; import editorExpanderBodyStyle from '../../scss/editor-expander-body.scss?inline';
import { renderDocumentation } from './doc-link'; import { renderDocumentation } from './doc-link';
import { renderForms } from './form'; import { renderForms } from './form';
+1 -1
View File
@@ -10,7 +10,7 @@ import { customElement, property } from 'lit/decorators.js';
import { getDocURL } from '../../components-lib/editor/doc-links'; import { getDocURL } from '../../components-lib/editor/doc-links';
import type { ConfigPath } from '../../components-lib/editor/types'; import type { ConfigPath } from '../../components-lib/editor/types';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import editorDocLinkStyle from '../../scss/editor-doc-link.scss'; import editorDocLinkStyle from '../../scss/editor-doc-link.scss?inline';
// A self-styled documentation link row. Carries its own styles so it renders // A self-styled documentation link row. Carries its own styles so it renders
// correctly when passed into the shadow DOM of Home Assistant elements (e.g. as // correctly when passed into the shadow DOM of Home Assistant elements (e.g. as
+1 -1
View File
@@ -15,7 +15,7 @@ import type { ConfigPath } from '../../components-lib/editor/types';
import { CONF_FOLDERS } from '../../config/const'; import { CONF_FOLDERS } from '../../config/const';
import type { HomeAssistant } from '../../ha/types'; import type { HomeAssistant } from '../../ha/types';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import editorExpanderBodyStyle from '../../scss/editor-expander-body.scss'; import editorExpanderBodyStyle from '../../scss/editor-expander-body.scss?inline';
import { renderDocumentation } from './doc-link'; import { renderDocumentation } from './doc-link';
import { renderForms } from './form'; import { renderForms } from './form';
+1 -1
View File
@@ -14,7 +14,7 @@ import { CONF_VIEW_KEYBOARD_SHORTCUTS } from '../../config/const.js';
import type { KeyboardShortcut } from '../../config/schema/view.js'; import type { KeyboardShortcut } from '../../config/schema/view.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import { localize } from '../../localize/localize.js'; import { localize } from '../../localize/localize.js';
import editorKeyboardShortcutsStyle from '../../scss/editor-keyboard-shortcuts.scss'; import editorKeyboardShortcutsStyle from '../../scss/editor-keyboard-shortcuts.scss?inline';
import { renderDocumentation } from './doc-link.js'; import { renderDocumentation } from './doc-link.js';
import { renderForms } from './form.js'; import { renderForms } from './form.js';
+1 -1
View File
@@ -9,7 +9,7 @@ import {
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import editorListStyle from '../../scss/editor-list.scss'; import editorListStyle from '../../scss/editor-list.scss?inline';
import { fireAdvancedCameraCardEvent } from '../../utils/fire-advanced-camera-card-event'; import { fireAdvancedCameraCardEvent } from '../../utils/fire-advanced-camera-card-event';
import './../icon'; import './../icon';
+1 -1
View File
@@ -9,7 +9,7 @@ import {
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import editorPageStyle from '../../scss/editor-page.scss'; import editorPageStyle from '../../scss/editor-page.scss?inline';
import { fireAdvancedCameraCardEvent } from '../../utils/fire-advanced-camera-card-event'; import { fireAdvancedCameraCardEvent } from '../../utils/fire-advanced-camera-card-event';
// The editor for one item of a list, shown in place of the list itself: a // The editor for one item of a list, shown in place of the list itself: a
+1 -1
View File
@@ -16,7 +16,7 @@ import type { FormRequest } from '../../components-lib/editor/schema/registry';
import { SectionController } from '../../components-lib/editor/section-controller'; import { SectionController } from '../../components-lib/editor/section-controller';
import type { ConfigPath } from '../../components-lib/editor/types'; import type { ConfigPath } from '../../components-lib/editor/types';
import type { HomeAssistant } from '../../ha/types'; import type { HomeAssistant } from '../../ha/types';
import editorSectionStyle from '../../scss/editor-section.scss'; import editorSectionStyle from '../../scss/editor-section.scss?inline';
import { renderDocumentation } from './doc-link'; import { renderDocumentation } from './doc-link';
import { renderForms } from './form'; import { renderForms } from './form';
+1 -1
View File
@@ -1,7 +1,7 @@
import { LitElement, unsafeCSS, type CSSResultGroup, type PropertyValues } from 'lit'; import { LitElement, unsafeCSS, type CSSResultGroup, type PropertyValues } from 'lit';
import { property } from 'lit/decorators.js'; import { property } from 'lit/decorators.js';
import effectBaseStyle from '../../scss/effect-base.scss'; import effectBaseStyle from '../../scss/effect-base.scss?inline';
import { forceReflow } from '../../utils/basic'; import { forceReflow } from '../../utils/basic';
export abstract class BaseEffectComponent extends LitElement { export abstract class BaseEffectComponent extends LitElement {
+1 -1
View File
@@ -2,7 +2,7 @@ import { html, unsafeCSS, type CSSResultGroup, type TemplateResult } from 'lit';
import { customElement } from 'lit/decorators.js'; import { customElement } from 'lit/decorators.js';
import checkCircleIcon from '../../images/check-circle.svg'; import checkCircleIcon from '../../images/check-circle.svg';
import checkStyle from '../../scss/check.scss'; import checkStyle from '../../scss/check.scss?inline';
import { BaseEffectComponent } from './base'; import { BaseEffectComponent } from './base';
@customElement('advanced-camera-card-effect-check') @customElement('advanced-camera-card-effect-check')
+1 -1
View File
@@ -2,7 +2,7 @@ import { LitElement, unsafeCSS, type PropertyValues } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import type { EffectsManager } from '../../card-controller/effects/effects-manager'; import type { EffectsManager } from '../../card-controller/effects/effects-manager';
import effectsStyle from '../../scss/effects.scss'; import effectsStyle from '../../scss/effects.scss?inline';
@customElement('advanced-camera-card-effects') @customElement('advanced-camera-card-effects')
export class AdvancedCameraCardEffects extends LitElement { export class AdvancedCameraCardEffects extends LitElement {
+1 -1
View File
@@ -8,7 +8,7 @@ import {
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js'; import { repeat } from 'lit/directives/repeat.js';
import fireworkBurstStyle from '../../scss/firework-burst.scss'; import fireworkBurstStyle from '../../scss/firework-burst.scss?inline';
import './firework-particle'; import './firework-particle';
+1 -1
View File
@@ -7,7 +7,7 @@ import {
} from 'lit'; } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import fireworkParticleStyle from '../../scss/firework-particle.scss'; import fireworkParticleStyle from '../../scss/firework-particle.scss?inline';
@customElement('advanced-camera-card-firework-particle') @customElement('advanced-camera-card-firework-particle')
export class AdvancedCameraCardFireworkParticle extends LitElement { export class AdvancedCameraCardFireworkParticle extends LitElement {
+1 -1
View File
@@ -1,7 +1,7 @@
import { html, unsafeCSS, type CSSResultGroup, type TemplateResult } from 'lit'; import { html, unsafeCSS, type CSSResultGroup, type TemplateResult } from 'lit';
import { customElement } from 'lit/decorators.js'; import { customElement } from 'lit/decorators.js';
import ghostStyle from '../../scss/ghost.scss'; import ghostStyle from '../../scss/ghost.scss?inline';
import { BaseEffectComponent } from './base'; import { BaseEffectComponent } from './base';
@customElement('advanced-camera-card-effect-ghost') @customElement('advanced-camera-card-effect-ghost')
+1 -1
View File
@@ -7,7 +7,7 @@ import {
} from 'lit'; } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import heartStyle from '../../scss/heart.scss'; import heartStyle from '../../scss/heart.scss?inline';
@customElement('advanced-camera-card-heart') @customElement('advanced-camera-card-heart')
export class AdvancedCameraCardHeart extends LitElement { export class AdvancedCameraCardHeart extends LitElement {
+1 -1
View File
@@ -7,7 +7,7 @@ import {
} from 'lit'; } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import shamrockStyle from '../../scss/shamrock.scss'; import shamrockStyle from '../../scss/shamrock.scss?inline';
@customElement('advanced-camera-card-shamrock') @customElement('advanced-camera-card-shamrock')
export class AdvancedCameraCardShamrock extends LitElement { export class AdvancedCameraCardShamrock extends LitElement {
+1 -1
View File
@@ -7,7 +7,7 @@ import {
} from 'lit'; } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import snowflakeStyle from '../../scss/snowflake.scss'; import snowflakeStyle from '../../scss/snowflake.scss?inline';
@customElement('advanced-camera-card-snowflake') @customElement('advanced-camera-card-snowflake')
export class AdvancedCameraCardSnowflake extends LitElement { export class AdvancedCameraCardSnowflake extends LitElement {
+1 -1
View File
@@ -32,7 +32,7 @@ import type {
} from '../config/schema/elements/types.js'; } from '../config/schema/elements/types.js';
import type { HomeAssistant } from '../ha/types.js'; import type { HomeAssistant } from '../ha/types.js';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import elementsStyle from '../scss/elements.scss'; import elementsStyle from '../scss/elements.scss?inline';
import { AdvancedCameraCardError } from '../types.js'; import { AdvancedCameraCardError } from '../types.js';
import { errorToConsole } from '../utils/basic.js'; import { errorToConsole } from '../utils/basic.js';
import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js'; import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js';
+1 -1
View File
@@ -16,7 +16,7 @@ import {
import { THUMBNAIL_WIDTH_DEFAULT } from '../../config/schema/common/controls/thumbnails.js'; import { THUMBNAIL_WIDTH_DEFAULT } from '../../config/schema/common/controls/thumbnails.js';
import type { CardWideConfig } from '../../config/schema/types.js'; import type { CardWideConfig } from '../../config/schema/types.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import galleryCoreStyle from '../../scss/gallery-core.scss'; import galleryCoreStyle from '../../scss/gallery-core.scss?inline';
import '../progress-indicator.js'; import '../progress-indicator.js';
+1 -1
View File
@@ -28,7 +28,7 @@ import type { MediaGalleryConfig } from '../../config/schema/media-gallery.js';
import type { CardWideConfig } from '../../config/schema/types.js'; import type { CardWideConfig } from '../../config/schema/types.js';
import { MEDIA_CHUNK_SIZE_DEFAULT } from '../../const.js'; import { MEDIA_CHUNK_SIZE_DEFAULT } from '../../const.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import galleryStyle from '../../scss/gallery.scss'; import galleryStyle from '../../scss/gallery.scss?inline';
import { stopEventFromActivatingCardWideActions } from '../../utils/action.js'; import { stopEventFromActivatingCardWideActions } from '../../utils/action.js';
import { ViewItemClassifier } from '../../view/item-classifier.js'; import { ViewItemClassifier } from '../../view/item-classifier.js';
import type { ViewFolder, ViewItem } from '../../view/item.js'; import type { ViewFolder, ViewItem } from '../../view/item.js';
+1 -1
View File
@@ -10,7 +10,7 @@ import { customElement, property } from 'lit/decorators.js';
import { IconController } from '../components-lib/icon-controller'; import { IconController } from '../components-lib/icon-controller';
import type { InternalIcon } from '../config/schema/common/icon.js'; import type { InternalIcon } from '../config/schema/common/icon.js';
import type { HomeAssistant } from '../ha/types'; import type { HomeAssistant } from '../ha/types';
import iconStyle from '../scss/icon.scss'; import iconStyle from '../scss/icon.scss?inline';
import { contentsChanged } from '../utils/basic.js'; import { contentsChanged } from '../utils/basic.js';
@customElement('advanced-camera-card-icon') @customElement('advanced-camera-card-icon')
+1 -1
View File
@@ -11,7 +11,7 @@ import { createRef, ref, type Ref } from 'lit/directives/ref.js';
import { MediaLoadedInfoSourceController } from '../components-lib/media-loaded-info-source-controller.js'; import { MediaLoadedInfoSourceController } from '../components-lib/media-loaded-info-source-controller.js';
import { ImageMediaPlayerController } from '../components-lib/media-player/image'; import { ImageMediaPlayerController } from '../components-lib/media-player/image';
import imagePlayerStyle from '../scss/image-player.scss'; import imagePlayerStyle from '../scss/image-player.scss?inline';
import type { import type {
MediaPlayer, MediaPlayer,
MediaPlayerController, MediaPlayerController,
+1 -1
View File
@@ -31,7 +31,7 @@ import { isHassDifferent } from '../ha/is-hass-different.js';
import type { HomeAssistant } from '../ha/types.js'; import type { HomeAssistant } from '../ha/types.js';
import defaultImage from '../images/iris-screensaver.jpg'; import defaultImage from '../images/iris-screensaver.jpg';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import imageUpdatingPlayerStyle from '../scss/image-updating-player.scss'; import imageUpdatingPlayerStyle from '../scss/image-updating-player.scss?inline';
import type { MediaPlayer, MediaPlayerController } from '../types.js'; import type { MediaPlayer, MediaPlayerController } from '../types.js';
import { contentsChanged } from '../utils/basic.js'; import { contentsChanged } from '../utils/basic.js';
import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js'; import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js';
+1 -1
View File
@@ -22,7 +22,7 @@ import {
import { type ImageViewConfig, type ImageViewProxyConfig } from '../config/schema/image'; import { type ImageViewConfig, type ImageViewProxyConfig } from '../config/schema/image';
import type { HomeAssistant } from '../ha/types'; import type { HomeAssistant } from '../ha/types';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import imageStyle from '../scss/image.scss'; import imageStyle from '../scss/image.scss?inline';
import type { import type {
MediaPlayer, MediaPlayer,
MediaPlayerController, MediaPlayerController,
+1 -1
View File
@@ -11,7 +11,7 @@ import { customElement, property } from 'lit/decorators.js';
import { KeyAssignerController } from '../components-lib/key-assigner-controller'; import { KeyAssignerController } from '../components-lib/key-assigner-controller';
import type { KeyboardShortcut } from '../config/schema/view'; import type { KeyboardShortcut } from '../config/schema/view';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import keyAssignerStyle from '../scss/key-assigner.scss'; import keyAssignerStyle from '../scss/key-assigner.scss?inline';
import './icon'; import './icon';
+1 -1
View File
@@ -31,7 +31,7 @@ import type { TransitionEffect } from '../../config/schema/common/transition-eff
import type { LiveConfig } from '../../config/schema/live.js'; import type { LiveConfig } from '../../config/schema/live.js';
import { configDefaults, type CardWideConfig } from '../../config/schema/types.js'; import { configDefaults, type CardWideConfig } from '../../config/schema/types.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import liveCarouselStyle from '../../scss/live-carousel.scss'; import liveCarouselStyle from '../../scss/live-carousel.scss?inline';
import { stopEventFromActivatingCardWideActions } from '../../utils/action.js'; import { stopEventFromActivatingCardWideActions } from '../../utils/action.js';
import type { CarouselSelected } from '../../utils/embla/carousel-controller.js'; import type { CarouselSelected } from '../../utils/embla/carousel-controller.js';
import { getTextDirection } from '../../utils/text-direction.js'; import { getTextDirection } from '../../utils/text-direction.js';
+1 -1
View File
@@ -18,7 +18,7 @@ import type { MediaGridSelected } from '../../components-lib/media-grid-controll
import type { LiveConfig } from '../../config/schema/live.js'; import type { LiveConfig } from '../../config/schema/live.js';
import type { CardWideConfig } from '../../config/schema/types.js'; import type { CardWideConfig } from '../../config/schema/types.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import liveGridStyle from '../../scss/live-grid.scss'; import liveGridStyle from '../../scss/live-grid.scss?inline';
import { contentsChanged } from '../../utils/basic.js'; import { contentsChanged } from '../../utils/basic.js';
import './carousel.js'; import './carousel.js';
+1 -1
View File
@@ -21,7 +21,7 @@ import '../../components-lib/live/types.js';
import type { LiveConfig } from '../../config/schema/live.js'; import type { LiveConfig } from '../../config/schema/live.js';
import type { CardWideConfig } from '../../config/schema/types.js'; import type { CardWideConfig } from '../../config/schema/types.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import basicBlockStyle from '../../scss/basic-block.scss'; import basicBlockStyle from '../../scss/basic-block.scss?inline';
import { contentsChanged } from '../../utils/basic.js'; import { contentsChanged } from '../../utils/basic.js';
import './grid.js'; import './grid.js';
+1 -1
View File
@@ -23,7 +23,7 @@ import type { LiveConfig } from '../../config/schema/live.js';
import type { CardWideConfig } from '../../config/schema/types.js'; import type { CardWideConfig } from '../../config/schema/types.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import { localize } from '../../localize/localize.js'; import { localize } from '../../localize/localize.js';
import liveProviderStyle from '../../scss/live-provider.scss'; import liveProviderStyle from '../../scss/live-provider.scss?inline';
import type { import type {
MediaPlayer, MediaPlayer,
MediaPlayerController, MediaPlayerController,
@@ -34,7 +34,7 @@ import type { MicrophoneConfig } from '../../../../config/schema/live.js';
import type { CardWideConfig } from '../../../../config/schema/types.js'; import type { CardWideConfig } from '../../../../config/schema/types.js';
import type { HomeAssistant } from '../../../../ha/types.js'; import type { HomeAssistant } from '../../../../ha/types.js';
import { localize } from '../../../../localize/localize.js'; import { localize } from '../../../../localize/localize.js';
import liveGo2RTCExperimentalStyle from '../../../../scss/live-go2rtc-experimental.scss'; import liveGo2RTCExperimentalStyle from '../../../../scss/live-go2rtc-experimental.scss?inline';
import type { MediaPlayer, MediaPlayerController } from '../../../../types.js'; import type { MediaPlayer, MediaPlayerController } from '../../../../types.js';
import { import {
dispatchMediaPauseEvent, dispatchMediaPauseEvent,
@@ -18,7 +18,7 @@ import {
import type { MicrophoneConfig } from '../../../../config/schema/live.js'; import type { MicrophoneConfig } from '../../../../config/schema/live.js';
import type { HomeAssistant } from '../../../../ha/types.js'; import type { HomeAssistant } from '../../../../ha/types.js';
import { localize } from '../../../../localize/localize.js'; import { localize } from '../../../../localize/localize.js';
import liveGo2RTCStyle from '../../../../scss/live-go2rtc.scss'; import liveGo2RTCStyle from '../../../../scss/live-go2rtc.scss?inline';
import type { MediaPlayer, MediaPlayerController } from '../../../../types.js'; import type { MediaPlayer, MediaPlayerController } from '../../../../types.js';
import { renderMediaNotification } from '../../../notification/media.js'; import { renderMediaNotification } from '../../../notification/media.js';
import { VideoRTC } from './video-rtc.js'; import { VideoRTC } from './video-rtc.js';
+1 -1
View File
@@ -16,7 +16,7 @@ import '../../../patches/ha-camera-stream';
import '../../../patches/ha-hls-player.js'; import '../../../patches/ha-hls-player.js';
import '../../../patches/ha-web-rtc-player.js'; import '../../../patches/ha-web-rtc-player.js';
import liveHAStyle from '../../../scss/live-ha.scss'; import liveHAStyle from '../../../scss/live-ha.scss?inline';
import type { import type {
MediaPlayer, MediaPlayer,
MediaPlayerController, MediaPlayerController,
+1 -1
View File
@@ -12,7 +12,7 @@ import type { Camera } from '../../../camera-manager/camera.js';
import type { MediaUnavailableIssueReason } from '../../../card-controller/issues/issues/media-unavailable.js'; import type { MediaUnavailableIssueReason } from '../../../card-controller/issues/issues/media-unavailable.js';
import { dispatchLiveErrorEvent } from '../../../components-lib/live/utils/dispatch-live-error.js'; import { dispatchLiveErrorEvent } from '../../../components-lib/live/utils/dispatch-live-error.js';
import type { HomeAssistant } from '../../../ha/types'; import type { HomeAssistant } from '../../../ha/types';
import basicBlockStyle from '../../../scss/basic-block.scss'; import basicBlockStyle from '../../../scss/basic-block.scss?inline';
import type { import type {
MediaPlayer, MediaPlayer,
MediaPlayerController, MediaPlayerController,
+1 -1
View File
@@ -20,7 +20,7 @@ import type { CardWideConfig } from '../../../config/schema/types.js';
import { homeAssistantGetSignedURLIfNecessary } from '../../../ha/sign-path.js'; import { homeAssistantGetSignedURLIfNecessary } from '../../../ha/sign-path.js';
import type { HomeAssistant } from '../../../ha/types.js'; import type { HomeAssistant } from '../../../ha/types.js';
import { localize } from '../../../localize/localize.js'; import { localize } from '../../../localize/localize.js';
import liveJSMPEGStyle from '../../../scss/live-jsmpeg.scss'; import liveJSMPEGStyle from '../../../scss/live-jsmpeg.scss?inline';
import type { MediaPlayer, MediaPlayerController } from '../../../types.js'; import type { MediaPlayer, MediaPlayerController } from '../../../types.js';
import { errorToConsole } from '../../../utils/basic.js'; import { errorToConsole } from '../../../utils/basic.js';
import { import {
+1 -1
View File
@@ -20,7 +20,7 @@ import type { Notification } from '../../../config/schema/actions/types.js';
import type { CardWideConfig } from '../../../config/schema/types.js'; import type { CardWideConfig } from '../../../config/schema/types.js';
import type { HomeAssistant } from '../../../ha/types.js'; import type { HomeAssistant } from '../../../ha/types.js';
import { localize } from '../../../localize/localize.js'; import { localize } from '../../../localize/localize.js';
import liveWebRTCCardStyle from '../../../scss/live-webrtc-card.scss'; import liveWebRTCCardStyle from '../../../scss/live-webrtc-card.scss?inline';
import type { MediaPlayer, MediaPlayerController } from '../../../types.js'; import type { MediaPlayer, MediaPlayerController } from '../../../types.js';
import { mayHaveAudio } from '../../../utils/audio.js'; import { mayHaveAudio } from '../../../utils/audio.js';
import { import {
+1 -1
View File
@@ -7,7 +7,7 @@ import {
} from 'lit'; } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import loadingStyle from '../scss/loading.scss'; import loadingStyle from '../scss/loading.scss?inline';
import type { EffectName, EffectsManagerInterface } from '../types'; import type { EffectName, EffectsManagerInterface } from '../types';
import { getReleaseVersion } from '../utils/build-info.js'; import { getReleaseVersion } from '../utils/build-info.js';
+1 -1
View File
@@ -11,7 +11,7 @@ import { createRef, ref, type Ref } from 'lit/directives/ref.js';
import { MediaDimensionsContainerController } from '../components-lib/media-dimensions-container-controller.js'; import { MediaDimensionsContainerController } from '../components-lib/media-dimensions-container-controller.js';
import type { CameraDimensionsConfig } from '../config/schema/cameras'; import type { CameraDimensionsConfig } from '../config/schema/cameras';
import mediaDimensionsContainerStyle from '../scss/media-dimensions-container.scss'; import mediaDimensionsContainerStyle from '../scss/media-dimensions-container.scss?inline';
@customElement('advanced-camera-card-media-dimensions-container') @customElement('advanced-camera-card-media-dimensions-container')
export class AdvancedCameraCardMediaDimensionsContainer extends LitElement { export class AdvancedCameraCardMediaDimensionsContainer extends LitElement {
+1 -1
View File
@@ -21,7 +21,7 @@ import {
import type { CardWideConfig } from '../config/schema/types'; import type { CardWideConfig } from '../config/schema/types';
import type { HomeAssistant } from '../ha/types'; import type { HomeAssistant } from '../ha/types';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import mediaFilterStyle from '../scss/media-filter.scss'; import mediaFilterStyle from '../scss/media-filter.scss?inline';
import { AdvancedCameraCardDatePicker } from './date-picker'; import { AdvancedCameraCardDatePicker } from './date-picker';
import './date-picker.js'; import './date-picker.js';
+1 -1
View File
@@ -11,7 +11,7 @@ import { createRef, ref, type Ref } from 'lit/directives/ref.js';
import { MediaGridController } from '../components-lib/media-grid-controller.js'; import { MediaGridController } from '../components-lib/media-grid-controller.js';
import type { ViewDisplayConfig } from '../config/schema/common/display.js'; import type { ViewDisplayConfig } from '../config/schema/common/display.js';
import mediaGridStyle from '../scss/media-grid.scss'; import mediaGridStyle from '../scss/media-grid.scss?inline';
@customElement('advanced-camera-card-media-grid') @customElement('advanced-camera-card-media-grid')
export class AdvancedCameraCardMediaGrid extends LitElement { export class AdvancedCameraCardMediaGrid extends LitElement {
+1 -1
View File
@@ -17,7 +17,7 @@ import type { MenuConfig } from '../config/schema/menu.js';
import { getEntityTitle } from '../ha/get-entity-title.js'; import { getEntityTitle } from '../ha/get-entity-title.js';
import type { EntityRegistryManager } from '../ha/registry/entity/types.js'; import type { EntityRegistryManager } from '../ha/registry/entity/types.js';
import type { HomeAssistant } from '../ha/types.js'; import type { HomeAssistant } from '../ha/types.js';
import menuStyle from '../scss/menu.scss'; import menuStyle from '../scss/menu.scss?inline';
import { hasAction } from '../utils/action.js'; import { hasAction } from '../utils/action.js';
import { contentsChanged } from '../utils/basic.js'; import { contentsChanged } from '../utils/basic.js';
+1 -1
View File
@@ -12,7 +12,7 @@ import { isAutoHidden, type AutoHideState } from '../components-lib/auto-hide.js
import type { NextPreviousControlConfig } from '../config/schema/common/controls/next-previous.js'; import type { NextPreviousControlConfig } from '../config/schema/common/controls/next-previous.js';
import type { Icon } from '../config/schema/common/icon.js'; import type { Icon } from '../config/schema/common/icon.js';
import type { HomeAssistant } from '../ha/types.js'; import type { HomeAssistant } from '../ha/types.js';
import controlStyle from '../scss/next-previous-control.scss'; import controlStyle from '../scss/next-previous-control.scss?inline';
import { contentsChanged } from '../utils/basic.js'; import { contentsChanged } from '../utils/basic.js';
import { renderTask } from '../utils/task.js'; import { renderTask } from '../utils/task.js';
import { createFetchThumbnailTask } from '../utils/thumbnail.js'; import { createFetchThumbnailTask } from '../utils/thumbnail.js';
+1 -1
View File
@@ -15,7 +15,7 @@ import {
import { NotificationContextController } from '../../components-lib/notification/notification-context-controller.js'; import { NotificationContextController } from '../../components-lib/notification/notification-context-controller.js';
import type { Notification } from '../../config/schema/actions/types.js'; import type { Notification } from '../../config/schema/actions/types.js';
import { localize } from '../../localize/localize.js'; import { localize } from '../../localize/localize.js';
import notificationBlockStyle from '../../scss/notification-block.scss'; import notificationBlockStyle from '../../scss/notification-block.scss?inline';
import { import {
renderControl, renderControl,
renderDetail, renderDetail,
+1 -1
View File
@@ -13,7 +13,7 @@ import { NotificationContextController } from '../../components-lib/notification
import { NotificationPopupController } from '../../components-lib/notification/notification-popup-controller.js'; import { NotificationPopupController } from '../../components-lib/notification/notification-popup-controller.js';
import type { Notification } from '../../config/schema/actions/types.js'; import type { Notification } from '../../config/schema/actions/types.js';
import { localize } from '../../localize/localize.js'; import { localize } from '../../localize/localize.js';
import notificationPopupStyle from '../../scss/notification-popup.scss'; import notificationPopupStyle from '../../scss/notification-popup.scss?inline';
import { import {
renderControl, renderControl,
renderDetail, renderDetail,
+1 -1
View File
@@ -7,7 +7,7 @@ import {
} from 'lit'; } from 'lit';
import { customElement } from 'lit/decorators.js'; import { customElement } from 'lit/decorators.js';
import overlayStyle from '../scss/overlay.scss'; import overlayStyle from '../scss/overlay.scss?inline';
@customElement('advanced-camera-card-overlay') @customElement('advanced-camera-card-overlay')
export class AdvancedCameraCardOverlay extends LitElement { export class AdvancedCameraCardOverlay extends LitElement {
+1 -1
View File
@@ -10,7 +10,7 @@ import { classMap, type ClassInfo } from 'lit/directives/class-map.js';
import { ref, type Ref } from 'lit/directives/ref.js'; import { ref, type Ref } from 'lit/directives/ref.js';
import type { CardWideConfig } from '../config/schema/types'; import type { CardWideConfig } from '../config/schema/types';
import progressIndicatorStyle from '../scss/progress-indicator.scss'; import progressIndicatorStyle from '../scss/progress-indicator.scss?inline';
import './icon.js'; import './icon.js';
+1 -1
View File
@@ -20,7 +20,7 @@ import type {
} from '../config/schema/common/controls/ptz.js'; } from '../config/schema/common/controls/ptz.js';
import type { HomeAssistant } from '../ha/types.js'; import type { HomeAssistant } from '../ha/types.js';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import ptzStyle from '../scss/ptz.scss'; import ptzStyle from '../scss/ptz.scss?inline';
import type { Interaction } from '../types.js'; import type { Interaction } from '../types.js';
import { hasAction } from '../utils/action.js'; import { hasAction } from '../utils/action.js';
import { prettifyTitle } from '../utils/basic.js'; import { prettifyTitle } from '../utils/basic.js';
+1 -1
View File
@@ -12,7 +12,7 @@ import { createRef, ref, type Ref } from 'lit/directives/ref.js';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { grSelectElements } from '../scoped-elements/gr-select'; import { grSelectElements } from '../scoped-elements/gr-select';
import selectStyle from '../scss/select.scss'; import selectStyle from '../scss/select.scss?inline';
import { contentsChanged } from '../utils/basic'; import { contentsChanged } from '../utils/basic';
import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event'; import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event';
+1 -1
View File
@@ -15,7 +15,7 @@ import type { AutoHideState } from '../components-lib/auto-hide.js';
import { StatusBarController } from '../components-lib/status-bar-controller'; import { StatusBarController } from '../components-lib/status-bar-controller';
import type { StatusBarItem } from '../config/schema/actions/types.js'; import type { StatusBarItem } from '../config/schema/actions/types.js';
import type { StatusBarConfig } from '../config/schema/status-bar.js'; import type { StatusBarConfig } from '../config/schema/status-bar.js';
import statusStyle from '../scss/status.scss'; import statusStyle from '../scss/status.scss?inline';
import { hasAction } from '../utils/action'; import { hasAction } from '../utils/action';
import { contentsChanged } from '../utils/basic.js'; import { contentsChanged } from '../utils/basic.js';
+1 -1
View File
@@ -12,7 +12,7 @@ import { actionHandler } from '../../action-handler-directive.js';
import type { LockManagerEpoch } from '../../card-controller/lock/types'; import type { LockManagerEpoch } from '../../card-controller/lock/types';
import { getEntityTitle } from '../../ha/get-entity-title.js'; import { getEntityTitle } from '../../ha/get-entity-title.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import submenuStyle from '../../scss/submenu.scss'; import submenuStyle from '../../scss/submenu.scss?inline';
import { import {
hasAction, hasAction,
stopEventFromActivatingCardWideActions, stopEventFromActivatingCardWideActions,
+1 -1
View File
@@ -20,7 +20,7 @@ import { getEntityTitle } from '../../ha/get-entity-title.js';
import { isHassDifferent } from '../../ha/is-hass-different.js'; import { isHassDifferent } from '../../ha/is-hass-different.js';
import type { EntityRegistryManager } from '../../ha/registry/entity/types.js'; import type { EntityRegistryManager } from '../../ha/registry/entity/types.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import menuButtonStyle from '../../scss/menu-button.scss'; import menuButtonStyle from '../../scss/menu-button.scss?inline';
import { createSelectOptionAction, hasAction } from '../../utils/action.js'; import { createSelectOptionAction, hasAction } from '../../utils/action.js';
import '../icon.js'; import '../icon.js';
+1 -1
View File
@@ -12,7 +12,7 @@ import { actionHandler } from '../../action-handler-directive.js';
import type { LockManagerEpoch } from '../../card-controller/lock/types'; import type { LockManagerEpoch } from '../../card-controller/lock/types';
import type { MenuSubmenu } from '../../config/schema/elements/custom/menu/submenu.js'; import type { MenuSubmenu } from '../../config/schema/elements/custom/menu/submenu.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import menuButtonStyle from '../../scss/menu-button.scss'; import menuButtonStyle from '../../scss/menu-button.scss?inline';
import { hasAction } from '../../utils/action.js'; import { hasAction } from '../../utils/action.js';
import '../icon.js'; import '../icon.js';
+1 -1
View File
@@ -8,7 +8,7 @@ import {
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { createRef, ref, type Ref } from 'lit/directives/ref.js'; import { createRef, ref, type Ref } from 'lit/directives/ref.js';
import surroundBasicStyle from '../scss/surround-basic.scss'; import surroundBasicStyle from '../scss/surround-basic.scss?inline';
import { contentsChanged } from '../utils/basic.js'; import { contentsChanged } from '../utils/basic.js';
import './drawer.js'; import './drawer.js';
+1 -1
View File
@@ -17,7 +17,7 @@ import type { ThumbnailsControlConfig } from '../config/schema/common/controls/t
import type { MiniTimelineControlConfig } from '../config/schema/common/controls/timeline.js'; import type { MiniTimelineControlConfig } from '../config/schema/common/controls/timeline.js';
import type { CardWideConfig } from '../config/schema/types.js'; import type { CardWideConfig } from '../config/schema/types.js';
import type { HomeAssistant } from '../ha/types.js'; import type { HomeAssistant } from '../ha/types.js';
import basicBlockStyle from '../scss/basic-block.scss'; import basicBlockStyle from '../scss/basic-block.scss?inline';
import { contentsChanged } from '../utils/basic.js'; import { contentsChanged } from '../utils/basic.js';
import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js'; import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js';
+1 -1
View File
@@ -25,7 +25,7 @@ import type { ThumbnailsControlConfig } from '../config/schema/common/controls/t
import type { CardWideConfig } from '../config/schema/types.js'; import type { CardWideConfig } from '../config/schema/types.js';
import { MEDIA_CHUNK_SIZE_DEFAULT } from '../const.js'; import { MEDIA_CHUNK_SIZE_DEFAULT } from '../const.js';
import type { HomeAssistant } from '../ha/types.js'; import type { HomeAssistant } from '../ha/types.js';
import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss'; import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss?inline';
import { stopEventFromActivatingCardWideActions } from '../utils/action.js'; import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
import type { CarouselDirection } from '../utils/embla/carousel-controller.js'; import type { CarouselDirection } from '../utils/embla/carousel-controller.js';
import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js'; import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js';
+1 -1
View File
@@ -14,7 +14,7 @@ import type { CameraManager } from '../../camera-manager/manager';
import { MediaNotificationController } from '../../components-lib/media/notification-controller'; import { MediaNotificationController } from '../../components-lib/media/notification-controller';
import type { NotificationDetail } from '../../config/schema/actions/types'; import type { NotificationDetail } from '../../config/schema/actions/types';
import type { HomeAssistant } from '../../ha/types'; import type { HomeAssistant } from '../../ha/types';
import thumbnailDetailsStyle from '../../scss/thumbnail-details.scss'; import thumbnailDetailsStyle from '../../scss/thumbnail-details.scss?inline';
import type { ViewItem } from '../../view/item'; import type { ViewItem } from '../../view/item';
import '../icon'; import '../icon';
+1 -1
View File
@@ -20,7 +20,7 @@ import {
import { ThumbnailFeatureController } from '../../../components-lib/thumbnail/feature/controller'; import { ThumbnailFeatureController } from '../../../components-lib/thumbnail/feature/controller';
import type { HomeAssistant } from '../../../ha/types'; import type { HomeAssistant } from '../../../ha/types';
import { localize } from '../../../localize/localize'; import { localize } from '../../../localize/localize';
import thumbnailFeatureStyle from '../../../scss/thumbnail-feature.scss'; import thumbnailFeatureStyle from '../../../scss/thumbnail-feature.scss?inline';
import { import {
createNotificationAction, createNotificationAction,
stopEventFromActivatingCardWideActions, stopEventFromActivatingCardWideActions,
@@ -11,7 +11,7 @@ import { customElement, property } from 'lit/decorators.js';
import type { HomeAssistant } from '../../../ha/types'; import type { HomeAssistant } from '../../../ha/types';
import { localize } from '../../../localize/localize'; import { localize } from '../../../localize/localize';
import thumbnailFeatureThumbnailStyle from '../../../scss/thumbnail-feature-thumbnail.scss'; import thumbnailFeatureThumbnailStyle from '../../../scss/thumbnail-feature-thumbnail.scss?inline';
import { renderTask } from '../../../utils/task'; import { renderTask } from '../../../utils/task';
import { import {
createFetchThumbnailTask, createFetchThumbnailTask,
+1 -1
View File
@@ -6,7 +6,7 @@ import type { FoldersManager } from '../../card-controller/folders/manager.js';
import type { ViewItemManager } from '../../card-controller/view/item-manager.js'; import type { ViewItemManager } from '../../card-controller/view/item-manager.js';
import type { ViewManagerEpoch } from '../../card-controller/view/types.js'; import type { ViewManagerEpoch } from '../../card-controller/view/types.js';
import type { HomeAssistant } from '../../ha/types.js'; import type { HomeAssistant } from '../../ha/types.js';
import thumbnailStyle from '../../scss/thumbnail.scss'; import thumbnailStyle from '../../scss/thumbnail.scss?inline';
import type { ViewItem } from '../../view/item.js'; import type { ViewItem } from '../../view/item.js';
import './details.js'; import './details.js';
+1 -1
View File
@@ -26,7 +26,7 @@ import type { TimelineCoreComponentConfig } from '../config/schema/common/contro
import type { CardWideConfig } from '../config/schema/types'; import type { CardWideConfig } from '../config/schema/types';
import type { HomeAssistant } from '../ha/types'; import type { HomeAssistant } from '../ha/types';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import timelineCoreStyle from '../scss/timeline-core.scss'; import timelineCoreStyle from '../scss/timeline-core.scss?inline';
import { contentsChanged } from '../utils/basic'; import { contentsChanged } from '../utils/basic';
import './date-picker.js'; import './date-picker.js';
+1 -1
View File
@@ -15,7 +15,7 @@ import type { ConditionStateManagerReadonlyInterface } from '../condition-trigge
import type { TimelineConfig } from '../config/schema/timeline'; import type { TimelineConfig } from '../config/schema/timeline';
import type { CardWideConfig } from '../config/schema/types'; import type { CardWideConfig } from '../config/schema/types';
import type { HomeAssistant } from '../ha/types'; import type { HomeAssistant } from '../ha/types';
import basicBlockStyle from '../scss/basic-block.scss'; import basicBlockStyle from '../scss/basic-block.scss?inline';
import './surround.js'; import './surround.js';
import './timeline-core.js'; import './timeline-core.js';
+1 -1
View File
@@ -11,7 +11,7 @@ import { createRef, ref, type Ref } from 'lit/directives/ref.js';
import { MediaLoadedInfoSourceController } from '../components-lib/media-loaded-info-source-controller.js'; import { MediaLoadedInfoSourceController } from '../components-lib/media-loaded-info-source-controller.js';
import { VideoMediaPlayerController } from '../components-lib/media-player/video'; import { VideoMediaPlayerController } from '../components-lib/media-player/video';
import videoPlayerStyle from '../scss/video-player.scss'; import videoPlayerStyle from '../scss/video-player.scss?inline';
import type { MediaPlayer, MediaPlayerController, MediaPlayerElement } from '../types'; import type { MediaPlayer, MediaPlayerController, MediaPlayerElement } from '../types';
import { mayHaveAudio } from '../utils/audio'; import { mayHaveAudio } from '../utils/audio';
import { import {
+1 -1
View File
@@ -27,7 +27,7 @@ import { localize } from '../../localize/localize.js';
import '../../patches/ha-hls-player.js'; import '../../patches/ha-hls-player.js';
import viewerCarouselStyle from '../../scss/viewer-carousel.scss'; import viewerCarouselStyle from '../../scss/viewer-carousel.scss?inline';
import { stopEventFromActivatingCardWideActions } from '../../utils/action.js'; import { stopEventFromActivatingCardWideActions } from '../../utils/action.js';
import { contentsChanged } from '../../utils/basic.js'; import { contentsChanged } from '../../utils/basic.js';
import type { CarouselSelected } from '../../utils/embla/carousel-controller.js'; import type { CarouselSelected } from '../../utils/embla/carousel-controller.js';
+1 -1
View File
@@ -20,7 +20,7 @@ import type { HomeAssistant } from '../../ha/types.js';
import '../../patches/ha-hls-player.js'; import '../../patches/ha-hls-player.js';
import basicBlockStyle from '../../scss/basic-block.scss'; import basicBlockStyle from '../../scss/basic-block.scss?inline';
import './carousel'; import './carousel';
+1 -1
View File
@@ -18,7 +18,7 @@ import type { HomeAssistant } from '../../ha/types.js';
import '../../patches/ha-hls-player.js'; import '../../patches/ha-hls-player.js';
import viewerStyle from '../../scss/viewer.scss'; import viewerStyle from '../../scss/viewer.scss?inline';
import { ViewItemClassifier } from '../../view/item-classifier.js'; import { ViewItemClassifier } from '../../view/item-classifier.js';
import { renderNoMediaNotification } from '../notification/media.js'; import { renderNoMediaNotification } from '../notification/media.js';
+1 -1
View File
@@ -30,7 +30,7 @@ import type { HomeAssistant, ResolvedMedia } from '../../ha/types.js';
import '../../patches/ha-hls-player.js'; import '../../patches/ha-hls-player.js';
import viewerProviderStyle from '../../scss/viewer-provider.scss'; import viewerProviderStyle from '../../scss/viewer-provider.scss?inline';
import type { import type {
MediaPlayer, MediaPlayer,
MediaPlayerController, MediaPlayerController,
+1 -1
View File
@@ -27,7 +27,7 @@ import type { RawAdvancedCameraCardConfig } from '../config/types.js';
import type { DeviceRegistryManager } from '../ha/registry/device/index.js'; import type { DeviceRegistryManager } from '../ha/registry/device/index.js';
import type { ResolvedMediaCache } from '../ha/resolved-media.js'; import type { ResolvedMediaCache } from '../ha/resolved-media.js';
import type { HomeAssistant } from '../ha/types.js'; import type { HomeAssistant } from '../ha/types.js';
import viewsStyle from '../scss/views.scss'; import viewsStyle from '../scss/views.scss?inline';
import { contentsChanged } from '../utils/basic.js'; import { contentsChanged } from '../utils/basic.js';
import './surround.js'; import './surround.js';
+4 -1
View File
@@ -1,4 +1,7 @@
declare module '*.scss'; declare module '*.scss?inline' {
const css: string;
export default css;
}
declare module '*.svg' { declare module '*.svg' {
const icon: { path: string; viewBox: string }; const icon: { path: string; viewBox: string };
export default icon; export default icon;
+1 -1
View File
@@ -29,7 +29,7 @@ import { CONF_CAMERAS } from './config/const.js';
import type { RawAdvancedCameraCardConfig } from './config/types.js'; import type { RawAdvancedCameraCardConfig } from './config/types.js';
import type { HAFormSchema, HomeAssistant, LovelaceCardEditor } from './ha/types.js'; import type { HAFormSchema, HomeAssistant, LovelaceCardEditor } from './ha/types.js';
import { localize } from './localize/localize.js'; import { localize } from './localize/localize.js';
import editorStyle from './scss/editor.scss'; import editorStyle from './scss/editor.scss?inline';
import { fireAdvancedCameraCardEvent } from './utils/fire-advanced-camera-card-event.js'; import { fireAdvancedCameraCardEvent } from './utils/fire-advanced-camera-card-event.js';
interface EditorSection { interface EditorSection {
+1 -1
View File
@@ -28,7 +28,7 @@ import { MediaLoadedInfoSourceController } from '../components-lib/media-loaded-
import '../components/image-player.js'; import '../components/image-player.js';
import liveHAComponentsStyle from '../scss/live-ha-components.scss'; import liveHAComponentsStyle from '../scss/live-ha-components.scss?inline';
import type { import type {
MediaLoadedInfo, MediaLoadedInfo,
MediaLoadedInfoEventDetail, MediaLoadedInfoEventDetail,
+1 -1
View File
@@ -25,7 +25,7 @@ import { MediaLoadedInfoSourceController } from '../components-lib/media-loaded-
import { VideoMediaPlayerController } from '../components-lib/media-player/video.js'; import { VideoMediaPlayerController } from '../components-lib/media-player/video.js';
import { renderMediaNotification } from '../components/notification/media.js'; import { renderMediaNotification } from '../components/notification/media.js';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import liveHAComponentsStyle from '../scss/live-ha-components.scss'; import liveHAComponentsStyle from '../scss/live-ha-components.scss?inline';
import type { MediaPlayer, MediaPlayerController } from '../types.js'; import type { MediaPlayer, MediaPlayerController } from '../types.js';
import { mayHaveAudio } from '../utils/audio.js'; import { mayHaveAudio } from '../utils/audio.js';
import { errorToConsole } from '../utils/basic.js'; import { errorToConsole } from '../utils/basic.js';
+1 -1
View File
@@ -25,7 +25,7 @@ import { MediaLoadedInfoSourceController } from '../components-lib/media-loaded-
import { VideoMediaPlayerController } from '../components-lib/media-player/video.js'; import { VideoMediaPlayerController } from '../components-lib/media-player/video.js';
import { renderMediaNotification } from '../components/notification/media.js'; import { renderMediaNotification } from '../components/notification/media.js';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import liveHAComponentsStyle from '../scss/live-ha-components.scss'; import liveHAComponentsStyle from '../scss/live-ha-components.scss?inline';
import type { MediaPlayer, MediaPlayerController } from '../types.js'; import type { MediaPlayer, MediaPlayerController } from '../types.js';
import { import {
addAudioTracksMuteStateListener, addAudioTracksMuteStateListener,
+1 -1
View File
@@ -1,5 +1,5 @@
@use './themes/base.scss'; @use './themes/base.scss';
@import './z-index.scss'; @use './z-index.scss' as *;
:host { :host {
display: block; display: block;
+1 -1
View File
@@ -1,4 +1,4 @@
@import './z-index.scss'; @use './z-index.scss' as *;
:host { :host {
// Drawer width sizes to contents. // Drawer width sizes to contents.
+1 -1
View File
@@ -1,4 +1,4 @@
@import './z-index.scss'; @use './z-index.scss' as *;
:host { :host {
display: block; display: block;
+3 -3
View File
@@ -1,6 +1,6 @@
@import 'dark.scss'; @use 'dark.scss' as *;
@import 'light.scss'; @use 'light.scss' as *;
@import 'traditional.scss'; @use 'traditional.scss' as *;
:host { :host {
/********* /*********
@@ -0,0 +1,44 @@
import { describe, expect, it } from 'vitest';
import { MountedCardFactory } from '../browser/mounted-card';
import {
createStillCameraHASS,
createStillImageCardConfig,
} from '../browser/test-utils';
// A colour the dark theme sets and the card carries no other way. Reading it
// back proves the stylesheet reached the card rather than merely compiling.
// See src/scss/themes/dark.scss .
const DARK_PRIMARY_BACKGROUND = '#111111';
const mountThemed = async (themes: string[]) =>
await MountedCardFactory.createFromSource(
createStillImageCardConfig({ view: { theme: { themes } } }),
createStillCameraHASS(),
);
describe('themes', () => {
it('should style the card from the theme it is configured with', async () => {
const card = await mountThemed(['dark']);
await card.waitForRender(
() => card.card.getAttribute('themes'),
'the card being given its themes',
);
expect(
getComputedStyle(card.card).getPropertyValue('--primary-background-color').trim(),
).toBe(DARK_PRIMARY_BACKGROUND);
});
it('should not style the card from a theme it is not configured with', async () => {
const card = await mountThemed(['light']);
await card.waitForRender(
() => card.card.getAttribute('themes'),
'the card being given its themes',
);
expect(
getComputedStyle(card.card).getPropertyValue('--primary-background-color').trim(),
).not.toBe(DARK_PRIMARY_BACKGROUND);
});
});
+62
View File
@@ -0,0 +1,62 @@
import { beforeAll, describe, expect, it } from 'vitest';
import { commands } from 'vitest/browser';
import { defineHAElementStubs } from '../browser/ha-element-stubs';
import { flushBrowserWork, loadModule } from './test-utils';
beforeAll(() => {
// The card subclasses Home Assistant's own player elements once those exist.
// Without them the chunks holding the subclasses still load, but never run
// them.
defineHAElementStubs();
});
describe('every chunk the build emits', () => {
it('should load correctly', async () => {
const chunks = (await commands.listDistFiles()).filter((file) =>
file.endsWith('.js'),
);
expect(chunks.length).toBeGreaterThan(0);
const failures: string[] = [];
// What a chunk throws while running is reported to `window` rather than to
// whoever loaded it. The browser names the file it came from.
const recordError = (event: ErrorEvent): void => {
failures.push(`${event.filename}: ${event.message}`);
};
window.addEventListener('error', recordError);
// Part of what a chunk runs can be deferred to a promise it keeps to itself
// (e.g. the player subclasses wait on Home Assistant's own element), which
// is reported separately and without naming a file.
const recordRejection = (event: PromiseRejectionEvent): void => {
failures.push(`${event.reason}`);
};
window.addEventListener('unhandledrejection', recordRejection);
try {
// Most of what the build emits is reached only by a view the user has to
// navigate to, so nothing else here runs it. A chunk that throws the
// moment it is loaded -- a dependency resolved to a build the code using
// it cannot call, say -- reaches a user as a view that renders empty, and
// does so without failing any other test.
for (const chunk of chunks) {
try {
await loadModule(`/${chunk}`);
} catch (error) {
failures.push(`${chunk}: ${error}`);
}
}
// Need to flush browser work to ensure deferrals from the last chunk are
// noticed.
await flushBrowserWork();
} finally {
window.removeEventListener('error', recordError);
window.removeEventListener('unhandledrejection', recordRejection);
}
expect(failures).toEqual([]);
});
});

Some files were not shown because too many files have changed in this diff Show More