mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-12-20 12:06:43 +03:00
Compare commits
5 Commits
a114786a03
...
2887af7bef
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2887af7bef | ||
|
|
bae32f8e40 | ||
|
|
1c108bd910 | ||
|
|
6214d5232a | ||
|
|
38b13a0cf1 |
@ -144,7 +144,8 @@
|
|||||||
"unselect": "Unselect",
|
"unselect": "Unselect",
|
||||||
"export": "Export",
|
"export": "Export",
|
||||||
"deleteNow": "Delete Now",
|
"deleteNow": "Delete Now",
|
||||||
"next": "Next"
|
"next": "Next",
|
||||||
|
"continue": "Continue"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"system": "System",
|
"system": "System",
|
||||||
|
|||||||
@ -24,8 +24,8 @@
|
|||||||
"label": "Detail",
|
"label": "Detail",
|
||||||
"noDataFound": "No detail data to review",
|
"noDataFound": "No detail data to review",
|
||||||
"aria": "Toggle detail view",
|
"aria": "Toggle detail view",
|
||||||
"trackedObject_one": "object",
|
"trackedObject_one": "{{count}} object",
|
||||||
"trackedObject_other": "objects",
|
"trackedObject_other": "{{count}} objects",
|
||||||
"noObjectDetailData": "No object detail data available.",
|
"noObjectDetailData": "No object detail data available.",
|
||||||
"settings": "Detail View Settings",
|
"settings": "Detail View Settings",
|
||||||
"alwaysExpandActive": {
|
"alwaysExpandActive": {
|
||||||
|
|||||||
@ -454,6 +454,24 @@ export function GeneralFilterContent({
|
|||||||
onClose,
|
onClose,
|
||||||
}: GeneralFilterContentProps) {
|
}: GeneralFilterContentProps) {
|
||||||
const { t } = useTranslation(["components/filter", "views/events"]);
|
const { t } = useTranslation(["components/filter", "views/events"]);
|
||||||
|
const { data: config } = useSWR<FrigateConfig>("config", {
|
||||||
|
revalidateOnFocus: false,
|
||||||
|
});
|
||||||
|
const allAudioListenLabels = useMemo<string[]>(() => {
|
||||||
|
if (!config) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const labels = new Set<string>();
|
||||||
|
Object.values(config.cameras).forEach((camera) => {
|
||||||
|
if (camera?.audio?.enabled) {
|
||||||
|
camera.audio.listen.forEach((label) => {
|
||||||
|
labels.add(label);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return [...labels].sort();
|
||||||
|
}, [config]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="scrollbar-container h-auto max-h-[80dvh] overflow-y-auto overflow-x-hidden">
|
<div className="scrollbar-container h-auto max-h-[80dvh] overflow-y-auto overflow-x-hidden">
|
||||||
@ -504,7 +522,10 @@ export function GeneralFilterContent({
|
|||||||
{allLabels.map((item) => (
|
{allLabels.map((item) => (
|
||||||
<FilterSwitch
|
<FilterSwitch
|
||||||
key={item}
|
key={item}
|
||||||
label={getTranslatedLabel(item)}
|
label={getTranslatedLabel(
|
||||||
|
item,
|
||||||
|
allAudioListenLabels.includes(item) ? "audio" : "object",
|
||||||
|
)}
|
||||||
isChecked={filter.labels?.includes(item) ?? false}
|
isChecked={filter.labels?.includes(item) ?? false}
|
||||||
onCheckedChange={(isChecked) => {
|
onCheckedChange={(isChecked) => {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
|
|||||||
@ -81,6 +81,22 @@ export default function InputWithTags({
|
|||||||
revalidateOnFocus: false,
|
revalidateOnFocus: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const allAudioListenLabels = useMemo<string[]>(() => {
|
||||||
|
if (!config) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const labels = new Set<string>();
|
||||||
|
Object.values(config.cameras).forEach((camera) => {
|
||||||
|
if (camera?.audio?.enabled) {
|
||||||
|
camera.audio.listen.forEach((label) => {
|
||||||
|
labels.add(label);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return [...labels].sort();
|
||||||
|
}, [config]);
|
||||||
|
|
||||||
const [inputValue, setInputValue] = useState(search || "");
|
const [inputValue, setInputValue] = useState(search || "");
|
||||||
const [currentFilterType, setCurrentFilterType] = useState<FilterType | null>(
|
const [currentFilterType, setCurrentFilterType] = useState<FilterType | null>(
|
||||||
null,
|
null,
|
||||||
@ -421,7 +437,11 @@ export default function InputWithTags({
|
|||||||
? t("button.yes", { ns: "common" })
|
? t("button.yes", { ns: "common" })
|
||||||
: t("button.no", { ns: "common" });
|
: t("button.no", { ns: "common" });
|
||||||
} else if (filterType === "labels") {
|
} else if (filterType === "labels") {
|
||||||
return getTranslatedLabel(String(filterValues));
|
const value = String(filterValues);
|
||||||
|
return getTranslatedLabel(
|
||||||
|
value,
|
||||||
|
allAudioListenLabels.includes(value) ? "audio" : "object",
|
||||||
|
);
|
||||||
} else if (filterType === "search_type") {
|
} else if (filterType === "search_type") {
|
||||||
return t("filter.searchType." + String(filterValues));
|
return t("filter.searchType." + String(filterValues));
|
||||||
} else {
|
} else {
|
||||||
@ -828,7 +848,12 @@ export default function InputWithTags({
|
|||||||
>
|
>
|
||||||
{t("filter.label." + filterType)}:{" "}
|
{t("filter.label." + filterType)}:{" "}
|
||||||
{filterType === "labels" ? (
|
{filterType === "labels" ? (
|
||||||
getTranslatedLabel(value)
|
getTranslatedLabel(
|
||||||
|
value,
|
||||||
|
allAudioListenLabels.includes(value)
|
||||||
|
? "audio"
|
||||||
|
: "object",
|
||||||
|
)
|
||||||
) : filterType === "cameras" ? (
|
) : filterType === "cameras" ? (
|
||||||
<CameraNameLabel camera={value} />
|
<CameraNameLabel camera={value} />
|
||||||
) : filterType === "zones" ? (
|
) : filterType === "zones" ? (
|
||||||
|
|||||||
@ -349,7 +349,7 @@ function ReviewGroup({
|
|||||||
? fetchedEvents.length
|
? fetchedEvents.length
|
||||||
: (review.data.objects ?? []).length;
|
: (review.data.objects ?? []).length;
|
||||||
|
|
||||||
return `${objectCount} ${t("detail.trackedObject", { count: objectCount })}`;
|
return `${t("detail.trackedObject", { count: objectCount })}`;
|
||||||
}, [review, t, fetchedEvents]);
|
}, [review, t, fetchedEvents]);
|
||||||
|
|
||||||
const reviewDuration = useMemo(
|
const reviewDuration = useMemo(
|
||||||
@ -478,7 +478,7 @@ function ReviewGroup({
|
|||||||
<div className="rounded-full bg-muted-foreground p-1">
|
<div className="rounded-full bg-muted-foreground p-1">
|
||||||
{getIconForLabel(audioLabel, "size-3 text-white")}
|
{getIconForLabel(audioLabel, "size-3 text-white")}
|
||||||
</div>
|
</div>
|
||||||
<span>{getTranslatedLabel(audioLabel)}</span>
|
<span>{getTranslatedLabel(audioLabel, "audio")}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@ -513,7 +513,28 @@ function EventList({
|
|||||||
|
|
||||||
const isSelected = selectedObjectIds.includes(event.id);
|
const isSelected = selectedObjectIds.includes(event.id);
|
||||||
|
|
||||||
const label = event.sub_label || getTranslatedLabel(event.label);
|
const allAudioListenLabels = useMemo<string[]>(() => {
|
||||||
|
if (!config) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const labels = new Set<string>();
|
||||||
|
Object.values(config.cameras).forEach((camera) => {
|
||||||
|
if (camera?.audio?.enabled) {
|
||||||
|
camera.audio.listen.forEach((label) => {
|
||||||
|
labels.add(label);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return [...labels].sort();
|
||||||
|
}, [config]);
|
||||||
|
|
||||||
|
const label =
|
||||||
|
event.sub_label ||
|
||||||
|
getTranslatedLabel(
|
||||||
|
event.label,
|
||||||
|
allAudioListenLabels.includes(event.label) ? "audio" : "object",
|
||||||
|
);
|
||||||
|
|
||||||
const handleObjectSelect = (event: Event | undefined) => {
|
const handleObjectSelect = (event: Event | undefined) => {
|
||||||
if (event) {
|
if (event) {
|
||||||
|
|||||||
@ -649,7 +649,7 @@ export function RecordingView({
|
|||||||
value="detail"
|
value="detail"
|
||||||
aria-label="Detail Stream"
|
aria-label="Detail Stream"
|
||||||
>
|
>
|
||||||
<div className="">Detail</div>
|
<div className="">{t("detail.label")}</div>
|
||||||
</ToggleGroupItem>
|
</ToggleGroupItem>
|
||||||
</ToggleGroup>
|
</ToggleGroup>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user