- Add support for Frigate reviews / detections. - Add support for GenAI metadata. - Significant internal refactor to more flexible "UnifiedQuery" to allow mixing cameras with simple metadata and review metadata (e.g. a timeline view of a Frigate camera with reviews, and a Reolink camera with simple metadata). - Add support for folder media as camera media. There are a few more PRs to commit prior to this going live, but commiting this for now due to the scale of the change. BREAKING CHANGE: `media_type` and `events_type` are retired under `live`, `viewer` and `timeline` configuration sections, instead media type is associated (once) with the camera under `media`.
211 lines
5.4 KiB
SCSS
211 lines
5.4 KiB
SCSS
@use 'vis-timeline/dist/vis-timeline-graph2d.css';
|
|
@use 'drawer';
|
|
@use 'const.scss';
|
|
|
|
:host {
|
|
width: 100%;
|
|
// Share the screen space with thumbnails that may be above/below.
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
// So that absolute sidedrawer is relative to this host.
|
|
position: relative;
|
|
|
|
background-color: var(--advanced-camera-card-timeline-background);
|
|
}
|
|
|
|
:host(:not([mini])) {
|
|
// Timeline covers 100% of the parent unless it's in mini-mode.
|
|
height: 100%;
|
|
}
|
|
|
|
advanced-camera-card-thumbnail {
|
|
height: var(--advanced-camera-card-thumbnail-size);
|
|
width: var(--advanced-camera-card-thumbnail-size);
|
|
}
|
|
advanced-camera-card-thumbnail[details] {
|
|
width: var(--advanced-camera-card-thumbnail-details-width);
|
|
}
|
|
|
|
div.timeline {
|
|
flex: 1;
|
|
}
|
|
|
|
.vis-text {
|
|
color: var(--advanced-camera-card-timeline-text-color) !important;
|
|
}
|
|
|
|
.vis-timeline {
|
|
border: none;
|
|
}
|
|
|
|
.vis-labelset .vis-label {
|
|
// Group labels.
|
|
color: var(--advanced-camera-card-timeline-text-color);
|
|
}
|
|
|
|
:host([ribbon]:not([groups])) .vis-item:not(.vis-background) {
|
|
// When a ribbon timeline is used without groups, we need to add extra margin
|
|
// to the top to center the bar vertically within the mini-timeline.
|
|
margin-top: 7px;
|
|
}
|
|
|
|
:host([ribbon]) .vis-item:not(.vis-background) {
|
|
// Ribbon timelines have a much shorter 'bar'.
|
|
height: 6px;
|
|
}
|
|
.vis-item {
|
|
border-color: var(--advanced-camera-card-timeline-item-color);
|
|
background: none;
|
|
color: var(--advanced-camera-card-timeline-text-color);
|
|
background-color: var(--advanced-camera-card-timeline-item-color);
|
|
|
|
transition:
|
|
background-color ease-in-out 1s,
|
|
border-color ease-in-out 1s,
|
|
box-shadow ease-in-out 1s;
|
|
}
|
|
.vis-item[data-severity='high'] {
|
|
border-color: var(--advanced-camera-card-timeline-item-severity-high-color);
|
|
background-color: var(--advanced-camera-card-timeline-item-severity-high-color);
|
|
}
|
|
.vis-item[data-severity='medium'] {
|
|
border-color: var(--advanced-camera-card-timeline-item-severity-medium-color);
|
|
background-color: var(--advanced-camera-card-timeline-item-severity-medium-color);
|
|
}
|
|
.vis-item[data-severity='low'] {
|
|
border-color: var(--advanced-camera-card-timeline-item-severity-low-color);
|
|
background-color: var(--advanced-camera-card-timeline-item-severity-low-color);
|
|
}
|
|
.vis-item.vis-selected {
|
|
border-color: var(--advanced-camera-card-active-color);
|
|
background-color: var(--advanced-camera-card-active-color);
|
|
box-shadow: var(
|
|
--advanced-camera-card-box-shadow-override,
|
|
0px 0px 5px 1px var(--advanced-camera-card-active-color)
|
|
);
|
|
}
|
|
.vis-item.vis-background {
|
|
background-color: var(--advanced-camera-card-timeline-background-item-color);
|
|
}
|
|
|
|
// If there are no timeline groups shown (e.g. mini mode with a single camera),
|
|
// ensure the background (recordings) always span the full height. Otherwise, in
|
|
// cases where there are no events, the background is incorrectly rendered too
|
|
// short by visjs.
|
|
:host(:not([groups])) .vis-item.vis-background {
|
|
min-height: 100%;
|
|
}
|
|
|
|
.vis-item:not(.vis-background) {
|
|
cursor: pointer;
|
|
}
|
|
:host([recordings]) .vis-item.vis-background,
|
|
:host([recordings]) .vis-time-axis {
|
|
cursor: crosshair;
|
|
}
|
|
.vis-item:active {
|
|
cursor: unset;
|
|
}
|
|
|
|
.vis-item.vis-box {
|
|
border: none;
|
|
}
|
|
|
|
.vis-item .vis-item-content {
|
|
padding: 0px;
|
|
}
|
|
|
|
.vis-item.vis-cluster {
|
|
border-style: dotted;
|
|
color: var(--advanced-camera-card-timeline-text-color);
|
|
background-color: var(--advanced-camera-card-timeline-background);
|
|
box-shadow: var(
|
|
--advanced-camera-card-box-shadow-override,
|
|
0px 0px 5px 1px var(--advanced-camera-card-timeline-item-color)
|
|
);
|
|
}
|
|
.vis-item.vis-range {
|
|
border-radius: var(--advanced-camera-card-border-radius-final);
|
|
}
|
|
|
|
.vis-time-axis .vis-grid.vis-minor {
|
|
border-color: var(--advanced-camera-card-timeline-divider-color);
|
|
}
|
|
|
|
// Give an indication that the user can interact with the axes.
|
|
.vis-text.vis-minor,
|
|
.vis-label {
|
|
transition: background-color 0.5s ease-out;
|
|
}
|
|
:host([recordings]) .vis-text.vis-minor:hover {
|
|
background-color: color-mix(
|
|
in oklab,
|
|
var(--advanced-camera-card-timeline-text-color),
|
|
transparent 80%
|
|
);
|
|
}
|
|
|
|
.vis-time-axis .vis-grid.vis-major {
|
|
border-color: var(--advanced-camera-card-timeline-divider-color);
|
|
}
|
|
|
|
.vis-label {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
div.vis-tooltip {
|
|
padding: 0px;
|
|
background-color: unset;
|
|
border: none;
|
|
|
|
// Use browser default font-family for tooltips.
|
|
font-family: unset;
|
|
|
|
z-index: 30;
|
|
}
|
|
|
|
.target_bar {
|
|
background-color: var(--advanced-camera-card-timeline-target-bar-color);
|
|
width: 2px;
|
|
|
|
z-index: 20;
|
|
|
|
// Prevent the mouse interacting with the custom time.
|
|
pointer-events: none;
|
|
}
|
|
.target_bar .vis-custom-time-marker {
|
|
background-color: var(--advanced-camera-card-timeline-background);
|
|
color: var(--advanced-camera-card-timeline-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 {
|
|
display: inline-flex;
|
|
position: absolute;
|
|
right: 0px;
|
|
bottom: 0px;
|
|
color: var(--advanced-camera-card-timeline-tool-color);
|
|
z-index: 10;
|
|
}
|
|
.timeline-tools * {
|
|
margin: 2px 5px;
|
|
cursor: pointer;
|
|
}
|
|
.timeline-tools *:last-child {
|
|
margin-right: 10px;
|
|
}
|