Support media type in core filter.
This commit is contained in:
@@ -10,7 +10,7 @@ import { customElement, property } from 'lit/decorators.js';
|
|||||||
import { createRef, ref, Ref } from 'lit/directives/ref.js';
|
import { createRef, ref, Ref } from 'lit/directives/ref.js';
|
||||||
import { DateRange } from '../camera/range';
|
import { DateRange } from '../camera/range';
|
||||||
import { localize } from '../localize/localize';
|
import { localize } from '../localize/localize';
|
||||||
import mediaFilterStyle from '../scss/media-filter.scss';
|
import mediaFilterCoreStyle from '../scss/media-filter-core.scss';
|
||||||
import { ExtendedHomeAssistant } from '../types';
|
import { ExtendedHomeAssistant } from '../types';
|
||||||
import { dispatchFrigateCardEvent } from '../utils/basic';
|
import { dispatchFrigateCardEvent } from '../utils/basic';
|
||||||
|
|
||||||
@@ -20,6 +20,7 @@ export interface ValueLabel<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface MediaFilterCoreSelection {
|
export interface MediaFilterCoreSelection {
|
||||||
|
mediaType?: MediaFilterMediaType;
|
||||||
cameraIDs?: Set<string>;
|
cameraIDs?: Set<string>;
|
||||||
what?: Set<string>;
|
what?: Set<string>;
|
||||||
where?: Set<string>;
|
where?: Set<string>;
|
||||||
@@ -44,11 +45,26 @@ export enum MediaFilterCoreWhen {
|
|||||||
Custom = 'custom',
|
Custom = 'custom',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum MediaFilterMediaType {
|
||||||
|
Clips = 'clips',
|
||||||
|
Snapshots = 'snapshots',
|
||||||
|
Recordings = 'recordings',
|
||||||
|
}
|
||||||
|
|
||||||
export interface MediaFilterCoreWhenSelection {
|
export interface MediaFilterCoreWhenSelection {
|
||||||
selection: MediaFilterCoreWhen;
|
selection: MediaFilterCoreWhen;
|
||||||
custom?: DateRange;
|
custom?: DateRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum MediaFilterControl {
|
||||||
|
mediaType = 'mediaType',
|
||||||
|
when = 'when',
|
||||||
|
camera = 'camera',
|
||||||
|
what = 'what',
|
||||||
|
where = 'where',
|
||||||
|
favorite = 'favorite',
|
||||||
|
}
|
||||||
|
|
||||||
@customElement('frigate-card-media-filter-core')
|
@customElement('frigate-card-media-filter-core')
|
||||||
export class FrigateCardMediaFilterCore extends LitElement {
|
export class FrigateCardMediaFilterCore extends LitElement {
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
@@ -69,12 +85,17 @@ export class FrigateCardMediaFilterCore extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public defaults?: MediaFilterCoreSelection;
|
public defaults?: MediaFilterCoreSelection;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public controls?: Record<MediaFilterControl, boolean>;
|
||||||
|
|
||||||
protected _cameraOptions?: ValueLabel<string>[];
|
protected _cameraOptions?: ValueLabel<string>[];
|
||||||
protected _whenOptions?: ValueLabel<MediaFilterCoreWhenSelection>[];
|
protected _whenOptions?: ValueLabel<MediaFilterCoreWhenSelection>[];
|
||||||
protected _whatOptions?: ValueLabel<string>[];
|
protected _whatOptions?: ValueLabel<string>[];
|
||||||
protected _whereOptions?: ValueLabel<string>[];
|
protected _whereOptions?: ValueLabel<string>[];
|
||||||
protected _favoriteOptions: ValueLabel<MediaFilterCoreFavoriteSelection>[];
|
protected _favoriteOptions: ValueLabel<MediaFilterCoreFavoriteSelection>[];
|
||||||
|
protected _mediaTypeOptions: ValueLabel<MediaFilterMediaType>[];
|
||||||
|
|
||||||
|
protected _refMediaType: Ref<FilterElement<MediaFilterMediaType>> = createRef();
|
||||||
protected _refCamera: Ref<FilterElement<string>> = createRef();
|
protected _refCamera: Ref<FilterElement<string>> = createRef();
|
||||||
protected _refWhen: Ref<FilterElement<MediaFilterCoreWhenSelection>> = createRef();
|
protected _refWhen: Ref<FilterElement<MediaFilterCoreWhenSelection>> = createRef();
|
||||||
protected _refWhat: Ref<FilterElement<string>> = createRef();
|
protected _refWhat: Ref<FilterElement<string>> = createRef();
|
||||||
@@ -98,6 +119,20 @@ export class FrigateCardMediaFilterCore extends LitElement {
|
|||||||
label: localize('media_filter.not_favorite'),
|
label: localize('media_filter.not_favorite'),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
this._mediaTypeOptions = [
|
||||||
|
{
|
||||||
|
value: MediaFilterMediaType.Clips,
|
||||||
|
label: localize('media_filter.media_types.clips'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: MediaFilterMediaType.Snapshots,
|
||||||
|
label: localize('media_filter.media_types.snapshots'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: MediaFilterMediaType.Recordings,
|
||||||
|
label: localize('media_filter.media_types.recordings'),
|
||||||
|
},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _valueChangedHandler(ev: CustomEvent<{ value: unknown }>): void {
|
protected _valueChangedHandler(ev: CustomEvent<{ value: unknown }>): void {
|
||||||
@@ -106,6 +141,10 @@ export class FrigateCardMediaFilterCore extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const values: MediaFilterCoreSelection = {
|
const values: MediaFilterCoreSelection = {
|
||||||
|
...(this._refMediaType.value &&
|
||||||
|
this._refMediaType.value.selectedItem?.value && {
|
||||||
|
mediaType: this._refMediaType.value.selectedItem?.value,
|
||||||
|
}),
|
||||||
...(this._refCamera.value &&
|
...(this._refCamera.value &&
|
||||||
this._refCamera.value.selectedItem?.value && {
|
this._refCamera.value.selectedItem?.value && {
|
||||||
cameraIDs: new Set([this._refCamera.value.selectedItem.value]),
|
cameraIDs: new Set([this._refCamera.value.selectedItem.value]),
|
||||||
@@ -150,19 +189,19 @@ export class FrigateCardMediaFilterCore extends LitElement {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: { selection: MediaFilterCoreWhen.Today },
|
value: { selection: MediaFilterCoreWhen.Today },
|
||||||
label: localize('media_filter.today'),
|
label: localize('media_filter.whens.today'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: { selection: MediaFilterCoreWhen.Yesterday },
|
value: { selection: MediaFilterCoreWhen.Yesterday },
|
||||||
label: localize('media_filter.yesterday'),
|
label: localize('media_filter.whens.yesterday'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: { selection: MediaFilterCoreWhen.PastWeek },
|
value: { selection: MediaFilterCoreWhen.PastWeek },
|
||||||
label: localize('media_filter.past_week'),
|
label: localize('media_filter.whens.past_week'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: { selection: MediaFilterCoreWhen.PastMonth },
|
value: { selection: MediaFilterCoreWhen.PastMonth },
|
||||||
label: localize('media_filter.past_month'),
|
label: localize('media_filter.whens.past_month'),
|
||||||
},
|
},
|
||||||
...(this.whenOptions ?? []),
|
...(this.whenOptions ?? []),
|
||||||
];
|
];
|
||||||
@@ -186,58 +225,72 @@ export class FrigateCardMediaFilterCore extends LitElement {
|
|||||||
* @returns A rendered template.
|
* @returns A rendered template.
|
||||||
*/
|
*/
|
||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
return html`
|
return html` ${this.controls?.mediaType ?? true
|
||||||
<ha-combo-box
|
? html` <ha-combo-box
|
||||||
${ref(this._refWhen)}
|
${ref(this._refMediaType)}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.label=${localize('media_filter.when')}
|
.label=${localize('media_filter.media_type')}
|
||||||
.items=${this._whenOptions}
|
.items=${this._mediaTypeOptions}
|
||||||
.allowCustomValue=${false}
|
.allowCustomValue=${false}
|
||||||
@value-changed=${this._valueChangedHandler.bind(this)}
|
@value-changed=${this._valueChangedHandler.bind(this)}
|
||||||
></ha-combo-box>
|
></ha-combo-box>`
|
||||||
${this.cameraOptions
|
: ''}
|
||||||
? html` <ha-combo-box
|
${this.controls?.when ?? true
|
||||||
${ref(this._refCamera)}
|
? html`<ha-combo-box
|
||||||
|
${ref(this._refWhen)}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.label=${localize('media_filter.when')}
|
||||||
|
.items=${this._whenOptions}
|
||||||
|
.allowCustomValue=${false}
|
||||||
|
@value-changed=${this._valueChangedHandler.bind(this)}
|
||||||
|
></ha-combo-box>`
|
||||||
|
: ''}
|
||||||
|
${(this.controls?.camera ?? true) && this.cameraOptions
|
||||||
|
? html` <ha-combo-box
|
||||||
|
${ref(this._refCamera)}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.label=${localize('media_filter.camera')}
|
||||||
|
.items=${this._cameraOptions}
|
||||||
|
.allowCustomValue=${false}
|
||||||
|
@value-changed=${this._valueChangedHandler.bind(this)}
|
||||||
|
></ha-combo-box>`
|
||||||
|
: ''}
|
||||||
|
${(this.controls?.what ?? true) && this.whatOptions
|
||||||
|
? html` <ha-combo-box
|
||||||
|
${ref(this._refWhat)}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.label=${localize('media_filter.what')}
|
||||||
|
.items="${this._whatOptions}"
|
||||||
|
.allowCustomValue=${false}
|
||||||
|
@value-changed=${this._valueChangedHandler.bind(this)}
|
||||||
|
></ha-combo-box>`
|
||||||
|
: ''}
|
||||||
|
${(this.controls?.where ?? true) && this.whereOptions
|
||||||
|
? html`<ha-combo-box
|
||||||
|
${ref(this._refWhere)}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.label=${localize('media_filter.where')}
|
||||||
|
.items=${this._whereOptions}
|
||||||
|
.allowCustomValue=${false}
|
||||||
|
@value-changed=${this._valueChangedHandler.bind(this)}
|
||||||
|
></ha-combo-box>`
|
||||||
|
: ''}
|
||||||
|
${this.controls?.favorite ?? true
|
||||||
|
? html`
|
||||||
|
<ha-combo-box
|
||||||
|
${ref(this._refFavorite)}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.label=${localize('media_filter.camera')}
|
.label=${localize('media_filter.favorite')}
|
||||||
.items=${this._cameraOptions}
|
.items=${this._favoriteOptions}
|
||||||
.allowCustomValue=${false}
|
.allowCustomValue=${false}
|
||||||
@value-changed=${this._valueChangedHandler.bind(this)}
|
@value-changed=${this._valueChangedHandler.bind(this)}
|
||||||
></ha-combo-box>`
|
></ha-combo-box>
|
||||||
: ''}
|
`
|
||||||
${this.whatOptions
|
: ''}`;
|
||||||
? html` <ha-combo-box
|
|
||||||
${ref(this._refWhat)}
|
|
||||||
.hass=${this.hass}
|
|
||||||
.label=${localize('media_filter.what')}
|
|
||||||
.items="${this._whatOptions}"
|
|
||||||
.allowCustomValue=${false}
|
|
||||||
@value-changed=${this._valueChangedHandler.bind(this)}
|
|
||||||
></ha-combo-box>`
|
|
||||||
: ''}
|
|
||||||
${this.whereOptions
|
|
||||||
? html`<ha-combo-box
|
|
||||||
${ref(this._refWhere)}
|
|
||||||
.hass=${this.hass}
|
|
||||||
.label=${localize('media_filter.where')}
|
|
||||||
.items=${this._whereOptions}
|
|
||||||
.allowCustomValue=${false}
|
|
||||||
@value-changed=${this._valueChangedHandler.bind(this)}
|
|
||||||
></ha-combo-box>`
|
|
||||||
: ''}
|
|
||||||
<ha-combo-box
|
|
||||||
${ref(this._refFavorite)}
|
|
||||||
.hass=${this.hass}
|
|
||||||
.label=${localize('media_filter.favorite')}
|
|
||||||
.items=${this._favoriteOptions}
|
|
||||||
.allowCustomValue=${false}
|
|
||||||
@value-changed=${this._valueChangedHandler.bind(this)}
|
|
||||||
></ha-combo-box>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return unsafeCSS(mediaFilterStyle);
|
return unsafeCSS(mediaFilterCoreStyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import startOfToday from 'date-fns/esm/startOfToday';
|
|||||||
import startOfDay from 'date-fns/startOfDay';
|
import startOfDay from 'date-fns/startOfDay';
|
||||||
import startOfYesterday from 'date-fns/startOfYesterday';
|
import startOfYesterday from 'date-fns/startOfYesterday';
|
||||||
import {
|
import {
|
||||||
css,
|
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
@@ -14,6 +13,7 @@ import {
|
|||||||
ReactiveController,
|
ReactiveController,
|
||||||
ReactiveControllerHost,
|
ReactiveControllerHost,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
|
unsafeCSS,
|
||||||
} from 'lit';
|
} from 'lit';
|
||||||
import { customElement, property } from 'lit/decorators.js';
|
import { customElement, property } from 'lit/decorators.js';
|
||||||
import { CameraManager } from '../camera/manager';
|
import { CameraManager } from '../camera/manager';
|
||||||
@@ -38,6 +38,7 @@ import { prettifyTitle } from '../utils/basic';
|
|||||||
import format from 'date-fns/format';
|
import format from 'date-fns/format';
|
||||||
import parse from 'date-fns/parse';
|
import parse from 'date-fns/parse';
|
||||||
import endOfMonth from 'date-fns/endOfMonth';
|
import endOfMonth from 'date-fns/endOfMonth';
|
||||||
|
import mediaFilterStyle from '../scss/media-filter.scss';
|
||||||
|
|
||||||
@customElement('frigate-card-media-filter')
|
@customElement('frigate-card-media-filter')
|
||||||
export class FrigateCardMediaFilter extends LitElement {
|
export class FrigateCardMediaFilter extends LitElement {
|
||||||
@@ -158,11 +159,7 @@ export class FrigateCardMediaFilter extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return unsafeCSS(mediaFilterStyle);
|
||||||
:host {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -368,14 +368,22 @@
|
|||||||
"all": "All",
|
"all": "All",
|
||||||
"camera": "Camera",
|
"camera": "Camera",
|
||||||
"favorite": "Favorite",
|
"favorite": "Favorite",
|
||||||
|
"media_type": "Media Type",
|
||||||
|
"media_types": {
|
||||||
|
"clips": "Clips",
|
||||||
|
"snapshots": "Snapshots",
|
||||||
|
"recordings": "Recordings"
|
||||||
|
},
|
||||||
"not_favorite": "Not Favorite",
|
"not_favorite": "Not Favorite",
|
||||||
"past_month": "Past Month",
|
|
||||||
"past_week": "Past Week",
|
|
||||||
"today": "Today",
|
|
||||||
"what": "What",
|
"what": "What",
|
||||||
"when": "When",
|
"when": "When",
|
||||||
"where": "Where",
|
"whens": {
|
||||||
"yesterday": "Yesterday"
|
"past_month": "Past Month",
|
||||||
|
"past_week": "Past Week",
|
||||||
|
"today": "Today",
|
||||||
|
"yesterday": "Yesterday"
|
||||||
|
},
|
||||||
|
"where": "Where"
|
||||||
},
|
},
|
||||||
"recording": {
|
"recording": {
|
||||||
"events": "Events",
|
"events": "Events",
|
||||||
|
|||||||
@@ -339,14 +339,22 @@
|
|||||||
"all": "",
|
"all": "",
|
||||||
"camera": "",
|
"camera": "",
|
||||||
"favorite": "",
|
"favorite": "",
|
||||||
|
"media_type": "",
|
||||||
|
"media_types": {
|
||||||
|
"clips": "",
|
||||||
|
"snapshots": "",
|
||||||
|
"recordings": ""
|
||||||
|
},
|
||||||
"not_favorite": "",
|
"not_favorite": "",
|
||||||
"past_month": "",
|
|
||||||
"past_week": "",
|
|
||||||
"today": "",
|
|
||||||
"what": "",
|
"what": "",
|
||||||
"when": "",
|
"when": "",
|
||||||
"where": "",
|
"whens": {
|
||||||
"yesterday": ""
|
"past_month": "",
|
||||||
|
"past_week": "",
|
||||||
|
"today": "",
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
|
"where": ""
|
||||||
},
|
},
|
||||||
"recording": {
|
"recording": {
|
||||||
"events": "Eventi",
|
"events": "Eventi",
|
||||||
|
|||||||
@@ -339,14 +339,22 @@
|
|||||||
"all": "",
|
"all": "",
|
||||||
"camera": "",
|
"camera": "",
|
||||||
"favorite": "",
|
"favorite": "",
|
||||||
|
"media_type": "",
|
||||||
|
"media_types": {
|
||||||
|
"clips": "",
|
||||||
|
"snapshots": "",
|
||||||
|
"recordings": ""
|
||||||
|
},
|
||||||
"not_favorite": "",
|
"not_favorite": "",
|
||||||
"past_month": "",
|
|
||||||
"past_week": "",
|
|
||||||
"today": "",
|
|
||||||
"what": "",
|
"what": "",
|
||||||
"when": "",
|
"when": "",
|
||||||
"where": "",
|
"whens": {
|
||||||
"yesterday": ""
|
"past_month": "",
|
||||||
|
"past_week": "",
|
||||||
|
"today": "",
|
||||||
|
"yesterday": ""
|
||||||
|
},
|
||||||
|
"where": ""
|
||||||
},
|
},
|
||||||
"recording": {
|
"recording": {
|
||||||
"events": "Eventos",
|
"events": "Eventos",
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
:host {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
// Hide scrollbar: Firefox
|
||||||
|
scrollbar-width: none;
|
||||||
|
// Hide scrollbar: IE and Edge
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||||
|
:host::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
:host {
|
:host {
|
||||||
display: flex;
|
display: block;
|
||||||
flex-direction: column;
|
height: 100%;
|
||||||
overflow: auto;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user