From e8de846ed0842d8a56ab3ab3f155c93eff40791b Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Mon, 16 Jan 2023 18:11:33 -0800 Subject: [PATCH] Identities are loading; starting to think through workflow Signed-off-by: James Ketrenos --- client/src/App.css | 32 ++++++--- client/src/App.tsx | 154 ++++++++++++++++++++++++++++++------------ client/src/useApi.tsx | 9 ++- reset-identities.sh | 7 ++ 4 files changed, 146 insertions(+), 56 deletions(-) create mode 100644 reset-identities.sh diff --git a/client/src/App.css b/client/src/App.css index 09fc090..9367a7d 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -26,20 +26,30 @@ div { border: 1px solid green; } -.Identity { +.Face { display: flex; + box-sizing: border-box; flex-direction: column; position: relative; - margin: 0.125rem; - border: 1px solid transparent; } -.Identity:hover { - border: 1px solid yellow; +.Face:hover { cursor: pointer; } -.Identity .Title { +.Face .Image { + border: 0.25rem solid transparent; +} + +.Face:hover .Image { + border: 0.25rem solid yellow; +} + +.Face.Selected .Image { + border: 0.25rem solid blue; +} + +.Face .Title { position: absolute; top: 0; left: 0; @@ -50,7 +60,9 @@ div { color: white; } -.Identity .Face { +.Face .Image { + position: relative; + box-sizing: border-box; width: 8rem; height: 8rem; background-size: contain !important; @@ -58,16 +70,18 @@ div { background-position: 50% 50% !important;; } - .Cluster { display: flex; flex-direction: column; overflow-y: scroll; flex-grow: 1; - border: 1px solid red; padding: 0.5rem; } +.Cluster .Face.Selected { +/* filter: grayscale(100%); */ +} + .Cluster .Info { display: flex; flex-direction: column; diff --git a/client/src/App.tsx b/client/src/App.tsx index 769f041..e117a7d 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -3,6 +3,21 @@ import React, { useState, useMemo, useEffect } from 'react'; import { useApi } from './useApi'; import './App.css'; +const Face = ({ faceId, onClick, title }: any) => { + const idPath = String(faceId % 100).padStart(2, '0'); + return ( +
{ onClick(e, faceId) }} + className='Face'> +
+
{title}
+
+
+ ); +}; + type ClusterProps = { id: number }; @@ -23,48 +38,113 @@ const Cluster = ({ id }: ClusterProps) => { } }, [data]); + + const relatedFacesJSX = useMemo(() => { + const faceClicked = (e: any, id: any) => { + if (!identity) { + return; + } + const el = e.currentTarget; + const face = identity.relatedFaces.find(item => item.faceId === id); + el.classList.toggle('Selected'); + console.log(face); + } if (identity === undefined) { return <>; } - return identity.relatedFaces.map((face) => { - const idPath = String(face.faceId % 100).padStart(2, '0'); - return ( -
-
- {face.distance} -
-
-
- ); - }); + return identity.relatedFaces.map(face => + + ); }, [identity]); + const lastNameChanged = (e: any) => { + setIdentity(Object.assign( + {}, + identity, { + lastName: e.currentTarget.value + } + )); + }; + const firstNameChanged = (e: any) => { + setIdentity(Object.assign( + {}, + identity, { + firstName: e.currentTarget.value + } + )); + }; + const middleNameChanged = (e: any) => { + setIdentity(Object.assign( + {}, + identity, { + middleName: e.currentTarget.value + } + )); + }; + const displayNameChanged = (e: any) => { + setIdentity(Object.assign( + {}, + identity, { + displayName: e.currentTarget.value + } + )); + }; + + if (loading) { + return (
+ {loading && `Loading ${id}...`} +
); + } + + if (identity === undefined) { + return (
+ Select identity to load. +
); + } + return (
- { loading && `Loading ${id}`} - { identity !== undefined &&
-
{identity.lastName}
-
{identity.firstName}
-
{identity.middleName}
-
{identity.displayName}
+
+
+
+
+
+
Faces: {identity.relatedFaces.length}
-
} - { identity !== undefined &&
+ +
+
{ relatedFacesJSX } -
} +
); }; -type Face = { - distance: number, +type FaceData = { faceId: number, - photoId: number + lastName: string, + firstName: string, + middleName: string, + displayName: string, + identityId: number, + distance: number, + descriptors: any[] }; type Identity = { @@ -74,7 +154,7 @@ type Identity = { descriptors: number[], id: number displayName: string, - relatedFaces: Face[] + relatedFaces: FaceData[] }; interface IdentitiesProps { @@ -83,8 +163,6 @@ interface IdentitiesProps { }; const Identities = ({ identities, setIdentity } : IdentitiesProps) => { - - const identitiesJSX = useMemo(() => { const loadIdentity = (id: number): void => { if (setIdentity) { @@ -93,19 +171,11 @@ const Identities = ({ identities, setIdentity } : IdentitiesProps) => { }; return identities.map((identity) => { const face = identity.relatedFaces[0]; - const idPath = String(face.faceId % 100).padStart(2, '0'); return ( -
loadIdentity(identity.id)} - className='Identity'> -
- {identity.displayName} -
-
-
+ title={identity.displayName}/> ); }); }, [ setIdentity, identities ]); @@ -133,7 +203,7 @@ const App = () => { return (
- { loading &&
Loading...
} + { loading &&
Loading...
} { !loading && identity !== 0 && } { !loading && identity === 0 &&
Select identity to edit diff --git a/client/src/useApi.tsx b/client/src/useApi.tsx index ef6d04a..7416bf9 100644 --- a/client/src/useApi.tsx +++ b/client/src/useApi.tsx @@ -8,31 +8,30 @@ type UseApi = { }; const useApi = (_url: string, _options?: {}) : UseApi => { - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); const [data, setData] = useState(undefined); const [error, setError] = useState(undefined); useEffect(() => { - if (_url === '' || loading) { + if (_url === '') { return; } const fetchApi = async () => { console.log(`Fetching ${_url}...`); - setLoading(true); try { const res = await window.fetch(_url, _options); const data = await res.json(); setData(data); + setLoading(false); } catch (e) { console.log(e); setError(e) - } finally { setLoading(false); }; }; fetchApi(); - }, [_url, _options, loading]); + }, [_url, _options]); return { loading, data, error }; }; diff --git a/reset-identities.sh b/reset-identities.sh new file mode 100644 index 0000000..3170641 --- /dev/null +++ b/reset-identities.sh @@ -0,0 +1,7 @@ +#!/bin/bash +. .env +cat << EOF | ./query.sh +update faces set identityId=NULL where identityId is not null; +delete from identities where id>0; +delete from sqlite_sequence where name='identities'; +EOF