Add support for timeline seeking locked to a camera.
This commit is contained in:
@@ -854,6 +854,17 @@ timeline:
|
||||
|
||||
<a name="dimensions"></a>
|
||||
|
||||
#### Timeline Seek Behavior
|
||||
|
||||
The behavior of the timeline during seeking/dragging can be controlled by means of the icon on the bottom-right of the timeline.
|
||||
|
||||
| Option | Behavior |
|
||||
| - | - |
|
||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>filmstrip-box-multiple</title><path d="M4,6H2V20A2,2 0 0,0 4,22H18V20H4V6M20,2H8A2,2 0 0,0 6,4V16A2,2 0 0,0 8,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M10,15H8V13H10V15M10,11H8V9H10V11M10,7H8V5H10V7M20,15H18V13H20V15M20,11H18V9H20V11M20,7H18V5H20V7Z" /></svg> | Dragging the timeline will seek / select across all available media from all cameras, selecting the media item with the longest duration whilst favoring (but not limited to) the currently selected camera. |
|
||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>play-box-lock</title><path d="M23 17.3V20.8C23 21.4 22.4 22 21.7 22H16.2C15.6 22 15 21.4 15 20.7V17.2C15 16.6 15.6 16 16.2 16V14.5C16.2 13.1 17.6 12 19 12C20.4 12 21.8 13.1 21.8 14.5V16C22.4 16 23 16.6 23 17.3M13 19V21H4C2.89 21 2 20.1 2 19V5C2 3.89 2.89 3 4 3H18C19.1 3 20 3.89 20 5V10.1L19 10L18 10.1C15.79 10.55 14.12 12.45 14 14.76C13.39 15.31 13 16.11 13 17V19M20.5 14.5C20.5 13.7 19.8 13.2 19 13.2C18.2 13.2 17.5 13.7 17.5 14.5V16H20.5V14.5M9 8V16L14 12L9 8Z" /></svg> | Dragging the timeline will seek within the selected media item only. |
|
||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>camera-lock</title><path d="M4 4H7L9 2H15L17 4H20C21.11 4 22 4.89 22 6V12C21.16 11.37 20.13 11 19 11C18.21 11 17.46 11.18 16.79 11.5C16.18 9.22 14.27 7 12 7C9.24 7 7 9.24 7 12C7 14.76 9.24 17 12 17C12.42 17 12.84 16.95 13.23 16.85C13.08 17.2 13 17.59 13 18V20H4C2.9 20 2 19.11 2 18V6C2 4.89 2.9 4 4 4M12 9C13.66 9 15 10.34 15 12C15 13.66 13.66 15 12 15C10.34 15 9 13.66 9 12C9 10.34 10.34 9 12 9M23 18.3V21.8C23 22.4 22.4 23 21.7 23H16.2C15.6 23 15 22.4 15 21.7V18.2C15 17.6 15.6 17 16.2 17V15.5C16.2 14.1 17.6 13 19 13C20.4 13 21.8 14.1 21.8 15.5V17C22.4 17 23 17.6 23 18.3M20.5 15.5C20.5 14.7 19.8 14.2 19 14.2C18.2 14.2 17.5 14.7 17.5 15.5V17H20.5V15.5Z" /></svg> | Dragging the timeline will seek / select across all available media from the selected camera only, selecting the media item with the longest duration. |
|
||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>pan-horizontal</title><path d="M7,8L2.5,12L7,16V8M17,8V16L21.5,12L17,8M12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12A2,2 0 0,0 12,10Z" /></svg> | Dragging the timeline will pan only without selected or seeking any media. |
|
||||
|
||||
### Dimensions Options
|
||||
|
||||
These options control the aspect-ratio of the entire card to make placement in
|
||||
|
||||
@@ -63,6 +63,7 @@ import {
|
||||
MediaQueriesClassifier,
|
||||
MediaQueriesType,
|
||||
} from '../view/media-queries-classifier';
|
||||
import { MediaQueriesResults } from '../view/media-queries-results';
|
||||
import { View } from '../view/view';
|
||||
import './date-picker.js';
|
||||
import { DatePickerEvent, FrigateCardDatePicker } from './date-picker.js';
|
||||
@@ -85,7 +86,7 @@ interface TimelineViewContext {
|
||||
}
|
||||
|
||||
type TimelineItemClickAction = 'play' | 'select';
|
||||
type TimelinePanBehavior = 'pan' | 'seek' | 'seek-in-media';
|
||||
type TimelinePanBehavior = 'pan' | 'seek' | 'seek-in-media' | 'seek-in-camera';
|
||||
|
||||
declare module 'view' {
|
||||
interface ViewContext {
|
||||
@@ -288,13 +289,17 @@ export class FrigateCardTimelineCore extends LitElement {
|
||||
? localize('timeline.pan_behavior.pan')
|
||||
: this._panBehavior === 'seek'
|
||||
? localize('timeline.pan_behavior.seek')
|
||||
: localize('timeline.pan_behavior.seek-in-media');
|
||||
: this._panBehavior === 'seek-in-media'
|
||||
? localize('timeline.pan_behavior.seek-in-media')
|
||||
: localize('timeline.pan_behavior.seek-in-camera');
|
||||
const panIcon =
|
||||
this._panBehavior === 'pan'
|
||||
? 'mdi:pan-horizontal'
|
||||
: this._panBehavior === 'seek'
|
||||
? 'mdi:filmstrip'
|
||||
: 'mdi:lock';
|
||||
? 'mdi:filmstrip-box-multiple'
|
||||
: this._panBehavior === 'seek-in-media'
|
||||
? 'mdi:play-box-lock'
|
||||
: 'mdi:camera-lock';
|
||||
|
||||
return html` ${capabilities?.supportsTimeline
|
||||
? html` <div
|
||||
@@ -314,6 +319,8 @@ export class FrigateCardTimelineCore extends LitElement {
|
||||
? 'seek'
|
||||
: this._panBehavior === 'seek'
|
||||
? 'seek-in-media'
|
||||
: this._panBehavior === 'seek-in-media'
|
||||
? 'seek-in-camera'
|
||||
: 'pan';
|
||||
}}
|
||||
aria-label="${panTitle}"
|
||||
@@ -406,10 +413,13 @@ export class FrigateCardTimelineCore extends LitElement {
|
||||
const targetBarOn =
|
||||
this._shouldSupportSeeking() &&
|
||||
(this._panBehavior === 'seek' ||
|
||||
this._panBehavior === 'seek-in-camera' ||
|
||||
(this._panBehavior === 'seek-in-media' &&
|
||||
this._timeline.getSelection().some((id) => {
|
||||
const item = this._timelineSource?.dataset?.get(id);
|
||||
return (
|
||||
this._panBehavior !== 'seek-in-camera' ||
|
||||
item?.media?.getCameraID() === this.view?.camera,
|
||||
item &&
|
||||
item.start &&
|
||||
item.end &&
|
||||
@@ -482,19 +492,30 @@ export class FrigateCardTimelineCore extends LitElement {
|
||||
}
|
||||
|
||||
const canSeek = this._shouldSupportSeeking();
|
||||
const newResults =
|
||||
this._panBehavior === 'seek-in-media'
|
||||
? results
|
||||
: results
|
||||
let newResults: MediaQueriesResults | null = null;
|
||||
|
||||
if (this._panBehavior === 'seek') {
|
||||
newResults = results
|
||||
.clone()
|
||||
.resetSelectedResult()
|
||||
.selectBestResult(
|
||||
(media) => findBestMediaIndex(media, targetTime, this.view?.camera),
|
||||
(mediaArray) => findBestMediaIndex(mediaArray, targetTime, this.view?.camera),
|
||||
{
|
||||
allCameras: true,
|
||||
main: true,
|
||||
},
|
||||
);
|
||||
} else if (this._panBehavior === 'seek-in-camera') {
|
||||
newResults = results
|
||||
.clone()
|
||||
.resetSelectedResult()
|
||||
.selectBestResult((mediaArray) => findBestMediaIndex(mediaArray, targetTime), {
|
||||
cameraID: this.view.camera,
|
||||
})
|
||||
.promoteCameraSelectionToMainSelection(this.view.camera);
|
||||
} else if (this._panBehavior === 'seek-in-media') {
|
||||
newResults = results;
|
||||
}
|
||||
|
||||
const desiredView: FrigateCardView = this.mini
|
||||
? targetTime >= new Date()
|
||||
|
||||
@@ -516,6 +516,7 @@
|
||||
"pan_behavior": {
|
||||
"pan": "Pan",
|
||||
"seek": "Pan seeks across all media",
|
||||
"seek-in-camera": "Pan seeks within selected camera only",
|
||||
"seek-in-media": "Pan seeks within selected media item only"
|
||||
},
|
||||
"select_date": "Choose date"
|
||||
|
||||
@@ -504,6 +504,7 @@
|
||||
"pan_behavior": {
|
||||
"pan": "",
|
||||
"seek": "",
|
||||
"seek-in-camera": "",
|
||||
"seek-in-media": ""
|
||||
},
|
||||
"select_date": "Scegli la data"
|
||||
|
||||
@@ -515,6 +515,7 @@
|
||||
"pan_behavior": {
|
||||
"pan": "",
|
||||
"seek": "",
|
||||
"seek-in-camera": "",
|
||||
"seek-in-media": ""
|
||||
},
|
||||
"select_date": "Escolha a data"
|
||||
|
||||
@@ -495,9 +495,10 @@
|
||||
},
|
||||
"timeline": {
|
||||
"pan_behavior": {
|
||||
"pan": "Pan",
|
||||
"seek": "Pan seeks across all media",
|
||||
"seek-in-media": "Pan seeks within selected media item only"
|
||||
"pan": "",
|
||||
"seek": "",
|
||||
"seek-in-camera": "",
|
||||
"seek-in-media": ""
|
||||
},
|
||||
"select_date": "Selecionar a data"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user