diff --git a/frigate/api/app.py b/frigate/api/app.py index 5860377e7..f6e9471f2 100644 --- a/frigate/api/app.py +++ b/frigate/api/app.py @@ -20,7 +20,7 @@ from fastapi.encoders import jsonable_encoder from fastapi.params import Depends from fastapi.responses import JSONResponse, PlainTextResponse, StreamingResponse from markupsafe import escape -from peewee import operator +from peewee import SQL, operator from pydantic import ValidationError from frigate.api.auth import require_role @@ -685,7 +685,14 @@ def plusModels(request: Request, filterByCurrentModelDetector: bool = False): @router.get("/recognized_license_plates") def get_recognized_license_plates(split_joined: Optional[int] = None): try: - events = Event.select(Event.data).distinct() + query = ( + Event.select( + SQL("json_extract(data, '$.recognized_license_plate') AS plate") + ) + .where(SQL("json_extract(data, '$.recognized_license_plate') IS NOT NULL")) + .distinct() + ) + recognized_license_plates = [row[0] for row in query.tuples()] except Exception: return JSONResponse( content=( @@ -694,14 +701,6 @@ def get_recognized_license_plates(split_joined: Optional[int] = None): status_code=404, ) - recognized_license_plates = [] - for e in events: - if e.data is not None and "recognized_license_plate" in e.data: - recognized_license_plates.append(e.data["recognized_license_plate"]) - - while None in recognized_license_plates: - recognized_license_plates.remove(None) - if split_joined: original_recognized_license_plates = recognized_license_plates.copy() for recognized_license_plate in original_recognized_license_plates: diff --git a/web/src/components/overlay/dialog/SearchFilterDialog.tsx b/web/src/components/overlay/dialog/SearchFilterDialog.tsx index e3c54e021..b9c03c796 100644 --- a/web/src/components/overlay/dialog/SearchFilterDialog.tsx +++ b/web/src/components/overlay/dialog/SearchFilterDialog.tsx @@ -42,6 +42,7 @@ import { CommandList, } from "@/components/ui/command"; import { LuCheck } from "react-icons/lu"; +import ActivityIndicator from "@/components/indicators/activity-indicator"; type SearchFilterDialogProps = { config?: FrigateConfig; @@ -64,6 +65,9 @@ export default function SearchFilterDialog({ const { t } = useTranslation(["components/filter"]); const [currentFilter, setCurrentFilter] = useState(filter ?? {}); const { data: allSubLabels } = useSWR(["sub_labels", { split_joined: 1 }]); + const { data: allRecognizedLicensePlates } = useSWR( + "recognized_license_plates", + ); useEffect(() => { if (filter) { @@ -130,6 +134,7 @@ export default function SearchFilterDialog({ } /> setCurrentFilter({ @@ -875,6 +880,7 @@ export function SnapshotClipFilterContent({ } type RecognizedLicensePlatesFilterContentProps = { + allRecognizedLicensePlates: string[] | undefined; recognizedLicensePlates: string[] | undefined; setRecognizedLicensePlates: ( recognizedLicensePlates: string[] | undefined, @@ -882,18 +888,12 @@ type RecognizedLicensePlatesFilterContentProps = { }; export function RecognizedLicensePlatesFilterContent({ + allRecognizedLicensePlates, recognizedLicensePlates, setRecognizedLicensePlates, }: RecognizedLicensePlatesFilterContentProps) { const { t } = useTranslation(["components/filter"]); - const { data: allRecognizedLicensePlates, error } = useSWR( - "recognized_license_plates", - { - revalidateOnFocus: false, - }, - ); - const [selectedRecognizedLicensePlates, setSelectedRecognizedLicensePlates] = useState(recognizedLicensePlates || []); const [inputValue, setInputValue] = useState(""); @@ -923,7 +923,7 @@ export function RecognizedLicensePlatesFilterContent({ } }; - if (!allRecognizedLicensePlates || allRecognizedLicensePlates.length === 0) { + if (allRecognizedLicensePlates && allRecognizedLicensePlates.length === 0) { return null; } @@ -947,15 +947,12 @@ export function RecognizedLicensePlatesFilterContent({
{t("recognizedLicensePlates.title")}
- {error ? ( -

- {t("recognizedLicensePlates.loadFailed")} -

- ) : !allRecognizedLicensePlates ? ( -

- {t("recognizedLicensePlates.loading")} -

- ) : ( + {allRecognizedLicensePlates == undefined ? ( +
+ +

{t("recognizedLicensePlates.loading")}

+
+ ) : allRecognizedLicensePlates.length == 0 ? null : ( <> )} +

+ {t("recognizedLicensePlates.selectPlatesFromList")} +

)} -

- {t("recognizedLicensePlates.selectPlatesFromList")} -

); }