Add label to timeline marker with current time.
This commit is contained in:
@@ -19,7 +19,7 @@ import isEqual from 'lodash-es/isEqual';
|
|||||||
import throttle from 'lodash-es/throttle';
|
import throttle from 'lodash-es/throttle';
|
||||||
import { ViewContext } from 'view';
|
import { ViewContext } from 'view';
|
||||||
import { DataSet } from 'vis-data/esnext';
|
import { DataSet } from 'vis-data/esnext';
|
||||||
import type { DataGroupCollectionType, IdType } from 'vis-timeline/esnext';
|
import type { DataGroupCollectionType, DateType, IdType } from 'vis-timeline/esnext';
|
||||||
import {
|
import {
|
||||||
Timeline,
|
Timeline,
|
||||||
TimelineEventPropertiesResult,
|
TimelineEventPropertiesResult,
|
||||||
@@ -46,6 +46,7 @@ import { stopEventFromActivatingCardWideActions } from '../utils/action';
|
|||||||
import {
|
import {
|
||||||
contentsChanged,
|
contentsChanged,
|
||||||
dispatchFrigateCardEvent,
|
dispatchFrigateCardEvent,
|
||||||
|
formatDateAndTime,
|
||||||
isHoverableDevice,
|
isHoverableDevice,
|
||||||
setOrRemoveAttribute,
|
setOrRemoveAttribute,
|
||||||
} from '../utils/basic';
|
} from '../utils/basic';
|
||||||
@@ -89,6 +90,11 @@ declare module 'view' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ExtendedTimeline extends Timeline {
|
||||||
|
// setCustomTimeMarker currently missing from Timeline types.
|
||||||
|
setCustomTimeMarker?(time: DateType, id?: IdType): void;
|
||||||
|
}
|
||||||
|
|
||||||
// An event used to fetch data required for thumbnail rendering. See special
|
// An event used to fetch data required for thumbnail rendering. See special
|
||||||
// note below on why this is necessary.
|
// note below on why this is necessary.
|
||||||
interface ThumbnailDataRequest {
|
interface ThumbnailDataRequest {
|
||||||
@@ -206,8 +212,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
|
|
||||||
protected _refDatePicker: Ref<FrigateCardDatePicker> = createRef();
|
protected _refDatePicker: Ref<FrigateCardDatePicker> = createRef();
|
||||||
protected _refTimeline: Ref<HTMLElement> = createRef();
|
protected _refTimeline: Ref<HTMLElement> = createRef();
|
||||||
|
protected _timeline?: ExtendedTimeline;
|
||||||
protected _timeline?: Timeline;
|
|
||||||
|
|
||||||
protected _timelineSource: TimelineDataSource | null = null;
|
protected _timelineSource: TimelineDataSource | null = null;
|
||||||
|
|
||||||
@@ -417,6 +422,22 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
} else {
|
} else {
|
||||||
this._timeline?.setCustomTime(targetTime, TIMELINE_TARGET_BAR_ID);
|
this._timeline?.setCustomTime(targetTime, TIMELINE_TARGET_BAR_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const window = this._timeline.getWindow();
|
||||||
|
const markerProportion =
|
||||||
|
(targetTime.getTime() - window.start.getTime()) /
|
||||||
|
(window.end.getTime() - window.start.getTime());
|
||||||
|
|
||||||
|
// Position the marker proportionally to how 'far' the pointer is being
|
||||||
|
// held relative to the timeline window.
|
||||||
|
this.setAttribute(
|
||||||
|
'target-bar-marker-direction',
|
||||||
|
markerProportion < 0.25 ? 'right' : markerProportion > 0.75 ? 'left' : 'center',
|
||||||
|
);
|
||||||
|
this._timeline?.setCustomTimeMarker?.(
|
||||||
|
formatDateAndTime(targetTime, true),
|
||||||
|
TIMELINE_TARGET_BAR_ID,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this._removeTargetBar();
|
this._removeTargetBar();
|
||||||
}
|
}
|
||||||
@@ -426,6 +447,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
* Remove the target bar.
|
* Remove the target bar.
|
||||||
*/
|
*/
|
||||||
protected _removeTargetBar(): void {
|
protected _removeTargetBar(): void {
|
||||||
|
this.removeAttribute('target-bar-direction');
|
||||||
if (this._targetBarVisible) {
|
if (this._targetBarVisible) {
|
||||||
this._timeline?.removeCustomTime(TIMELINE_TARGET_BAR_ID);
|
this._timeline?.removeCustomTime(TIMELINE_TARGET_BAR_ID);
|
||||||
this._targetBarVisible = false;
|
this._targetBarVisible = false;
|
||||||
@@ -463,12 +485,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
: results
|
: results
|
||||||
.clone()
|
.clone()
|
||||||
.resetSelectedResult()
|
.resetSelectedResult()
|
||||||
.selectBestResult((media) =>
|
.selectBestResult((media) => findBestMediaIndex(media, targetTime));
|
||||||
findBestMediaIndex(
|
|
||||||
media,
|
|
||||||
targetTime,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
const desiredView: FrigateCardView = this.mini
|
const desiredView: FrigateCardView = this.mini
|
||||||
? targetTime >= new Date()
|
? targetTime >= new Date()
|
||||||
|
|||||||
@@ -144,13 +144,30 @@ div.vis-tooltip {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.target_bar {
|
.target_bar {
|
||||||
border-left: 2px solid var(--primary-color);
|
background-color: var(--primary-color);
|
||||||
opacity: 0.7;
|
width: 2px;
|
||||||
box-shadow: var(--frigate-card-css-box-shadow, 0px 0px 3px 1px var(--primary-color));
|
|
||||||
|
z-index: 20;
|
||||||
|
|
||||||
// Prevent the mouse interacting with the custom time.
|
// Prevent the mouse interacting with the custom time.
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
.target_bar .vis-custom-time-marker {
|
||||||
|
background-color: var(--primary-background-color);
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
bottom: 0px;
|
||||||
|
top: unset;
|
||||||
|
}
|
||||||
|
:host([target-bar-marker-direction='right']) .target_bar .vis-custom-time-marker {
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
:host([target-bar-marker-direction='left']) .target_bar .vis-custom-time-marker {
|
||||||
|
right: 2px;
|
||||||
|
}
|
||||||
|
:host([target-bar-marker-direction='center']) .target_bar .vis-custom-time-marker {
|
||||||
|
left: 0px;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
.timeline-tools {
|
.timeline-tools {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -162,4 +179,4 @@ div.vis-tooltip {
|
|||||||
|
|
||||||
.timeline-tools ha-icon {
|
.timeline-tools ha-icon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -114,8 +114,8 @@ export const isHoverableDevice = (): boolean =>
|
|||||||
* @param date A Date object.
|
* @param date A Date object.
|
||||||
* @returns A date and time.
|
* @returns A date and time.
|
||||||
*/
|
*/
|
||||||
export const formatDateAndTime = (date: Date): string => {
|
export const formatDateAndTime = (date: Date, includeSeconds?: boolean): string => {
|
||||||
return format(date, 'yyyy-MM-dd HH:mm');
|
return format(date, `yyyy-MM-dd HH:mm${includeSeconds ? ':ss' : ''}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
prettifyTitle,
|
prettifyTitle,
|
||||||
runWhenIdleIfSupported,
|
runWhenIdleIfSupported,
|
||||||
setify,
|
setify,
|
||||||
|
setOrRemoveAttribute,
|
||||||
sleep,
|
sleep,
|
||||||
} from '../src/utils/basic';
|
} from '../src/utils/basic';
|
||||||
|
|
||||||
@@ -131,6 +132,10 @@ describe('formatDateAndTime', () => {
|
|||||||
const date = new Date(2023, 3, 14, 13, 35, 0);
|
const date = new Date(2023, 3, 14, 13, 35, 0);
|
||||||
expect(formatDateAndTime(date)).toBe('2023-04-14 13:35');
|
expect(formatDateAndTime(date)).toBe('2023-04-14 13:35');
|
||||||
});
|
});
|
||||||
|
it('should format date and time with seconds', () => {
|
||||||
|
const date = new Date(2023, 3, 14, 13, 35, 1);
|
||||||
|
expect(formatDateAndTime(date, true)).toBe('2023-04-14 13:35:01');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('formatDate', () => {
|
describe('formatDate', () => {
|
||||||
@@ -220,3 +225,18 @@ describe('isValidDate', () => {
|
|||||||
expect(isValidDate(new Date('moo'))).toBeFalsy();
|
expect(isValidDate(new Date('moo'))).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('setOrRemoveAttribute', () => {
|
||||||
|
it('should set attribute', () => {
|
||||||
|
const element = document.createElement('div');
|
||||||
|
setOrRemoveAttribute(element, true, 'key', 'value');
|
||||||
|
expect(element.getAttribute('key')).toBe('value');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove attribute date', () => {
|
||||||
|
const element = document.createElement('div');
|
||||||
|
element.setAttribute('key', 'value');
|
||||||
|
setOrRemoveAttribute(element, false, 'key');
|
||||||
|
expect(element.getAttribute('key')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user