Merge pull request #1067 from dermotduffy/click-always-plays
Improve behavior when timeline items are clicked
This commit is contained in:
@@ -144,10 +144,7 @@ export class FrigateCardSurround extends LitElement {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (this.view?.is('live')) {
|
if (this.view?.is('live')) {
|
||||||
return getAllDependentCameras(
|
return getAllDependentCameras(this.cameraManager, this.view.camera);
|
||||||
this.cameraManager,
|
|
||||||
this.view.camera,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (this.view.isViewerView()) {
|
if (this.view.isViewerView()) {
|
||||||
return new Set(
|
return new Set(
|
||||||
@@ -225,6 +222,10 @@ export class FrigateCardSurround extends LitElement {
|
|||||||
slot=${this.timelineConfig.mode}
|
slot=${this.timelineConfig.mode}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.view=${this.view}
|
.view=${this.view}
|
||||||
|
.itemClickAction=${this.view.isViewerView() ||
|
||||||
|
this.thumbnailConfig.mode === 'none'
|
||||||
|
? 'play'
|
||||||
|
: 'select'}
|
||||||
.cameraIDs=${this._cameraIDsForTimeline}
|
.cameraIDs=${this._cameraIDsForTimeline}
|
||||||
.mini=${true}
|
.mini=${true}
|
||||||
.timelineConfig=${this.timelineConfig}
|
.timelineConfig=${this.timelineConfig}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import {
|
|||||||
ExtendedHomeAssistant,
|
ExtendedHomeAssistant,
|
||||||
frigateCardConfigDefaults,
|
frigateCardConfigDefaults,
|
||||||
FrigateCardView,
|
FrigateCardView,
|
||||||
ThumbnailsControlConfig,
|
ThumbnailsControlBaseConfig,
|
||||||
TimelineCoreConfig,
|
TimelineCoreConfig,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { stopEventFromActivatingCardWideActions } from '../utils/action';
|
import { stopEventFromActivatingCardWideActions } from '../utils/action';
|
||||||
@@ -78,6 +78,8 @@ interface TimelineViewContext {
|
|||||||
window?: TimelineWindow;
|
window?: TimelineWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TimelineItemClickAction = 'play' | 'select';
|
||||||
|
|
||||||
declare module 'view' {
|
declare module 'view' {
|
||||||
interface ViewContext {
|
interface ViewContext {
|
||||||
timeline?: TimelineViewContext;
|
timeline?: TimelineViewContext;
|
||||||
@@ -173,7 +175,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
public timelineConfig?: TimelineCoreConfig;
|
public timelineConfig?: TimelineCoreConfig;
|
||||||
|
|
||||||
@property({ attribute: true, type: Boolean })
|
@property({ attribute: true, type: Boolean })
|
||||||
public thumbnailConfig?: ThumbnailsControlConfig;
|
public thumbnailConfig?: ThumbnailsControlBaseConfig;
|
||||||
|
|
||||||
// Whether or not this is a mini-timeline (in mini-mode the component takes a
|
// Whether or not this is a mini-timeline (in mini-mode the component takes a
|
||||||
// supportive role for other views).
|
// supportive role for other views).
|
||||||
@@ -191,6 +193,9 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public cardWideConfig?: CardWideConfig;
|
public cardWideConfig?: CardWideConfig;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public itemClickAction?: TimelineItemClickAction;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
protected _locked = false;
|
protected _locked = false;
|
||||||
|
|
||||||
@@ -507,6 +512,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let view: View | null = null;
|
let view: View | null = null;
|
||||||
|
let drawerAction: 'open' | 'close' = 'close';
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.timelineConfig?.show_recordings &&
|
this.timelineConfig?.show_recordings &&
|
||||||
@@ -585,23 +591,23 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
} else {
|
} else {
|
||||||
view = this.view.evolve({
|
view = this.view.evolve({
|
||||||
queryResults: newResults,
|
queryResults: newResults,
|
||||||
|
view: this.itemClickAction === 'play' ? 'media' : this.view.view,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view?.queryResults?.hasResults()) {
|
if (view?.queryResults?.hasResults()) {
|
||||||
view.mergeInContext({ mediaViewer: { seek: properties.time } });
|
view.mergeInContext({ mediaViewer: { seek: properties.time } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.itemClickAction === 'select' && view) {
|
||||||
|
drawerAction = 'open';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view) {
|
if (view) {
|
||||||
view.dispatchChangeEvent(this);
|
view.dispatchChangeEvent(this);
|
||||||
|
|
||||||
if (this.view?.is('timeline')) {
|
|
||||||
dispatchFrigateCardEvent(this, 'thumbnails:open');
|
|
||||||
}
|
|
||||||
} else if (this.view?.is('timeline')) {
|
|
||||||
dispatchFrigateCardEvent(this, 'thumbnails:close');
|
|
||||||
}
|
}
|
||||||
|
dispatchFrigateCardEvent(this, `thumbnails:${drawerAction}`);
|
||||||
|
|
||||||
this._ignoreClick = false;
|
this._ignoreClick = false;
|
||||||
}
|
}
|
||||||
@@ -1114,13 +1120,11 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
this._destroy();
|
this._destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = this._getOptions();
|
|
||||||
let createdTimeline = false;
|
let createdTimeline = false;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this._timelineSource &&
|
this._timelineSource &&
|
||||||
this._refTimeline.value &&
|
this._refTimeline.value &&
|
||||||
options &&
|
|
||||||
this.timelineConfig &&
|
this.timelineConfig &&
|
||||||
(changedProperties.has('timelineConfig') || changedProperties.has('cameraIDs'))
|
(changedProperties.has('timelineConfig') || changedProperties.has('cameraIDs'))
|
||||||
) {
|
) {
|
||||||
@@ -1139,6 +1143,8 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const options = this._getOptions();
|
||||||
|
if (options) {
|
||||||
createdTimeline = true;
|
createdTimeline = true;
|
||||||
if (this.mini && groups.length === 1) {
|
if (this.mini && groups.length === 1) {
|
||||||
// In a mini timeline, if there's only one group don't bother grouping
|
// In a mini timeline, if there's only one group don't bother grouping
|
||||||
@@ -1179,6 +1185,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
this._removeTargetBar();
|
this._removeTargetBar();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (changedProperties.has('view')) {
|
if (changedProperties.has('view')) {
|
||||||
if (createdTimeline) {
|
if (createdTimeline) {
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ export class FrigateCardTimeline extends LitElement {
|
|||||||
.thumbnailConfig=${this.timelineConfig.controls.thumbnails}
|
.thumbnailConfig=${this.timelineConfig.controls.thumbnails}
|
||||||
.cameraManager=${this.cameraManager}
|
.cameraManager=${this.cameraManager}
|
||||||
.cardWideConfig=${this.cardWideConfig}
|
.cardWideConfig=${this.cardWideConfig}
|
||||||
|
.itemClickAction=${this.timelineConfig.controls.thumbnails.mode === 'none'
|
||||||
|
? 'play'
|
||||||
|
: 'select'}
|
||||||
>
|
>
|
||||||
</frigate-card-timeline-core>
|
</frigate-card-timeline-core>
|
||||||
</frigate-card-surround>`;
|
</frigate-card-surround>`;
|
||||||
|
|||||||
+1
-1
@@ -165,7 +165,7 @@ export const CONF_LIVE_CONTROLS_THUMBNAILS_SHOW_FAVORITE_CONTROL =
|
|||||||
export const CONF_LIVE_CONTROLS_THUMBNAILS_SHOW_TIMELINE_CONTROL =
|
export const CONF_LIVE_CONTROLS_THUMBNAILS_SHOW_TIMELINE_CONTROL =
|
||||||
`${CONF_LIVE}.controls.thumbnails.show_timeline_control` as const;
|
`${CONF_LIVE}.controls.thumbnails.show_timeline_control` as const;
|
||||||
export const CONF_LIVE_CONTROLS_TIMELINE_CLUSTERING_THRESHOLD =
|
export const CONF_LIVE_CONTROLS_TIMELINE_CLUSTERING_THRESHOLD =
|
||||||
`${CONF_LIVE}.control s.timeline.clustering_threshold` as const;
|
`${CONF_LIVE}.controls.timeline.clustering_threshold` as const;
|
||||||
export const CONF_LIVE_CONTROLS_TIMELINE_MEDIA =
|
export const CONF_LIVE_CONTROLS_TIMELINE_MEDIA =
|
||||||
`${CONF_LIVE}.controls.timeline.media` as const;
|
`${CONF_LIVE}.controls.timeline.media` as const;
|
||||||
export const CONF_LIVE_CONTROLS_TIMELINE_MODE =
|
export const CONF_LIVE_CONTROLS_TIMELINE_MODE =
|
||||||
|
|||||||
+24
-11
@@ -779,8 +779,8 @@ export type ImageViewConfig = z.infer<typeof imageConfigSchema>;
|
|||||||
/**
|
/**
|
||||||
* Thumbnail controls configuration section.
|
* Thumbnail controls configuration section.
|
||||||
*/
|
*/
|
||||||
const thumbnailControlsDefaults = {
|
|
||||||
mode: 'right' as const,
|
const thumbnailControlsBaseDefaults = {
|
||||||
size: 100,
|
size: 100,
|
||||||
show_details: true,
|
show_details: true,
|
||||||
show_favorite_control: true,
|
show_favorite_control: true,
|
||||||
@@ -788,26 +788,39 @@ const thumbnailControlsDefaults = {
|
|||||||
show_download_control: true,
|
show_download_control: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const thumbnailsControlSchema = z.object({
|
// Configuration for the actual rendered thumbnail.
|
||||||
mode: z
|
const thumbnailsControlBaseSchema = z.object({
|
||||||
.enum(['none', 'above', 'below', 'left', 'right'])
|
|
||||||
.default(thumbnailControlsDefaults.mode),
|
|
||||||
size: z
|
size: z
|
||||||
.number()
|
.number()
|
||||||
.min(THUMBNAIL_WIDTH_MIN)
|
.min(THUMBNAIL_WIDTH_MIN)
|
||||||
.max(THUMBNAIL_WIDTH_MAX)
|
.max(THUMBNAIL_WIDTH_MAX)
|
||||||
.default(thumbnailControlsDefaults.size),
|
.default(thumbnailControlsBaseDefaults.size),
|
||||||
show_details: z.boolean().default(thumbnailControlsDefaults.show_details),
|
show_details: z.boolean().default(thumbnailControlsBaseDefaults.show_details),
|
||||||
show_favorite_control: z
|
show_favorite_control: z
|
||||||
.boolean()
|
.boolean()
|
||||||
.default(thumbnailControlsDefaults.show_favorite_control),
|
.default(thumbnailControlsBaseDefaults.show_favorite_control),
|
||||||
show_timeline_control: z
|
show_timeline_control: z
|
||||||
.boolean()
|
.boolean()
|
||||||
.default(thumbnailControlsDefaults.show_timeline_control),
|
.default(thumbnailControlsBaseDefaults.show_timeline_control),
|
||||||
show_download_control: z
|
show_download_control: z
|
||||||
.boolean()
|
.boolean()
|
||||||
.default(thumbnailControlsDefaults.show_download_control),
|
.default(thumbnailControlsBaseDefaults.show_download_control),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export type ThumbnailsControlBaseConfig = z.infer<typeof thumbnailsControlBaseSchema>;
|
||||||
|
|
||||||
|
// Configuration that may control the placement of the thumbnail.
|
||||||
|
const thumbnailControlsDefaults = {
|
||||||
|
...thumbnailControlsBaseDefaults,
|
||||||
|
mode: 'right' as const,
|
||||||
|
};
|
||||||
|
|
||||||
|
const thumbnailsControlSchema = thumbnailsControlBaseSchema.extend({
|
||||||
|
mode: z
|
||||||
|
.enum(['none', 'above', 'below', 'left', 'right'])
|
||||||
|
.default(thumbnailControlsDefaults.mode),
|
||||||
|
});
|
||||||
|
|
||||||
export type ThumbnailsControlConfig = z.infer<typeof thumbnailsControlSchema>;
|
export type ThumbnailsControlConfig = z.infer<typeof thumbnailsControlSchema>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user