From cfdf0a429bd063ecb0e467f9fa8926eddd277008 Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Wed, 12 Oct 2022 17:58:36 -0700 Subject: [PATCH] Add optional prevention of playing a clip on snapshot click --- README.md | 2 ++ src/components/viewer.ts | 3 ++- src/const.ts | 2 ++ src/editor.ts | 5 +++++ src/localize/languages/en.json | 1 + src/performance.ts | 4 ++++ src/types.ts | 19 ++++++++++++++++--- 7 files changed, 32 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9b90c3dd..f5954a61 100644 --- a/README.md +++ b/README.md @@ -463,6 +463,7 @@ See the [fully expanded Media viewer configuration example](#config-expanded-med | `auto_unmute` | `never` | :heavy_multiplication_x: | Whether to automatically unmute events. `never` will never automatically unmute, `selected` will automatically unmute when an event is selected in the carousel, `visible` will automatically unmute when the browser/tab becomes visible or `all` on any opportunity to automatically unmute (i.e. either case). Note that some browsers will not allow automated unmute until the user has interacted with the page in some way -- if the user has not then the browser may pause the media instead.| | `lazy_load` | `true` | :heavy_multiplication_x: | Whether or not to lazily load media in the Media viewer carousel. Setting this will false will fetch all media immediately which may make the carousel experience smoother at a cost of (potentially) a substantial number of simultaneous media fetches on load. | | `draggable` | `true` | :heavy_multiplication_x: | Whether or not the Media viewer carousel can be dragged left or right, via touch/swipe and mouse dragging. | +| `snapshot_click_plays_clip` | `true` | :heavy_multiplication_x: | Whether clicking on a snapshot in the media viewer should play a related clip. | | `transition_effect` | `slide` | :heavy_multiplication_x: | Effect to apply as a transition between event media. Accepted values: `slide` or `none`. | | `controls` | | :heavy_multiplication_x: | Configuration for the Media viewer controls. See below. | | `actions` | | :heavy_multiplication_x: | Actions to use for all views that use the `media_viewer` (e.g. `clip`, `snapshot`). See [actions](#actions) below.| @@ -1523,6 +1524,7 @@ media_viewer: auto_unmute: never lazy_load: true draggable: true + snapshot_click_plays_clip: true transition_effect: slide controls: next_previous: diff --git a/src/components/viewer.ts b/src/components/viewer.ts index 5e1b7ed1..ec3e0c1e 100644 --- a/src/components/viewer.ts +++ b/src/components/viewer.ts @@ -793,7 +793,8 @@ export class FrigateCardViewerCarousel extends LitElement { if ( this._refMediaCarousel.value ?.frigateCardCarousel() - ?.carouselClickAllowed() + ?.carouselClickAllowed() && + this.viewerConfig?.snapshot_click_plays_clip ) { this._findRelatedClipView(mediaToRender).then((view) => { if (view) { diff --git a/src/const.ts b/src/const.ts index 5468ea2e..b0db79f8 100644 --- a/src/const.ts +++ b/src/const.ts @@ -68,6 +68,8 @@ export const CONF_MEDIA_VIEWER_AUTO_MUTE = `${CONF_MEDIA_VIEWER}.auto_mute` as c export const CONF_MEDIA_VIEWER_AUTO_UNMUTE = `${CONF_MEDIA_VIEWER}.auto_unmute` as const; export const CONF_MEDIA_VIEWER_DRAGGABLE = `${CONF_MEDIA_VIEWER}.draggable` as const; export const CONF_MEDIA_VIEWER_LAZY_LOAD = `${CONF_MEDIA_VIEWER}.lazy_load` as const; +export const CONF_MEDIA_VIEWER_SNAPSHOT_CLICK_PLAYS_CLIP = + `${CONF_MEDIA_VIEWER}.snapshot_click_plays_clip` as const; export const CONF_MEDIA_VIEWER_TRANSITION_EFFECT = `${CONF_MEDIA_VIEWER}.transition_effect` as const; export const CONF_MEDIA_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE = diff --git a/src/editor.ts b/src/editor.ts index 4c682108..ef0c0002 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -75,6 +75,7 @@ import { CONF_MEDIA_VIEWER_AUTO_PAUSE, CONF_MEDIA_VIEWER_AUTO_PLAY, CONF_MEDIA_VIEWER_AUTO_UNMUTE, + CONF_MEDIA_VIEWER_SNAPSHOT_CLICK_PLAYS_CLIP, CONF_MEDIA_VIEWER_CONTROLS_NEXT_PREVIOUS_SIZE, CONF_MEDIA_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE, CONF_MEDIA_VIEWER_CONTROLS_THUMBNAILS_MODE, @@ -1650,6 +1651,10 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor CONF_MEDIA_VIEWER_TRANSITION_EFFECT, this._transitionEffects, )} + ${this._renderSwitch( + CONF_MEDIA_VIEWER_SNAPSHOT_CLICK_PLAYS_CLIP, + this._defaults.media_viewer.snapshot_click_plays_clip, + )} ${this._putInSubmenu( MENU_MEDIA_VIEWER_CONTROLS, true, diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json index 92491f85..d296043b 100644 --- a/src/localize/languages/en.json +++ b/src/localize/languages/en.json @@ -182,6 +182,7 @@ "auto_pause": "Automatically pause media", "auto_play": "Automatically play media", "auto_unmute": "Automatically unmute media", + "snapshot_click_plays_clip": "Clicking on a snapshot plays a related clip", "controls": { "editor_label": "Media Viewer Controls" }, diff --git a/src/performance.ts b/src/performance.ts index d59e5132..a3cdc340 100644 --- a/src/performance.ts +++ b/src/performance.ts @@ -25,6 +25,7 @@ import { CONF_MEDIA_VIEWER_AUTO_MUTE, CONF_MEDIA_VIEWER_AUTO_PAUSE, CONF_MEDIA_VIEWER_AUTO_PLAY, + CONF_MEDIA_VIEWER_SNAPSHOT_CLICK_PLAYS_CLIP, CONF_MEDIA_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE, CONF_MEDIA_VIEWER_CONTROLS_THUMBNAILS_MODE, CONF_MEDIA_VIEWER_CONTROLS_THUMBNAILS_SHOW_DETAILS, @@ -122,6 +123,9 @@ const LOW_PROFILE_DEFAULTS = { // Disable all expensive CSS features. [CONF_PERFORMANCE_STYLE_BORDER_RADIUS]: false, [CONF_PERFORMANCE_STYLE_BOX_SHADOW]: false, + + // Clicking on a snapshot should not play a clip. + [CONF_MEDIA_VIEWER_SNAPSHOT_CLICK_PLAYS_CLIP]: false, }; const LOW_PROFILE_CAMERA_DEFAULTS = { diff --git a/src/types.ts b/src/types.ts index e7239ddb..77d58d28 100644 --- a/src/types.ts +++ b/src/types.ts @@ -52,7 +52,14 @@ export type FrigateCardUserSpecifiedView = typeof FRIGATE_CARD_VIEWS_USER_SPECIFIED[number]; export const FRIGATE_CARD_VIEW_DEFAULT = 'live' as const; -const FRIGATE_MENU_STYLES = ['none', 'hidden', 'overlay', 'hover', 'hover-card', 'outside'] as const; +const FRIGATE_MENU_STYLES = [ + 'none', + 'hidden', + 'overlay', + 'hover', + 'hover-card', + 'outside', +] as const; const FRIGATE_MENU_POSITIONS = ['left', 'right', 'top', 'bottom'] as const; const FRIGATE_MENU_ALIGNMENTS = FRIGATE_MENU_POSITIONS; @@ -700,7 +707,7 @@ export type TimelineCoreConfig = z.infer; const miniTimelineConfigDefault = { ...timelineCoreConfigDefault, mode: 'none' as const, -} +}; const miniTimelineConfigSchema = timelineCoreConfigSchema.extend({ mode: z.enum(['none', 'above', 'below']).default(miniTimelineConfigDefault.mode), }); @@ -981,6 +988,7 @@ const viewerConfigDefault = { lazy_load: true, draggable: true, transition_effect: 'slide' as const, + snapshot_click_plays_clip: true, controls: { next_previous: { size: 48, @@ -1031,6 +1039,9 @@ const viewerConfigSchema = z transition_effect: transitionEffectConfigSchema.default( viewerConfigDefault.transition_effect, ), + snapshot_click_plays_clip: z + .boolean() + .default(viewerConfigDefault.snapshot_click_plays_clip), controls: z .object({ next_previous: viewerNextPreviousControlConfigSchema.default( @@ -1057,7 +1068,9 @@ const viewerConfigSchema = z ), }) .default(viewerConfigDefault.controls.thumbnails), - timeline: miniTimelineConfigSchema.default(viewerConfigDefault.controls.timeline), + timeline: miniTimelineConfigSchema.default( + viewerConfigDefault.controls.timeline, + ), title: titleControlConfigSchema .extend({ mode: titleControlConfigSchema.shape.mode.default(