mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-09 15:05:26 +03:00
Compare commits
No commits in common. "6a72a041d6a2deb75bab51328ff0738a665416fd" and "36b20435183a408a569bbfd5adb77956ffacd359" have entirely different histories.
6a72a041d6
...
36b2043518
@ -45,9 +45,8 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { ObjectPath } from "./ObjectPath";
|
import { ObjectPath } from "./ObjectPath";
|
||||||
import { getLifecycleItemDescription } from "@/utils/lifecycleUtil";
|
import { getLifecycleItemDescription } from "@/utils/lifecycleUtil";
|
||||||
import { IoPlayCircleOutline } from "react-icons/io5";
|
import { IoPlayCircleOutline } from "react-icons/io5";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { getTranslatedLabel } from "@/utils/i18n";
|
import { getTranslatedLabel } from "@/utils/i18n";
|
||||||
import { resolveZoneName } from "@/hooks/use-zone-friendly-name";
|
|
||||||
|
|
||||||
type ObjectLifecycleProps = {
|
type ObjectLifecycleProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -63,7 +62,7 @@ export default function ObjectLifecycle({
|
|||||||
setPane,
|
setPane,
|
||||||
}: ObjectLifecycleProps) {
|
}: ObjectLifecycleProps) {
|
||||||
const { t } = useTranslation(["views/explore"]);
|
const { t } = useTranslation(["views/explore"]);
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
|
||||||
const { data: eventSequence } = useSWR<ObjectLifecycleSequence[]>([
|
const { data: eventSequence } = useSWR<ObjectLifecycleSequence[]>([
|
||||||
"timeline",
|
"timeline",
|
||||||
{
|
{
|
||||||
@ -71,12 +70,7 @@ export default function ObjectLifecycle({
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
eventSequence?.map((event) => {
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
event.data.zones_friendly_names = event.data?.zones?.map((zone) => {
|
|
||||||
return resolveZoneName(config, zone);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const apiHost = useApiHost();
|
const apiHost = useApiHost();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@ -679,9 +673,7 @@ export default function ObjectLifecycle({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full flex-row justify-between">
|
<div className="flex w-full flex-row justify-between">
|
||||||
<Trans>
|
<div>{getLifecycleItemDescription(item)}</div>
|
||||||
<div>{getLifecycleItemDescription(item)}</div>
|
|
||||||
</Trans>
|
|
||||||
<div className={cn("p-1 text-sm")}>
|
<div className={cn("p-1 text-sm")}>
|
||||||
{formattedEventTimestamp}
|
{formattedEventTimestamp}
|
||||||
</div>
|
</div>
|
||||||
@ -739,9 +731,7 @@ export default function ObjectLifecycle({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<span className="smart-capitalize">
|
<span className="smart-capitalize">
|
||||||
{item.data?.zones_friendly_names?.[
|
{zone.replaceAll("_", " ")}
|
||||||
zidx
|
|
||||||
] ?? zone.replaceAll("_", " ")}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -22,7 +22,6 @@ export type ObjectLifecycleSequence = {
|
|||||||
attribute: string;
|
attribute: string;
|
||||||
attribute_box?: [number, number, number, number];
|
attribute_box?: [number, number, number, number];
|
||||||
zones: string[];
|
zones: string[];
|
||||||
zones_friendly_names?: string[];
|
|
||||||
};
|
};
|
||||||
class_type: LifecycleClassType;
|
class_type: LifecycleClassType;
|
||||||
source_id: string;
|
source_id: string;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { ObjectLifecycleSequence } from "@/types/timeline";
|
import { ObjectLifecycleSequence } from "@/types/timeline";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import i18n, { getTranslatedLabel } from "./i18n";
|
import { getTranslatedLabel } from "./i18n";
|
||||||
|
|
||||||
export function getLifecycleItemDescription(
|
export function getLifecycleItemDescription(
|
||||||
lifecycleItem: ObjectLifecycleSequence,
|
lifecycleItem: ObjectLifecycleSequence,
|
||||||
@ -11,17 +11,6 @@ export function getLifecycleItemDescription(
|
|||||||
|
|
||||||
const label = getTranslatedLabel(rawLabel);
|
const label = getTranslatedLabel(rawLabel);
|
||||||
|
|
||||||
let supportedListFormat = false;
|
|
||||||
let zonesFormatter: Intl.ListFormat | null = null;
|
|
||||||
|
|
||||||
if (typeof Intl !== "undefined" && Intl.ListFormat) {
|
|
||||||
supportedListFormat = true;
|
|
||||||
zonesFormatter = new Intl.ListFormat(i18n.language, {
|
|
||||||
style: "long",
|
|
||||||
type: "conjunction",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (lifecycleItem.class_type) {
|
switch (lifecycleItem.class_type) {
|
||||||
case "visible":
|
case "visible":
|
||||||
return t("objectLifecycle.lifecycleItemDesc.visible", {
|
return t("objectLifecycle.lifecycleItemDesc.visible", {
|
||||||
@ -32,18 +21,7 @@ export function getLifecycleItemDescription(
|
|||||||
return t("objectLifecycle.lifecycleItemDesc.entered_zone", {
|
return t("objectLifecycle.lifecycleItemDesc.entered_zone", {
|
||||||
ns: "views/explore",
|
ns: "views/explore",
|
||||||
label,
|
label,
|
||||||
zones:
|
zones: lifecycleItem.data.zones.join(" and ").replaceAll("_", " "),
|
||||||
supportedListFormat && zonesFormatter
|
|
||||||
? zonesFormatter.format(
|
|
||||||
lifecycleItem.data.zones_friendly_names?.map(
|
|
||||||
(x) => `<strong>${x}</strong>`,
|
|
||||||
) ??
|
|
||||||
lifecycleItem.data.zones.map((x) => `<strong>${x}</strong>`),
|
|
||||||
)
|
|
||||||
: (
|
|
||||||
lifecycleItem.data.zones_friendly_names ??
|
|
||||||
lifecycleItem.data.zones
|
|
||||||
).join(" and "),
|
|
||||||
});
|
});
|
||||||
case "active":
|
case "active":
|
||||||
return t("objectLifecycle.lifecycleItemDesc.active", {
|
return t("objectLifecycle.lifecycleItemDesc.active", {
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import { StatusBarMessagesContext } from "@/context/statusbar-provider";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { LuExternalLink } from "react-icons/lu";
|
import { LuExternalLink } from "react-icons/lu";
|
||||||
|
import { capitalizeFirstLetter } from "@/utils/stringUtil";
|
||||||
import { MdCircle } from "react-icons/md";
|
import { MdCircle } from "react-icons/md";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
@ -87,7 +88,7 @@ export default function CameraSettingsView({
|
|||||||
// zones and labels
|
// zones and labels
|
||||||
|
|
||||||
const getZoneName = useCallback(
|
const getZoneName = useCallback(
|
||||||
(zoneId: string, cameraId?: string) =>
|
(cameraId: string, zoneId: string) =>
|
||||||
resolveZoneName(config, zoneId, cameraId),
|
resolveZoneName(config, zoneId, cameraId),
|
||||||
[config],
|
[config],
|
||||||
);
|
);
|
||||||
@ -97,7 +98,7 @@ export default function CameraSettingsView({
|
|||||||
return Object.entries(cameraConfig.zones).map(([name, zoneData]) => ({
|
return Object.entries(cameraConfig.zones).map(([name, zoneData]) => ({
|
||||||
camera: cameraConfig.name,
|
camera: cameraConfig.name,
|
||||||
name,
|
name,
|
||||||
friendly_name: getZoneName(name, cameraConfig.name),
|
friendly_name: getZoneName(cameraConfig.name, name),
|
||||||
objects: zoneData.objects,
|
objects: zoneData.objects,
|
||||||
color: zoneData.color,
|
color: zoneData.color,
|
||||||
}));
|
}));
|
||||||
@ -556,7 +557,12 @@ export default function CameraSettingsView({
|
|||||||
{
|
{
|
||||||
alertsLabels,
|
alertsLabels,
|
||||||
zone: watchedAlertsZones
|
zone: watchedAlertsZones
|
||||||
.map((zone) => getZoneName(zone))
|
.map((zone) =>
|
||||||
|
capitalizeFirstLetter(zone).replaceAll(
|
||||||
|
"_",
|
||||||
|
" ",
|
||||||
|
),
|
||||||
|
)
|
||||||
.join(", "),
|
.join(", "),
|
||||||
cameraName: selectCameraName,
|
cameraName: selectCameraName,
|
||||||
},
|
},
|
||||||
@ -670,7 +676,12 @@ export default function CameraSettingsView({
|
|||||||
values={{
|
values={{
|
||||||
detectionsLabels,
|
detectionsLabels,
|
||||||
zone: watchedDetectionsZones
|
zone: watchedDetectionsZones
|
||||||
.map((zone) => getZoneName(zone))
|
.map((zone) =>
|
||||||
|
capitalizeFirstLetter(zone).replaceAll(
|
||||||
|
"_",
|
||||||
|
" ",
|
||||||
|
),
|
||||||
|
)
|
||||||
.join(", "),
|
.join(", "),
|
||||||
cameraName: selectCameraName,
|
cameraName: selectCameraName,
|
||||||
}}
|
}}
|
||||||
@ -682,7 +693,12 @@ export default function CameraSettingsView({
|
|||||||
values={{
|
values={{
|
||||||
detectionsLabels,
|
detectionsLabels,
|
||||||
zone: watchedDetectionsZones
|
zone: watchedDetectionsZones
|
||||||
.map((zone) => getZoneName(zone))
|
.map((zone) =>
|
||||||
|
capitalizeFirstLetter(zone).replaceAll(
|
||||||
|
"_",
|
||||||
|
" ",
|
||||||
|
),
|
||||||
|
)
|
||||||
.join(", "),
|
.join(", "),
|
||||||
cameraName: selectCameraName,
|
cameraName: selectCameraName,
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2021",
|
"target": "ES2020",
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"lib": ["ES2021", "DOM", "DOM.Iterable", "ES2021.String"],
|
"lib": ["ES2020", "DOM", "DOM.Iterable", "ES2021.String"],
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user