fix: Improve media background image (#1635)
* fix: Improve media background image * Simplify loading spinner. This is slightly less fancy, but removes code. I'm guessing no-one will notice or care enough to raise it! (BMFW).
This commit is contained in:
@@ -63,7 +63,6 @@ export class CardElementManager {
|
|||||||
this._api.getMediaLoadedInfoManager().initialize();
|
this._api.getMediaLoadedInfoManager().initialize();
|
||||||
this._api.getMicrophoneManager().initialize();
|
this._api.getMicrophoneManager().initialize();
|
||||||
this._api.getKeyboardStateManager().initialize();
|
this._api.getKeyboardStateManager().initialize();
|
||||||
this._api.getStyleManager().initialize();
|
|
||||||
|
|
||||||
// These initializers are called when the config is updated, but on initial
|
// These initializers are called when the config is updated, but on initial
|
||||||
// creation of the card hass is not yet available when the config is first
|
// creation of the card hass is not yet available when the config is first
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { StyleInfo } from 'lit/directives/style-map';
|
import { StyleInfo } from 'lit/directives/style-map';
|
||||||
import { FrigateCardConfig } from '../config/types';
|
import { FrigateCardConfig } from '../config/types';
|
||||||
import irisLogo from '../images/camera-iris.svg';
|
|
||||||
import { aspectRatioToStyle, setOrRemoveAttribute } from '../utils/basic';
|
import { aspectRatioToStyle, setOrRemoveAttribute } from '../utils/basic';
|
||||||
import { View } from '../view/view';
|
import { View } from '../view/view';
|
||||||
import { CardStyleAPI } from './types';
|
import { CardStyleAPI } from './types';
|
||||||
@@ -12,10 +11,6 @@ export class StyleManager {
|
|||||||
this._api = api;
|
this._api = api;
|
||||||
}
|
}
|
||||||
|
|
||||||
public initialize(): void {
|
|
||||||
this._setCommonStyleProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
public setLightOrDarkMode = (): void => {
|
public setLightOrDarkMode = (): void => {
|
||||||
const config = this._api.getConfigManager().getConfig();
|
const config = this._api.getConfigManager().getConfig();
|
||||||
const isDarkMode =
|
const isDarkMode =
|
||||||
@@ -138,11 +133,4 @@ export class StyleManager {
|
|||||||
}
|
}
|
||||||
return aspectRatioToStyle({ defaultStatic: true });
|
return aspectRatioToStyle({ defaultStatic: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _setCommonStyleProperties(): void {
|
|
||||||
this._api
|
|
||||||
.getCardElementManager()
|
|
||||||
.getElement()
|
|
||||||
.style.setProperty('--frigate-card-media-background-image', `url("${irisLogo}")`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,6 @@ export interface CardElementAPI {
|
|||||||
getMediaLoadedInfoManager(): MediaLoadedInfoManager;
|
getMediaLoadedInfoManager(): MediaLoadedInfoManager;
|
||||||
getMediaPlayerManager(): MediaPlayerManager;
|
getMediaPlayerManager(): MediaPlayerManager;
|
||||||
getMicrophoneManager(): MicrophoneManager;
|
getMicrophoneManager(): MicrophoneManager;
|
||||||
getStyleManager(): StyleManager;
|
|
||||||
getQueryStringManager(): QueryStringManager;
|
getQueryStringManager(): QueryStringManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-6
@@ -339,9 +339,8 @@ class FrigateCard extends LitElement {
|
|||||||
|
|
||||||
const actions = this._controller.getActionsManager().getMergedActions();
|
const actions = this._controller.getActionsManager().getMergedActions();
|
||||||
const cameraManager = this._controller.getCameraManager();
|
const cameraManager = this._controller.getCameraManager();
|
||||||
const renderLoadingSpinner =
|
|
||||||
this._config?.performance?.features.animated_progress_indicator !== false;
|
|
||||||
const showLoadingSpinner =
|
const showLoadingSpinner =
|
||||||
|
this._config?.performance?.features.animated_progress_indicator !== false &&
|
||||||
!this._controller.getInitializationManager().wasEverInitialized() &&
|
!this._controller.getInitializationManager().wasEverInitialized() &&
|
||||||
!this._controller.getMessageManager().hasMessage();
|
!this._controller.getMessageManager().hasMessage();
|
||||||
|
|
||||||
@@ -372,10 +371,7 @@ class FrigateCard extends LitElement {
|
|||||||
}
|
}
|
||||||
@frigate-card:focus=${() => this.focus()}
|
@frigate-card:focus=${() => this.focus()}
|
||||||
>
|
>
|
||||||
${renderLoadingSpinner
|
${showLoadingSpinner ? html`<frigate-card-loading></frigate-card-loading>` : ''}
|
||||||
? html`<frigate-card-loading .show=${showLoadingSpinner}>
|
|
||||||
</frigate-card-loading>`
|
|
||||||
: ''}
|
|
||||||
${this._renderMenuStatusContainer('top')}
|
${this._renderMenuStatusContainer('top')}
|
||||||
${this._renderMenuStatusContainer('overlay')}
|
${this._renderMenuStatusContainer('overlay')}
|
||||||
<div ${ref(this._refMain)} class="${classMap(mainClasses)}">
|
<div ${ref(this._refMain)} class="${classMap(mainClasses)}">
|
||||||
|
|||||||
@@ -1,44 +1,16 @@
|
|||||||
import {
|
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
|
||||||
CSSResultGroup,
|
import { customElement } from 'lit/decorators.js';
|
||||||
LitElement,
|
import irisLogo from '../images/camera-iris-transparent.svg';
|
||||||
PropertyValues,
|
import loadingStyle from '../scss/loading.scss';
|
||||||
TemplateResult,
|
|
||||||
html,
|
|
||||||
unsafeCSS,
|
|
||||||
} from 'lit';
|
|
||||||
import { customElement, property, state } from 'lit/decorators.js';
|
|
||||||
import irisLogo from '../images/camera-iris.svg';
|
|
||||||
import controlStyle from '../scss/loading.scss';
|
|
||||||
import { Timer } from '../utils/timer';
|
|
||||||
|
|
||||||
// Number of seconds after the loading spinner is hidden before rendering this
|
|
||||||
// component as empty. Should be longer than the opacity css transition time.
|
|
||||||
const LOADING_EMPTY_SECONDS = 2;
|
|
||||||
|
|
||||||
@customElement('frigate-card-loading')
|
@customElement('frigate-card-loading')
|
||||||
export class FrigateCardLoading extends LitElement {
|
export class FrigateCardLoading extends LitElement {
|
||||||
@property({ attribute: true, reflect: true, type: Boolean })
|
|
||||||
public show = false;
|
|
||||||
|
|
||||||
@state()
|
|
||||||
protected _empty = false;
|
|
||||||
|
|
||||||
protected _timer = new Timer();
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return this._empty ? html`` : html` <img src="${irisLogo}" /> `;
|
return html` <img src="${irisLogo}" /> `;
|
||||||
}
|
|
||||||
|
|
||||||
protected willUpdate(changedProps: PropertyValues): void {
|
|
||||||
if (changedProps.has('show') && !this.show) {
|
|
||||||
this._timer.start(LOADING_EMPTY_SECONDS, () => {
|
|
||||||
this._empty = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return unsafeCSS(controlStyle);
|
return unsafeCSS(loadingStyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||||
|
sodipodi:docname="camera-iris.svg"
|
||||||
|
id="svg4"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#b93e3e"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.60784314"
|
||||||
|
inkscape:pagecheckerboard="false"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="26.62506"
|
||||||
|
inkscape:cx="-1.934268"
|
||||||
|
inkscape:cy="15.680716"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="1527"
|
||||||
|
inkscape:window-x="1080"
|
||||||
|
inkscape:window-y="227"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<g
|
||||||
|
id="g1119"
|
||||||
|
style="fill-opacity:0.05;fill:#ffffff">
|
||||||
|
<circle
|
||||||
|
style="fill:#ffffff;fill-opacity:0.05;stroke-width:1.39729"
|
||||||
|
id="path170"
|
||||||
|
cx="12"
|
||||||
|
cy="12"
|
||||||
|
inkscape:label="White Background"
|
||||||
|
r="11.25" />
|
||||||
|
<path
|
||||||
|
d="M 13.730001,15 9.8300003,21.76 C 10.53,21.91 11.25,22 12,22 c 2.400001,0 4.6,-0.85 6.32,-2.25 L 14.660001,13.4 M 2.4600003,15 c 0.92,2.92 3.15,5.26 5.99,6.34 L 12.12,15 m -3.5799997,-3 -3.9,-6.7499996 c -1.64,1.749999 -2.64,4.1399993 -2.64,6.7499996 0,0.68 0.07,1.35 0.2,2 h 7.49 M 21.8,9.9999997 H 14.310001 L 14.600001,10.5 19.36,18.75 C 21,16.97 22,14.6 22,12 22,11.31 21.93,10.64 21.8,9.9999997 m -0.26,-1 C 20.62,6.0700005 18.39,3.7400002 15.550001,2.6600002 L 11.88,8.9999997 M 9.4000003,10.5 14.170001,2.2400002 c -0.7,-0.15 -1.420001,-0.24 -2.170001,-0.24 -2.3999997,0 -4.5999997,0.84 -6.3199997,2.2500003 l 3.66,6.3499995 z"
|
||||||
|
id="path2"
|
||||||
|
inkscape:label="Iris"
|
||||||
|
style="fill-opacity:0.05;fill:#ffffff" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
+3
-19
@@ -1,32 +1,16 @@
|
|||||||
:host {
|
:host {
|
||||||
height: 100%;
|
width: intrinsic;
|
||||||
width: 100%;
|
height: intrinsic;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
transition: opacity 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([show]) {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host(:not([show])) {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 40%;
|
width: 10%;
|
||||||
height: 40%;
|
|
||||||
|
|
||||||
opacity: 0.2;
|
|
||||||
|
|
||||||
filter: invert(100%);
|
|
||||||
|
|
||||||
animation: rotate 8s linear infinite;
|
animation: rotate 8s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
$bg-img: url('../images/camera-iris-transparent.svg');
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
|
background-color: var(--primary-background-color);
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-image: var(--frigate-card-media-background-image);
|
background-image: $bg-img;
|
||||||
background-size: 25%;
|
background-size: 10%;
|
||||||
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,6 @@ describe('CardElementManager', () => {
|
|||||||
expect(api.getExpandManager().initialize).toBeCalled();
|
expect(api.getExpandManager().initialize).toBeCalled();
|
||||||
expect(api.getMediaLoadedInfoManager().initialize).toBeCalled();
|
expect(api.getMediaLoadedInfoManager().initialize).toBeCalled();
|
||||||
expect(api.getMicrophoneManager().initialize).toBeCalled();
|
expect(api.getMicrophoneManager().initialize).toBeCalled();
|
||||||
expect(api.getStyleManager().initialize).toBeCalled();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should disconnect', () => {
|
it('should disconnect', () => {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import { StyleManager } from '../../src/card-controller/style-manager';
|
import { StyleManager } from '../../src/card-controller/style-manager';
|
||||||
import { FrigateCardView } from '../../src/config/types';
|
import { FrigateCardView } from '../../src/config/types';
|
||||||
import irisLogo from '../../src/images/camera-iris.svg';
|
|
||||||
import { createCardAPI, createConfig, createHASS, createView } from '../test-utils';
|
import { createCardAPI, createConfig, createHASS, createView } from '../test-utils';
|
||||||
|
|
||||||
// @vitest-environment jsdom
|
// @vitest-environment jsdom
|
||||||
@@ -10,21 +9,6 @@ describe('StyleManager', () => {
|
|||||||
vi.resetAllMocks();
|
vi.resetAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('initialize should set common properties', () => {
|
|
||||||
it('should set media background', () => {
|
|
||||||
const api = createCardAPI();
|
|
||||||
const element = document.createElement('div');
|
|
||||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
|
||||||
const manager = new StyleManager(api);
|
|
||||||
|
|
||||||
manager.initialize();
|
|
||||||
|
|
||||||
expect(
|
|
||||||
element.style.getPropertyValue('--frigate-card-media-background-image'),
|
|
||||||
).toEqual(`url("${irisLogo}")`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('setLightOrDarkMode', () => {
|
describe('setLightOrDarkMode', () => {
|
||||||
it('dark mode unspecified', () => {
|
it('dark mode unspecified', () => {
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
|||||||
Reference in New Issue
Block a user