mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-12-17 02:26:43 +03:00
chore: fix objectLifecycle zones friendly name support and use Intl.ListFormat
This commit is contained in:
parent
23aba70819
commit
6a72a041d6
@ -45,8 +45,9 @@ 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 { useTranslation } from "react-i18next";
|
import { Trans, 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;
|
||||||
@ -62,7 +63,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",
|
||||||
{
|
{
|
||||||
@ -70,7 +71,12 @@ export default function ObjectLifecycle({
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
eventSequence?.map((event) => {
|
||||||
|
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();
|
||||||
|
|
||||||
@ -673,7 +679,9 @@ 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>
|
||||||
@ -731,7 +739,9 @@ export default function ObjectLifecycle({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<span className="smart-capitalize">
|
<span className="smart-capitalize">
|
||||||
{zone.replaceAll("_", " ")}
|
{item.data?.zones_friendly_names?.[
|
||||||
|
zidx
|
||||||
|
] ?? zone.replaceAll("_", " ")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ 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 { getTranslatedLabel } from "./i18n";
|
import i18n, { getTranslatedLabel } from "./i18n";
|
||||||
|
|
||||||
export function getLifecycleItemDescription(
|
export function getLifecycleItemDescription(
|
||||||
lifecycleItem: ObjectLifecycleSequence,
|
lifecycleItem: ObjectLifecycleSequence,
|
||||||
@ -11,6 +11,17 @@ 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", {
|
||||||
@ -21,7 +32,18 @@ export function getLifecycleItemDescription(
|
|||||||
return t("objectLifecycle.lifecycleItemDesc.entered_zone", {
|
return t("objectLifecycle.lifecycleItemDesc.entered_zone", {
|
||||||
ns: "views/explore",
|
ns: "views/explore",
|
||||||
label,
|
label,
|
||||||
zones: lifecycleItem.data.zones.join(" and ").replaceAll("_", " "),
|
zones:
|
||||||
|
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", {
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2020",
|
"target": "ES2021",
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"lib": ["ES2020", "DOM", "DOM.Iterable", "ES2021.String"],
|
"lib": ["ES2021", "DOM", "DOM.Iterable", "ES2021.String"],
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user