fix: Timeline window should match selected events for media views (#1555)

This commit is contained in:
Dermot Duffy
2024-09-21 15:39:18 -07:00
committed by GitHub
parent 120a1c8fb8
commit 7fd6bc6bee
2 changed files with 67 additions and 34 deletions
+29 -21
View File
@@ -245,7 +245,6 @@ export class ViewFactory {
} else { } else {
switch (view.view) { switch (view.view) {
case 'live': case 'live':
this._setTimelineWindowToLive(view);
if (config.live.controls.thumbnails.mode !== 'none') { if (config.live.controls.thumbnails.mode !== 'none') {
await executeMediaQuery( await executeMediaQuery(
config.live.controls.thumbnails.media_type === 'recordings' config.live.controls.thumbnails.media_type === 'recordings'
@@ -282,6 +281,7 @@ export class ViewFactory {
} }
} }
this._setOrRemoveTimelineWindow(view);
this._setOrRemoveSeekTime( this._setOrRemoveSeekTime(
view, view,
options?.queryExecutorOptions?.selectResult?.time?.time, options?.queryExecutorOptions?.selectResult?.time?.time,
@@ -289,29 +289,37 @@ export class ViewFactory {
return view; return view;
} }
protected _setTimelineWindowToLive(view: View): void { protected _setOrRemoveTimelineWindow(view: View): void {
const now = new Date(); if (view.is('live')) {
const liveConfig = this._api.getConfigManager().getConfig()?.live; // For live views, always force the timeline to now, regardless of
// presence or not of events.
const now = new Date();
const liveConfig = this._api.getConfigManager().getConfig()?.live;
/* istanbul ignore if: this if branch cannot be reached as if the config is /* istanbul ignore if: this if branch cannot be reached as if the config is
empty this function is never called -- @preserve */ empty this function is never called -- @preserve */
if (!liveConfig) { if (!liveConfig) {
return; return;
} }
view.mergeInContext({ view.mergeInContext({
// Force the window to start at the most recent time, not // Force the window to start at the most recent time, not
// necessarily when the most recent event/recording was: // necessarily when the most recent event/recording was:
// https://github.com/dermotduffy/frigate-hass-card/issues/1301 // https://github.com/dermotduffy/frigate-hass-card/issues/1301
timeline: { timeline: {
window: { window: {
start: sub(now, { start: sub(now, {
seconds: liveConfig.controls.timeline.window_seconds, seconds: liveConfig.controls.timeline.window_seconds,
}), }),
end: now, end: now,
},
}, },
}, });
}); } else {
// For non-live views stick to default timeline behavior (will select and
// scroll to event).
view.removeContextProperty('timeline', 'window');
}
} }
protected _setOrRemoveSeekTime(view: View, time?: Date): void { protected _setOrRemoveSeekTime(view: View, time?: Date): void {
+38 -13
View File
@@ -17,6 +17,7 @@ import {
createCardAPI, createCardAPI,
createConfig, createConfig,
createStore, createStore,
createView,
} from '../../test-utils'; } from '../../test-utils';
import { createPopulatedAPI } from './test-utils'; import { createPopulatedAPI } from './test-utils';
@@ -340,22 +341,46 @@ describe('getViewByParametersWithNewQuery', () => {
vi.useRealTimers(); vi.useRealTimers();
}); });
it('should set timeline window', async () => { describe('should set timeline window', async () => {
const executor = mock<QueryExecutor>(); it('should set timeline to now for live views', async () => {
const factory = new ViewFactory(createPopulatedAPI(), executor); const executor = mock<QueryExecutor>();
const view = await factory.getViewByParametersWithNewQuery({ const factory = new ViewFactory(createPopulatedAPI(), executor);
params: { const view = await factory.getViewByParametersWithNewQuery({
view: 'live', params: {
}, view: 'live',
},
});
expect(view?.context).toEqual({
timeline: {
window: {
start: new Date('2024-07-21T12:22:06.000Z'),
end: new Date('2024-07-21T13:22:06.000Z'),
},
},
});
}); });
expect(view?.context).toEqual({ it('should unset timeline for non-live views', async () => {
timeline: { const executor = mock<QueryExecutor>();
window: { const factory = new ViewFactory(createPopulatedAPI(), executor);
start: new Date('2024-07-21T12:22:06.000Z'), const view = await factory.getViewByParametersWithNewQuery({
end: new Date('2024-07-21T13:22:06.000Z'), baseView: createView({
context: {
timeline: {
window: {
start: new Date('2024-07-21T12:22:06.000Z'),
end: new Date('2024-07-21T13:22:06.000Z'),
},
},
},
}),
params: {
view: 'clip',
}, },
}, });
expect(view?.context).toEqual({ timeline: {} });
}); });
}); });