Files
advanced-camera-card/src/view/item.ts
T

189 lines
4.7 KiB
TypeScript

import { clone } from 'lodash-es';
import { FolderPathComponent } from '../card-controller/folders/types';
import { FolderConfig } from '../config/schema/folders';
import { Severity } from '../severity';
export enum ViewMediaType {
Clip = 'clip',
Snapshot = 'snapshot',
Recording = 'recording',
Review = 'review',
}
export interface ViewMediaSourceOptions {
cameraID?: string;
folder?: FolderConfig;
path?: readonly FolderPathComponent[];
}
export class ViewMedia {
protected _mediaType: ViewMediaType;
protected _cameraID: string | null;
protected _folder: FolderConfig | null;
constructor(mediaType: ViewMediaType, options?: ViewMediaSourceOptions) {
this._mediaType = mediaType;
this._cameraID = options?.cameraID ?? null;
this._folder = options?.folder ?? null;
}
public getCameraID(): string | null {
return this._cameraID;
}
public getFolder(): FolderConfig | null {
return this._folder;
}
public getMediaType(): ViewMediaType {
return this._mediaType;
}
public getID(): string | null {
return null;
}
public getStartTime(): Date | null {
return null;
}
public getEndTime(): Date | null {
return null;
}
public getUsableEndTime(): Date | null {
return this.getEndTime() ?? (this.inProgress() ? new Date() : this.getStartTime());
}
public inProgress(): boolean | null {
return null;
}
public getContentID(): string | null {
return null;
}
public getTitle(): string | null {
return null;
}
public getDescription(): string | null {
return null;
}
public getThumbnail(): string | null {
return null;
}
public getIcon(): string | null {
return null;
}
public isFavorite(): boolean | null {
return null;
}
public isReviewed(): boolean | null {
return null;
}
public includesTime(seek: Date): boolean {
const startTime = this.getStartTime();
const endTime = this.getUsableEndTime();
return !!startTime && !!endTime && seek >= startTime && seek <= endTime;
}
// Sets the favorite attribute (if any). This purely sets the media item as a
// favorite in JS.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public setFavorite(_favorite: boolean): void {
return;
}
public getSeverity(): Severity | null {
return null;
}
public getWhere(): string[] | null {
return null;
}
/**
* Creates a shallow clone of this ViewMedia instance.
*
* This is needed because Lit components use reference equality (===) to
* detect property changes. When we mutate an item's state (e.g.,
* setReviewed), the reference doesn't change, so Lit doesn't re-render. By
* cloning the item before mutation and replacing it in the QueryResults, we
* ensure Lit sees a new reference and updates the UI.
*/
public clone(): this {
return clone(this);
}
}
export interface EventViewMedia extends ViewMedia {
getScore(): number | null;
getWhat(): string[] | null;
getTags(): string[] | null;
isGroupableWith(that: EventViewMedia): boolean;
}
export interface RecordingViewMedia extends ViewMedia {
getEventCount(): number | null;
}
export interface ReviewViewMedia extends ViewMedia {
getWhat(): string[] | null;
isReviewed(): boolean | null;
setReviewed(reviewed: boolean): void;
}
interface ViewFolderParameters {
icon?: string | null;
id?: string | null;
title?: string | null;
thumbnail?: string | null;
}
export class ViewFolder {
private _folder: FolderConfig;
private _path: readonly FolderPathComponent[];
private _icon: string | null;
private _id: string | null;
private _title: string | null;
private _thumbnail: string | null;
constructor(
folder: FolderConfig,
path: readonly FolderPathComponent[],
params?: ViewFolderParameters,
) {
this._folder = folder;
this._path = path;
this._icon = params?.icon ?? null;
this._id = params?.id ?? null;
this._title = params?.title ?? null;
this._thumbnail = params?.thumbnail ?? null;
}
public getFolder(): FolderConfig {
return this._folder;
}
public getPath(): readonly FolderPathComponent[] {
return this._path;
}
public getID(): string | null {
return this._id;
}
public getTitle(): string | null {
return this._title;
}
public getDescription(): string | null {
return null;
}
public getThumbnail(): string | null {
return this._thumbnail;
}
public getIcon(): string | null {
return this._icon;
}
public getSeverity(): Severity | null {
return null;
}
public isFavorite(): boolean | null {
return null;
}
/** See ViewMedia.clone() for explanation. */
public clone(): this {
return clone(this);
}
}
export type ViewItem = ViewMedia | ViewFolder;