diff --git a/web/apps/photos/src/components/MachineLearning/FaceCropImageView.tsx b/web/apps/photos/src/components/MachineLearning/FaceCropImageView.tsx new file mode 100644 index 000000000..d5b364cc9 --- /dev/null +++ b/web/apps/photos/src/components/MachineLearning/FaceCropImageView.tsx @@ -0,0 +1,66 @@ +import log from "@/next/log"; +import { cached } from "@ente/shared/storage/cache"; +import { getData, LS_KEYS } from "@ente/shared/storage/localStorage"; +import { User } from "@ente/shared/user/types"; +import { Skeleton } from "@mui/material"; +import { useEffect, useState } from "react"; +import machineLearningService from "services/machineLearning/machineLearningService"; + +interface FaceCropImageViewProps { + url: string; + faceID: string; +} + +export const FaceCropImageView: React.FC = ({ + url, + faceID, +}) => { + const [objectURL, setObjectURL] = useState(); + + useEffect(() => { + let didCancel = false; + + async function loadImage() { + const user: User = getData(LS_KEYS.USER); + let blob: Blob; + if (!url || !user) { + blob = undefined; + } else { + blob = await cached("face-crops", url, async () => { + try { + log.debug( + () => + `ImageCacheView: regenerate face crop for ${faceID}`, + ); + return machineLearningService.regenerateFaceCrop( + user.token, + user.id, + faceID, + ); + } catch (e) { + log.error( + "ImageCacheView: regenerate face crop failed", + e, + ); + } + }); + } + + if (didCancel) return; + setObjectURL(URL.createObjectURL(blob)); + } + + loadImage(); + + return () => { + didCancel = true; + if (objectURL) URL.revokeObjectURL(objectURL); + }; + }, [url, faceID]); + + return objectURL ? ( + + ) : ( + + ); +}; diff --git a/web/apps/photos/src/components/MachineLearning/ImageViews.tsx b/web/apps/photos/src/components/MachineLearning/ImageViews.tsx deleted file mode 100644 index ccc79b430..000000000 --- a/web/apps/photos/src/components/MachineLearning/ImageViews.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import log from "@/next/log"; -import { cached } from "@ente/shared/storage/cache"; -import { getData, LS_KEYS } from "@ente/shared/storage/localStorage"; -import { User } from "@ente/shared/user/types"; -import { Skeleton } from "@mui/material"; -import { useEffect, useState } from "react"; -import machineLearningService from "services/machineLearning/machineLearningService"; - -interface FaceCropImageViewProps { - url: string; - faceID: string; -} - -export const FaceCropImageView: React.FC = ({ - url, - faceID, -}) => { - const [imageBlob, setImageBlob] = useState(); - - useEffect(() => { - let didCancel = false; - async function loadImage() { - try { - const user: User = getData(LS_KEYS.USER); - let blob: Blob; - if (!url || !user) { - blob = undefined; - } else { - blob = await cached("face-crops", url, async () => { - try { - log.debug( - () => - `ImageCacheView: regenerate face crop for ${faceID}`, - ); - return machineLearningService.regenerateFaceCrop( - user.token, - user.id, - faceID, - ); - } catch (e) { - log.error( - "ImageCacheView: regenerate face crop failed", - e, - ); - } - }); - } - - !didCancel && setImageBlob(blob); - } catch (e) { - log.error("ImageCacheView useEffect failed", e); - } - } - loadImage(); - return () => { - didCancel = true; - }; - }, [url, faceID]); - - return ; -}; - -const ImageBlobView = (props: { blob: Blob }) => { - const [imgUrl, setImgUrl] = useState(); - - useEffect(() => { - try { - setImgUrl(props.blob && URL.createObjectURL(props.blob)); - } catch (e) { - console.error( - "ImageBlobView: can not create object url for blob: ", - props.blob, - e, - ); - } - }, [props.blob]); - - return imgUrl ? ( - - ) : ( - - ); -}; diff --git a/web/apps/photos/src/components/MachineLearning/PeopleList.tsx b/web/apps/photos/src/components/MachineLearning/PeopleList.tsx index 7198aa267..397227693 100644 --- a/web/apps/photos/src/components/MachineLearning/PeopleList.tsx +++ b/web/apps/photos/src/components/MachineLearning/PeopleList.tsx @@ -10,7 +10,7 @@ import { getPeopleList, getUnidentifiedFaces, } from "utils/machineLearning"; -import { FaceCropImageView } from "./ImageViews"; +import { FaceCropImageView } from "./FaceCropImageView"; const FaceChipContainer = styled("div")` display: flex;