feat: Add camera nickname (#19567)

* refactor: Refactor camera nickname

* fix: fix cameraNameLabel visually

* chore: The Explore search function also displays the Camera's nickname in English

* chore: add mobile page camera nickname

* feat: webpush support camera nickname

* fix: fix storage camera name is null

* chore: fix review detail and context menu camera nickname

* chore: fix use-stats and notification setting camera nickname

* fix: fix stats camera if not nickname need capitalize

* fix: fix debug page open camera web ui i18n and camera nickname support

* fix: fix camera metrics not use nickname

* refactor: refactor use-camera-nickname hook.
This commit is contained in:
GuoQing Liu
2025-08-26 11:15:01 -06:00
committed by GitHub
parent 195f705616
commit d3af748366
31 changed files with 276 additions and 99 deletions
+29
View File
@@ -0,0 +1,29 @@
import { CameraConfig, FrigateConfig } from "@/types/frigateConfig";
import { useMemo } from "react";
import useSWR from "swr";
export function resolveCameraName(
config: FrigateConfig | undefined,
cameraId: string | CameraConfig | undefined,
) {
if (typeof cameraId === "object" && cameraId !== null) {
const camera = cameraId as CameraConfig;
return camera?.nickname || camera?.name.replaceAll("_", " ");
} else {
const camera = config?.cameras?.[String(cameraId)];
return camera?.nickname || String(cameraId).replaceAll("_", " ");
}
}
export function useCameraNickname(
cameraId: string | CameraConfig | undefined,
): string {
const { data: config } = useSWR<FrigateConfig>("config");
const name = useMemo(
() => resolveCameraName(config, cameraId),
[config, cameraId],
);
return name;
}
+6 -4
View File
@@ -8,7 +8,7 @@ import { FrigateStats, PotentialProblem } from "@/types/stats";
import { useMemo } from "react";
import useSWR from "swr";
import useDeepMemo from "./use-deep-memo";
import { capitalizeFirstLetter } from "@/utils/stringUtil";
import { capitalizeAll, capitalizeFirstLetter } from "@/utils/stringUtil";
import { useFrigateStats } from "@/api/ws";
import { useTranslation } from "react-i18next";
@@ -61,10 +61,11 @@ export default function useStats(stats: FrigateStats | undefined) {
return;
}
const cameraName = config.cameras?.[name]?.nickname ?? name;
if (config.cameras[name].enabled && cam["camera_fps"] == 0) {
problems.push({
text: t("stats.cameraIsOffline", {
camera: capitalizeFirstLetter(name.replaceAll("_", " ")),
camera: capitalizeFirstLetter(capitalizeAll(cameraName)),
}),
color: "text-danger",
relevantLink: "logs",
@@ -81,10 +82,11 @@ export default function useStats(stats: FrigateStats | undefined) {
memoizedStats["cpu_usages"][cam["pid"]]?.cpu_average,
);
const cameraName = config?.cameras?.[name]?.nickname ?? name;
if (!isNaN(ffmpegAvg) && ffmpegAvg >= CameraFfmpegThreshold.error) {
problems.push({
text: t("stats.ffmpegHighCpuUsage", {
camera: capitalizeFirstLetter(name.replaceAll("_", " ")),
camera: capitalizeFirstLetter(capitalizeAll(cameraName)),
ffmpegAvg,
}),
color: "text-danger",
@@ -95,7 +97,7 @@ export default function useStats(stats: FrigateStats | undefined) {
if (!isNaN(detectAvg) && detectAvg >= CameraDetectThreshold.error) {
problems.push({
text: t("stats.detectHighCpuUsage", {
camera: capitalizeFirstLetter(name.replaceAll("_", " ")),
camera: capitalizeFirstLetter(capitalizeAll(cameraName)),
detectAvg,
}),
color: "text-danger",