mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 08:34:21 -06:00
Various fixes (#14786)
* Catch openvino error * Remove clip deletion * Update deletion text * Fix timeline not respecting timezone config * Tweaks * More timezone fixes * Fix * More timezone fixes * Fix shm docs
This commit is contained in:
parent
156e7cc628
commit
a13b9815f6
@ -81,15 +81,15 @@ You can calculate the **minimum** shm size for each camera with the following fo
|
||||
|
||||
```console
|
||||
# Replace <width> and <height>
|
||||
$ python -c 'print("{:.2f}MB".format((<width> * <height> * 1.5 * 10 + 270480) / 1048576))'
|
||||
$ python -c 'print("{:.2f}MB".format((<width> * <height> * 1.5 * 20 + 270480) / 1048576))'
|
||||
|
||||
# Example for 1280x720
|
||||
$ python -c 'print("{:.2f}MB".format((1280 * 720 * 1.5 * 10 + 270480) / 1048576))'
|
||||
13.44MB
|
||||
# Example for 1280x720, including logs
|
||||
$ python -c 'print("{:.2f}MB".format((1280 * 720 * 1.5 * 20 + 270480) / 1048576)) + 40'
|
||||
46.63MB
|
||||
|
||||
# Example for eight cameras detecting at 1280x720, including logs
|
||||
$ python -c 'print("{:.2f}MB".format(((1280 * 720 * 1.5 * 10 + 270480) / 1048576) * 8 + 40))'
|
||||
136.99MB
|
||||
$ python -c 'print("{:.2f}MB".format(((1280 * 720 * 1.5 * 20 + 270480) / 1048576) * 8 + 40))'
|
||||
253MB
|
||||
```
|
||||
|
||||
The shm size cannot be set per container for Home Assistant add-ons. However, this is probably not required since by default Home Assistant Supervisor allocates `/dev/shm` with half the size of your total memory. If your machine has 8GB of memory, chances are that Frigate will have access to up to 4GB without any additional configuration.
|
||||
@ -194,7 +194,7 @@ services:
|
||||
privileged: true # this may not be necessary for all setups
|
||||
restart: unless-stopped
|
||||
image: ghcr.io/blakeblackshear/frigate:stable
|
||||
shm_size: "64mb" # update for your cameras based on calculation above
|
||||
shm_size: "512mb" # update for your cameras based on calculation above
|
||||
devices:
|
||||
- /dev/bus/usb:/dev/bus/usb # Passes the USB Coral, needs to be modified for other versions
|
||||
- /dev/apex_0:/dev/apex_0 # Passes a PCIe Coral, follow driver instructions here https://coral.ai/docs/m2/get-started/#2a-on-linux
|
||||
|
@ -1042,9 +1042,6 @@ def delete_event(request: Request, event_id: str):
|
||||
media.unlink(missing_ok=True)
|
||||
media = Path(f"{os.path.join(CLIPS_DIR, media_name)}-clean.png")
|
||||
media.unlink(missing_ok=True)
|
||||
if event.has_clip:
|
||||
media = Path(f"{os.path.join(CLIPS_DIR, media_name)}.mp4")
|
||||
media.unlink(missing_ok=True)
|
||||
|
||||
event.delete_instance()
|
||||
Timeline.delete().where(Timeline.source_id == event_id).execute()
|
||||
|
@ -521,9 +521,9 @@ class FrigateApp:
|
||||
f"Calculated total camera size {available_shm} / {cam_total_frame_size} :: {shm_frame_count} frames for each camera in SHM"
|
||||
)
|
||||
|
||||
if shm_frame_count < 10:
|
||||
if shm_frame_count < 20:
|
||||
logger.warning(
|
||||
f"The current SHM size of {total_shm}MB is too small, recommend increasing it to at least {round(min_req_shm + cam_total_frame_size * 10)}MB."
|
||||
f"The current SHM size of {total_shm}MB is too small, recommend increasing it to at least {round(min_req_shm + cam_total_frame_size * 20)}MB."
|
||||
)
|
||||
|
||||
return shm_frame_count
|
||||
|
@ -1,5 +1,6 @@
|
||||
"""Model Utils"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
@ -11,6 +12,8 @@ except ImportError:
|
||||
# openvino is not included
|
||||
pass
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_ort_providers(
|
||||
force_cpu: bool = False, device: str = "AUTO", requires_fp16: bool = False
|
||||
@ -89,19 +92,27 @@ class ONNXModelRunner:
|
||||
self.ort: ort.InferenceSession = None
|
||||
self.ov: ov.Core = None
|
||||
providers, options = get_ort_providers(device == "CPU", device, requires_fp16)
|
||||
self.interpreter = None
|
||||
|
||||
if "OpenVINOExecutionProvider" in providers:
|
||||
# use OpenVINO directly
|
||||
self.type = "ov"
|
||||
self.ov = ov.Core()
|
||||
self.ov.set_property(
|
||||
{ov.properties.cache_dir: "/config/model_cache/openvino"}
|
||||
)
|
||||
self.interpreter = self.ov.compile_model(
|
||||
model=model_path, device_name=device
|
||||
)
|
||||
else:
|
||||
# Use ONNXRuntime
|
||||
try:
|
||||
# use OpenVINO directly
|
||||
self.type = "ov"
|
||||
self.ov = ov.Core()
|
||||
self.ov.set_property(
|
||||
{ov.properties.cache_dir: "/config/model_cache/openvino"}
|
||||
)
|
||||
self.interpreter = self.ov.compile_model(
|
||||
model=model_path, device_name=device
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"OpenVINO failed to build model, using CPU instead: {e}"
|
||||
)
|
||||
self.interpreter = None
|
||||
|
||||
# Use ONNXRuntime
|
||||
if self.interpreter is None:
|
||||
self.type = "ort"
|
||||
self.ort = ort.InferenceSession(
|
||||
model_path,
|
||||
|
@ -1,191 +0,0 @@
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { GraphDataPoint } from "@/types/graph";
|
||||
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
||||
import useSWR from "swr";
|
||||
import ActivityIndicator from "../indicators/activity-indicator";
|
||||
|
||||
type TimelineBarProps = {
|
||||
startTime: number;
|
||||
graphData:
|
||||
| {
|
||||
objects: number[];
|
||||
motion: GraphDataPoint[];
|
||||
}
|
||||
| undefined;
|
||||
onClick?: () => void;
|
||||
};
|
||||
export default function TimelineBar({
|
||||
startTime,
|
||||
graphData,
|
||||
onClick,
|
||||
}: TimelineBarProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
|
||||
if (!config) {
|
||||
return <ActivityIndicator />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="h-18 my-1 w-full cursor-pointer rounded border p-1 hover:bg-secondary hover:bg-opacity-30"
|
||||
onClick={onClick}
|
||||
>
|
||||
{graphData != undefined && (
|
||||
<div className="relative flex h-8 w-full">
|
||||
{getHourBlocks().map((idx) => {
|
||||
return (
|
||||
<div
|
||||
key={idx}
|
||||
className={`h-2 flex-auto ${
|
||||
(graphData.motion.at(idx)?.y || 0) == 0
|
||||
? ""
|
||||
: graphData.objects.includes(idx)
|
||||
? "bg-object"
|
||||
: "bg-motion"
|
||||
}`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<div className="absolute bottom-0 left-0 top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:00" : "%I:00%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[8.3%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:05" : "%I:05%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[16.7%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:10" : "%I:10%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[25%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:15" : "%I:15%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[33.3%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:20" : "%I:20%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[41.7%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:25" : "%I:25%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[50%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:30" : "%I:30%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[58.3%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:35" : "%I:35%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[66.7%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:40" : "%I:40%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[75%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:45" : "%I:45%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[83.3%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:50" : "%I:50%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-[91.7%] top-0 border-l border-gray-500 align-bottom">
|
||||
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:55" : "%I:55%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="text-gray-500">
|
||||
{formatUnixTimestampToDateTime(startTime, {
|
||||
strftime_fmt:
|
||||
config.ui.time_format == "24hour" ? "%m/%d %H:%M" : "%m/%d %I:%M%P",
|
||||
time_style: "medium",
|
||||
date_style: "medium",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function getHourBlocks() {
|
||||
const arr = [];
|
||||
|
||||
for (let x = 0; x <= 59; x++) {
|
||||
arr.push(x);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { useTheme } from "@/context/theme-provider";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
||||
import { useCallback, useEffect, useMemo } from "react";
|
||||
import Chart from "react-apexcharts";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
@ -42,12 +43,14 @@ export function CameraLineGraph({
|
||||
|
||||
const formatTime = useCallback(
|
||||
(val: unknown) => {
|
||||
const date = new Date(updateTimes[Math.round(val as number)] * 1000);
|
||||
return date.toLocaleTimeString([], {
|
||||
hour12: config?.ui.time_format != "24hour",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
});
|
||||
return formatUnixTimestampToDateTime(
|
||||
updateTimes[Math.round(val as number)],
|
||||
{
|
||||
timezone: config?.ui.timezone,
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p",
|
||||
},
|
||||
);
|
||||
},
|
||||
[config, updateTimes],
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useTheme } from "@/context/theme-provider";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { Threshold } from "@/types/graph";
|
||||
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
||||
import { useCallback, useEffect, useMemo } from "react";
|
||||
import Chart from "react-apexcharts";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
@ -50,17 +51,17 @@ export function ThresholdBarGraph({
|
||||
|
||||
let timeOffset = 0;
|
||||
if (dateIndex < 0) {
|
||||
timeOffset = 5000 * Math.abs(dateIndex);
|
||||
timeOffset = 5 * Math.abs(dateIndex);
|
||||
}
|
||||
|
||||
const date = new Date(
|
||||
updateTimes[Math.max(1, dateIndex) - 1] * 1000 - timeOffset,
|
||||
return formatUnixTimestampToDateTime(
|
||||
updateTimes[Math.max(1, dateIndex) - 1] - timeOffset,
|
||||
{
|
||||
timezone: config?.ui.timezone,
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p",
|
||||
},
|
||||
);
|
||||
return date.toLocaleTimeString([], {
|
||||
hour12: config?.ui.time_format != "24hour",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
});
|
||||
},
|
||||
[config, updateTimes],
|
||||
);
|
||||
|
@ -159,7 +159,13 @@ export default function SearchResultActions({
|
||||
<AlertDialogTitle>Confirm Delete</AlertDialogTitle>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogDescription>
|
||||
Are you sure you want to delete this tracked object?
|
||||
Deleting this tracked object removes the snapshot, any saved
|
||||
embeddings, and any associated object lifecycle entries. Recorded
|
||||
footage of this tracked object in History view will <em>NOT</em> be
|
||||
deleted.
|
||||
<br />
|
||||
<br />
|
||||
Are you sure you want to proceed?
|
||||
</AlertDialogDescription>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
|
@ -427,6 +427,7 @@ export default function ObjectLifecycle({
|
||||
</div>
|
||||
<div className="text-sm text-primary-variant">
|
||||
{formatUnixTimestampToDateTime(item.timestamp, {
|
||||
timezone: config.ui.timezone,
|
||||
strftime_fmt:
|
||||
config.ui.time_format == "24hour"
|
||||
? "%d %b %H:%M:%S"
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
||||
import { useMemo } from "react";
|
||||
import useSWR from "swr";
|
||||
|
||||
type MinimapSegmentProps = {
|
||||
@ -40,22 +42,22 @@ export function MinimapBounds({
|
||||
className="pointer-events-none absolute inset-0 -bottom-7 z-20 flex w-full select-none scroll-mt-8 items-center justify-center text-center text-[10px] font-medium text-primary"
|
||||
ref={firstMinimapSegmentRef}
|
||||
>
|
||||
{new Date(alignedMinimapStartTime * 1000).toLocaleTimeString([], {
|
||||
hour12: config?.ui.time_format != "24hour",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
...(!dense && { month: "short", day: "2-digit" }),
|
||||
{formatUnixTimestampToDateTime(alignedMinimapStartTime, {
|
||||
timezone: config?.ui.timezone,
|
||||
strftime_fmt: !dense
|
||||
? `%b %d, ${config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p"}`
|
||||
: `${config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p"}`,
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isLastSegmentInMinimap && (
|
||||
<div className="pointer-events-none absolute inset-0 -top-3 z-20 flex w-full select-none items-center justify-center text-center text-[10px] font-medium text-primary">
|
||||
{new Date(alignedMinimapEndTime * 1000).toLocaleTimeString([], {
|
||||
hour12: config?.ui.time_format != "24hour",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
...(!dense && { month: "short", day: "2-digit" }),
|
||||
{formatUnixTimestampToDateTime(alignedMinimapEndTime, {
|
||||
timezone: config?.ui.timezone,
|
||||
strftime_fmt: !dense
|
||||
? `%b %d, ${config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p"}`
|
||||
: `${config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p"}`,
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
@ -92,6 +94,22 @@ export function Timestamp({
|
||||
}: TimestampSegmentProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
|
||||
const formattedTimestamp = useMemo(() => {
|
||||
if (
|
||||
!(
|
||||
timestamp.getMinutes() % timestampSpread === 0 &&
|
||||
timestamp.getSeconds() === 0
|
||||
)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return formatUnixTimestampToDateTime(timestamp.getTime() / 1000, {
|
||||
timezone: config?.ui.timezone,
|
||||
strftime_fmt: config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p",
|
||||
});
|
||||
}, [config, timestamp, timestampSpread]);
|
||||
|
||||
return (
|
||||
<div className="absolute left-[15px] z-10 h-[8px]">
|
||||
{!isFirstSegmentInMinimap && !isLastSegmentInMinimap && (
|
||||
@ -99,13 +117,7 @@ export function Timestamp({
|
||||
key={`${segmentKey}_timestamp`}
|
||||
className="pointer-events-none select-none text-[8px] text-neutral_variant dark:text-neutral"
|
||||
>
|
||||
{timestamp.getMinutes() % timestampSpread === 0 &&
|
||||
timestamp.getSeconds() === 0 &&
|
||||
timestamp.toLocaleTimeString([], {
|
||||
hour12: config?.ui.time_format != "24hour",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
})}
|
||||
{formattedTimestamp}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -10,6 +10,7 @@ import scrollIntoView from "scroll-into-view-if-needed";
|
||||
import { useTimelineUtils } from "./use-timeline-utils";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import useSWR from "swr";
|
||||
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
||||
|
||||
type DraggableElementProps = {
|
||||
contentRef: React.RefObject<HTMLElement>;
|
||||
@ -168,6 +169,19 @@ function useDraggableElement({
|
||||
[segmentDuration, timelineStartAligned, segmentHeight],
|
||||
);
|
||||
|
||||
const getFormattedTimestamp = useCallback(
|
||||
(segmentStartTime: number) => {
|
||||
return formatUnixTimestampToDateTime(segmentStartTime, {
|
||||
timezone: config?.ui.timezone,
|
||||
strftime_fmt:
|
||||
config?.ui.time_format == "24hour"
|
||||
? `%H:%M${segmentDuration < 60 && !dense ? ":%S" : ""}`
|
||||
: `%I:%M${segmentDuration < 60 && !dense ? ":%S" : ""} %p`,
|
||||
});
|
||||
},
|
||||
[config, dense, segmentDuration],
|
||||
);
|
||||
|
||||
const updateDraggableElementPosition = useCallback(
|
||||
(
|
||||
newElementPosition: number,
|
||||
@ -184,14 +198,8 @@ function useDraggableElement({
|
||||
}
|
||||
|
||||
if (draggableElementTimeRef.current) {
|
||||
draggableElementTimeRef.current.textContent = new Date(
|
||||
segmentStartTime * 1000,
|
||||
).toLocaleTimeString([], {
|
||||
hour12: config?.ui.time_format != "24hour",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
...(segmentDuration < 60 && !dense && { second: "2-digit" }),
|
||||
});
|
||||
draggableElementTimeRef.current.textContent =
|
||||
getFormattedTimestamp(segmentStartTime);
|
||||
if (scrollTimeline && !userInteracting) {
|
||||
scrollIntoView(thumb, {
|
||||
block: "center",
|
||||
@ -208,13 +216,11 @@ function useDraggableElement({
|
||||
}
|
||||
},
|
||||
[
|
||||
segmentDuration,
|
||||
draggableElementTimeRef,
|
||||
draggableElementRef,
|
||||
setDraggableElementTime,
|
||||
setDraggableElementPosition,
|
||||
dense,
|
||||
config,
|
||||
getFormattedTimestamp,
|
||||
userInteracting,
|
||||
],
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user