189 lines
4.7 KiB
TypeScript
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;
|