mirror of
https://github.com/alexhopeoconnor/frigate.git
synced 2026-10-04 03:18:11 +10:00
Add optional docs link to config field messages (#23569)
* add optional docs link to config field messages * docs tweaks * add field messages for model dimensions
This commit is contained in:
@@ -1924,6 +1924,10 @@
|
||||
"resolutionHigh": "This detect resolution is higher than recommended and may cause increased resource usage without improving detection accuracy. A detect resolution at or below 1080p is recommended for most cameras.",
|
||||
"globalResolutionMultipleCameras": "A global detect resolution is set while multiple cameras are configured. Unless all cameras share the same resolution and aspect ratio, the detect width and height should be defined per camera to match each camera's native aspect ratio."
|
||||
},
|
||||
"model": {
|
||||
"optimizedFor320": "Frigate is optimized for a 320x320 model, which is the best choice for most setups. A 640x640 model is slower and only helps in specific scenarios.",
|
||||
"inputDimensionsNotDetectResolution": "Model input width and height are the input dimensions of the object detection model, not your camera's detect resolution. They should match the dimensions of the model you're using — typically a square size like 320x320 or 640x640."
|
||||
},
|
||||
"ffmpeg": {
|
||||
"hwaccelManualNotRecommended": "Manual hardware acceleration arguments are not recommended. Unless a specific requirement exists, select the preset that matches your hardware."
|
||||
},
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||
import { LuInfo, LuTriangleAlert, LuCircleAlert } from "react-icons/lu";
|
||||
import {
|
||||
LuInfo,
|
||||
LuTriangleAlert,
|
||||
LuCircleAlert,
|
||||
LuExternalLink,
|
||||
} from "react-icons/lu";
|
||||
import { useDocDomain } from "@/hooks/use-doc-domain";
|
||||
import type { MessageSeverity } from "./section-configs/types";
|
||||
|
||||
const severityVariantMap: Record<
|
||||
@@ -28,13 +35,18 @@ function SeverityIcon({ severity }: { severity: string }) {
|
||||
type ConfigFieldMessageProps = {
|
||||
messageKey: string;
|
||||
severity: string;
|
||||
values?: Record<string, unknown>;
|
||||
docLink?: string;
|
||||
};
|
||||
|
||||
export function ConfigFieldMessage({
|
||||
messageKey,
|
||||
severity,
|
||||
values,
|
||||
docLink,
|
||||
}: ConfigFieldMessageProps) {
|
||||
const { t } = useTranslation("views/settings");
|
||||
const { t } = useTranslation(["views/settings", "common"]);
|
||||
const { getLocaleDocUrl } = useDocDomain();
|
||||
|
||||
return (
|
||||
<Alert
|
||||
@@ -42,7 +54,22 @@ export function ConfigFieldMessage({
|
||||
className="flex items-center [&>svg+div]:translate-y-0 [&>svg]:static [&>svg~*]:pl-2"
|
||||
>
|
||||
<SeverityIcon severity={severity} />
|
||||
<AlertDescription>{t(messageKey)}</AlertDescription>
|
||||
<AlertDescription>
|
||||
<div className="flex flex-col gap-1">
|
||||
<span>{t(messageKey, values)}</span>
|
||||
{docLink && (
|
||||
<Link
|
||||
to={getLocaleDocUrl(docLink)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center underline"
|
||||
>
|
||||
{t("readTheDocumentation", { ns: "common" })}
|
||||
<LuExternalLink className="ml-2 inline-flex size-3" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,39 @@ import type { SectionConfigOverrides } from "./types";
|
||||
const model: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/object_detectors#model",
|
||||
fieldMessages: [
|
||||
{
|
||||
key: "model-optimized-for-320",
|
||||
field: "width",
|
||||
position: "before",
|
||||
messageKey: "configMessages.model.optimizedFor320",
|
||||
severity: "info",
|
||||
docLink: "/configuration/object_detectors#choosing-a-model-size",
|
||||
condition: (ctx) => {
|
||||
const width = ctx.formData?.width as number | null | undefined;
|
||||
const height = ctx.formData?.height as number | null | undefined;
|
||||
return width === 640 || height === 640;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "model-input-dimensions-not-detect-resolution",
|
||||
field: "height",
|
||||
position: "after",
|
||||
messageKey: "configMessages.model.inputDimensionsNotDetectResolution",
|
||||
severity: "warning",
|
||||
condition: (ctx) => {
|
||||
const width = ctx.formData?.width as number | null | undefined;
|
||||
const height = ctx.formData?.height as number | null | undefined;
|
||||
if (typeof width !== "number" || typeof height !== "number") {
|
||||
return false;
|
||||
}
|
||||
if (width <= 0 || height <= 0) {
|
||||
return false;
|
||||
}
|
||||
return width > 640 || height > 640;
|
||||
},
|
||||
},
|
||||
],
|
||||
restartRequired: [
|
||||
"path",
|
||||
"labelmap_path",
|
||||
|
||||
@@ -26,6 +26,8 @@ export type ConditionalMessage = {
|
||||
condition: (ctx: MessageConditionContext) => boolean;
|
||||
/** Optional interpolation values passed to t() for {{var}} substitution */
|
||||
values?: Record<string, unknown>;
|
||||
/** Optional documentation path (e.g. "/configuration/object_detectors#model"). */
|
||||
docLink?: string;
|
||||
};
|
||||
|
||||
/** Field-level conditional message, adds field targeting */
|
||||
|
||||
@@ -406,6 +406,8 @@ export function FieldTemplate(props: FieldTemplateProps) {
|
||||
key={m.key}
|
||||
messageKey={m.messageKey}
|
||||
severity={m.severity}
|
||||
values={m.values}
|
||||
docLink={m.docLink}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -418,6 +420,8 @@ export function FieldTemplate(props: FieldTemplateProps) {
|
||||
key={m.key}
|
||||
messageKey={m.messageKey}
|
||||
severity={m.severity}
|
||||
values={m.values}
|
||||
docLink={m.docLink}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user