committed by
dermotduffy
parent
149fce4823
commit
591f466b92
@@ -115,6 +115,7 @@ export interface NativeFrigateEventQuery {
|
||||
instance_id?: string;
|
||||
cameras?: string[];
|
||||
labels?: string[];
|
||||
sub_labels?: string[];
|
||||
zones?: string[];
|
||||
after?: number;
|
||||
before?: number;
|
||||
|
||||
@@ -155,6 +155,11 @@ export type FrigateReviewSeverity =
|
||||
// Review data schema (only fields we need for display)
|
||||
const frigateReviewDataSchema = z.object({
|
||||
objects: z.string().array().optional(),
|
||||
|
||||
// Frigate adds sub_labels for non-attribute identifications (e.g. Frigate+
|
||||
// species name for a bird). Note: The matching `objects` entry carries a
|
||||
// `-verified` suffix in that case.
|
||||
sub_labels: z.string().array().optional(),
|
||||
zones: z.string().array().optional(),
|
||||
metadata: z
|
||||
.object({
|
||||
|
||||
@@ -105,12 +105,24 @@ export const getRecordingID = (
|
||||
* @param review The Frigate review item.
|
||||
*/
|
||||
export const getReviewTitle = (review: FrigateReview): string => {
|
||||
// Frigate flags Frigate+ verified detections by suffixing the object label
|
||||
// with `-verified`. The user-meaningful identification (e.g. species) lives
|
||||
// in `sub_labels` instead, so strip the suffix and surface sub_labels as a
|
||||
// tag separated by ': ' (matching event title formatting).
|
||||
const objects = review.data.objects?.length
|
||||
? review.data.objects.map((o) => prettifyTitle(o)).join(', ')
|
||||
? review.data.objects
|
||||
.map((o) => prettifyTitle(o.replace(/-verified$/, '')))
|
||||
.join(', ')
|
||||
: '';
|
||||
const subLabels = review.data.sub_labels?.length
|
||||
? review.data.sub_labels.map((s) => prettifyTitle(s)).join(', ')
|
||||
: '';
|
||||
|
||||
if (objects) {
|
||||
return objects;
|
||||
if (objects && subLabels) {
|
||||
return `${objects}: ${subLabels}`;
|
||||
}
|
||||
if (objects || subLabels) {
|
||||
return objects || subLabels;
|
||||
}
|
||||
|
||||
const durationSeconds = Math.round(
|
||||
@@ -121,7 +133,7 @@ export const getReviewTitle = (review: FrigateReview): string => {
|
||||
|
||||
return `${formatDateAndTime(
|
||||
new Date(review.start_time * 1000),
|
||||
)} [${durationSeconds}s${objects}]`;
|
||||
)} [${durationSeconds}s]`;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -146,6 +146,7 @@ describe('frigate requests', () => {
|
||||
instance_id: 'clientID',
|
||||
cameras: ['camera.office'],
|
||||
labels: ['person'],
|
||||
sub_labels: ['John'],
|
||||
zones: ['zone'],
|
||||
after: 0,
|
||||
before: 1,
|
||||
@@ -163,6 +164,7 @@ describe('frigate requests', () => {
|
||||
instance_id: 'clientID',
|
||||
cameras: ['camera.office'],
|
||||
labels: ['person'],
|
||||
sub_labels: ['John'],
|
||||
zones: ['zone'],
|
||||
after: 0,
|
||||
before: 1,
|
||||
|
||||
@@ -195,6 +195,43 @@ describe('getReviewTitle', () => {
|
||||
).toBe('Person, Dog');
|
||||
});
|
||||
|
||||
it('should append sub_labels as tags after objects', () => {
|
||||
expect(
|
||||
getReviewTitle(
|
||||
createFrigateReview({
|
||||
data: {
|
||||
objects: ['bird-verified'],
|
||||
sub_labels: ['Mourning Dove'],
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toBe('Bird: Mourning Dove');
|
||||
});
|
||||
|
||||
it('should strip -verified suffix from objects', () => {
|
||||
expect(
|
||||
getReviewTitle(
|
||||
createFrigateReview({
|
||||
data: {
|
||||
objects: ['bird-verified', 'person'],
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toBe('Bird, Person');
|
||||
});
|
||||
|
||||
it('should fall back to sub_labels when objects are absent', () => {
|
||||
expect(
|
||||
getReviewTitle(
|
||||
createFrigateReview({
|
||||
data: {
|
||||
sub_labels: ['John'],
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toBe('John');
|
||||
});
|
||||
|
||||
it('should get in-progress review title', () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(add(start, { seconds: 60 }));
|
||||
|
||||
Reference in New Issue
Block a user