mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-30 15:49:00 +03:00
Miscellaneous fixes (#22924)
* apply annotation offset to frigate+ submission frame time * fix broken docs links with hash fragments that resolve wrong on reload * undo * use recording snapshot for frigate+ frame submission from VideoControls rather than a canvas grab/paint, which may not always align with an ffmpeg snapshot due to keyframes * add more docs links - display docs link for main sections on collapsible fields * dialog button consistency
This commit is contained in:
@@ -113,18 +113,19 @@ export function DebugReplayContent({
|
||||
{isDesktop && <SelectSeparator className="my-4 bg-secondary" />}
|
||||
|
||||
<DialogFooter
|
||||
className={isDesktop ? "" : "mt-3 flex flex-col-reverse gap-4"}
|
||||
className={isDesktop ? "" : "mt-3 flex flex-col-reverse gap-2"}
|
||||
>
|
||||
<div
|
||||
className={`cursor-pointer p-2 text-center ${isDesktop ? "" : "w-full"}`}
|
||||
<Button
|
||||
className={isDesktop ? "" : "w-full"}
|
||||
aria-label={t("button.cancel", { ns: "common" })}
|
||||
variant="outline"
|
||||
onClick={onCancel}
|
||||
>
|
||||
{t("button.cancel", { ns: "common" })}
|
||||
</div>
|
||||
</Button>
|
||||
<Button
|
||||
className={isDesktop ? "" : "w-full"}
|
||||
variant="select"
|
||||
size="sm"
|
||||
disabled={isStarting}
|
||||
onClick={() => {
|
||||
if (selectedOption === "timeline") {
|
||||
|
||||
@@ -1043,20 +1043,21 @@ export function ExportContent({
|
||||
|
||||
{isDesktop && <SelectSeparator className="my-4 bg-secondary" />}
|
||||
<DialogFooter
|
||||
className={isDesktop ? "" : "mt-3 flex flex-col-reverse gap-4"}
|
||||
className={isDesktop ? "" : "mt-3 flex flex-col-reverse gap-2"}
|
||||
>
|
||||
<div
|
||||
className={`cursor-pointer p-2 text-center ${isDesktop ? "" : "w-full"}`}
|
||||
<Button
|
||||
className={isDesktop ? "" : "w-full"}
|
||||
aria-label={t("button.cancel", { ns: "common" })}
|
||||
variant="outline"
|
||||
onClick={onCancel}
|
||||
>
|
||||
{t("button.cancel", { ns: "common" })}
|
||||
</div>
|
||||
</Button>
|
||||
{activeTab === "export" ? (
|
||||
<Button
|
||||
className={isDesktop ? "" : "w-full"}
|
||||
aria-label={t("export.selectOrExport")}
|
||||
variant="select"
|
||||
size="sm"
|
||||
disabled={isStartingExport}
|
||||
onClick={async () => {
|
||||
if (selectedOption == "timeline") {
|
||||
|
||||
@@ -197,24 +197,21 @@ export function ShareTimestampContent({
|
||||
{isDesktop && <Separator className="my-4 bg-secondary" />}
|
||||
|
||||
<DialogFooter
|
||||
className={cn("mt-4", !isDesktop && "flex flex-col-reverse gap-4")}
|
||||
className={cn("mt-4", !isDesktop && "flex flex-col-reverse gap-2")}
|
||||
>
|
||||
{onCancel && (
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"cursor-pointer p-2 text-center",
|
||||
!isDesktop && "w-full",
|
||||
)}
|
||||
<Button
|
||||
className={cn(!isDesktop && "w-full")}
|
||||
aria-label={t("button.cancel", { ns: "common" })}
|
||||
variant="outline"
|
||||
onClick={onCancel}
|
||||
>
|
||||
{t("button.cancel", { ns: "common" })}
|
||||
</button>
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
className={cn(!isDesktop && "w-full")}
|
||||
variant="select"
|
||||
size="sm"
|
||||
onClick={() => onShareTimestamp(Math.floor(selectedTimestamp))}
|
||||
>
|
||||
{t("recording.shareTimestamp.button", { ns: "components/dialog" })}
|
||||
|
||||
@@ -636,6 +636,13 @@ export function TrackingDetails({
|
||||
return axios.post(`/${event.camera}/plus/${currentTime}`);
|
||||
}, [event.camera, currentTime]);
|
||||
|
||||
const getSnapshotUrlForPlus = useCallback(() => {
|
||||
if (!currentTime) {
|
||||
return undefined;
|
||||
}
|
||||
return `${apiHost}api/${event.camera}/recordings/${currentTime}/snapshot.jpg?height=500`;
|
||||
}, [apiHost, event.camera, currentTime]);
|
||||
|
||||
if (!config) {
|
||||
return <ActivityIndicator />;
|
||||
}
|
||||
@@ -683,6 +690,7 @@ export function TrackingDetails({
|
||||
onTimeUpdate={handleTimeUpdate}
|
||||
onSeekToTime={handleSeekToTime}
|
||||
onUploadFrame={onUploadFrameToPlus}
|
||||
getSnapshotUrl={getSnapshotUrlForPlus}
|
||||
onPlaying={() => setIsVideoLoading(false)}
|
||||
setFullResolution={setFullResolution}
|
||||
toggleFullscreen={toggleFullscreen}
|
||||
@@ -867,6 +875,7 @@ export function TrackingDetails({
|
||||
getZoneColor={getZoneColor}
|
||||
effectiveTime={effectiveTime}
|
||||
isTimelineActive={isWithinEventRange}
|
||||
annotationOffset={annotationOffset}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -890,6 +899,7 @@ type LifecycleIconRowProps = {
|
||||
getZoneColor: (zoneName: string) => number[] | undefined;
|
||||
effectiveTime?: number;
|
||||
isTimelineActive?: boolean;
|
||||
annotationOffset: number;
|
||||
};
|
||||
|
||||
function LifecycleIconRow({
|
||||
@@ -900,6 +910,7 @@ function LifecycleIconRow({
|
||||
getZoneColor,
|
||||
effectiveTime,
|
||||
isTimelineActive,
|
||||
annotationOffset,
|
||||
}: LifecycleIconRowProps) {
|
||||
const { t } = useTranslation(["views/explore", "components/player"]);
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
@@ -1206,7 +1217,7 @@ function LifecycleIconRow({
|
||||
className="cursor-pointer"
|
||||
onSelect={async () => {
|
||||
const resp = await axios.post(
|
||||
`/${item.camera}/plus/${item.timestamp}`,
|
||||
`/${item.camera}/plus/${item.timestamp + annotationOffset / 1000}`,
|
||||
);
|
||||
|
||||
if (resp && resp.status == 200) {
|
||||
|
||||
Reference in New Issue
Block a user