diff --git a/client/src/App.css b/client/src/App.css index af6ba70..49cfaec 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -50,6 +50,7 @@ div { overflow-y: scroll; overflow-x: clip; width: 100%; + max-height: 100%; /* scroll if too large */ gap: 0.25rem; grid-template-columns: repeat(auto-fill, minmax(4.25rem, auto)); } @@ -183,8 +184,10 @@ button { box-sizing: border-box; display: flex; justify-content: center; - min-width: 8rem; - min-height: 8rem; + min-width: 9.5rem; + min-height: 9.5rem; + width: 100%; + height: 100%; } .Cluster { @@ -211,18 +214,20 @@ button { object-fit: contain; max-width: 100%; max-height: 100%; + position: relative; } .Image img { object-fit: cover; /* contain */ width: 100%; height: 100%; + position: absolute; } .Cluster .Faces { display: grid; gap: 0.25rem; - grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr)); + grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); width: 100%; flex-wrap: wrap; } \ No newline at end of file diff --git a/client/src/App.tsx b/client/src/App.tsx index d950ee0..81439df 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -206,17 +206,15 @@ type ClusterProps = { setIdentity(identity: IdentityData): void, identities: IdentityData[], setIdentities(identiteis: IdentityData[]): void, - setImage(image: number): void, selected: number[], - setSelected(selected: number[]): void, + onFaceClick(e: any, face: FaceData): void }; const Cluster = ({ identity, setIdentity, identities, setIdentities, selected, - setSelected, - setImage, + onFaceClick }: ClusterProps) => { const [lastName, setLastName] = useState(identity.lastName); const [firstName, setFirstName] = useState(identity.firstName); @@ -254,29 +252,6 @@ const Cluster = ({ setDisplayName(identity.displayName); }, [identity]); - const faceClicked = useCallback((e: any, face: FaceData) => { - const el = e.currentTarget; - - /* Control -- select / deselect single item */ - if (e.ctrlKey) { - el.classList.toggle('Selected'); - const tmp = [...document.querySelectorAll('.Cluster .Selected')] - .map((face: any) => +face.getAttribute('data-face-id')); - setSelected(tmp); - return; - } - - /* Shift -- select groups */ - if (e.shiftKey) { - return; - } - - /* Default to load image */ - e.stopPropagation(); - e.preventDefault(); - setImage(face.photoId); - }, [setSelected, setImage]); - const deleteIdentity = async () => { if (!identity || identity.identityId === -1) { return; @@ -401,7 +376,7 @@ const Cluster = ({ (x: number) => x === face.faceId) !== -1 } face={face} - onFaceClick={faceClicked} + onFaceClick={onFaceClick} title={face.distance} /> )} /> @@ -811,6 +786,7 @@ const App = () => { }); const faces = await res.json(); setGuess(faces[0]); + setImage(0); } catch (error) { console.error(error); } @@ -861,22 +837,55 @@ const App = () => { const guessOnFaceClick = (e: any, face: FaceData) => { }; - const identitiesOnFaceClick = (e: any, face: FaceData) => { + const onClusterFaceClicked = useCallback((e: any, face: FaceData) => { + const el = e.currentTarget; + + /* Control -- select / deselect single item */ + if (e.ctrlKey) { + const faceId = +el.getAttribute('data-face-id') + el.classList.toggle('Selected'); + const index = selected.indexOf(faceId); + if (index !== -1) { + el.classList.remove('Selected'); + selected.splice(index, 1); + } else { + el.classList.add('Selected'); + selected.push(faceId); + } + setSelected([...selected]); + return; + } + + /* Shift -- select groups */ + if (e.shiftKey) { + return; + } + + /* Default to load image */ + e.stopPropagation(); + e.preventDefault(); + setGuess(undefined); + setImage(face.photoId); + }, [selected, setSelected, setImage]); + + + const identitiesOnFaceClick = useCallback((e: any, face: FaceData) => { const identityId = face.identityId; const el = e.currentTarget; /* Control -- select / deselect single item */ if (e.ctrlKey) { - let set = !el.classList.contains('Selected'); - [...document.querySelectorAll('.Identities .Selected')].forEach(item => { - item.classList.remove('Selected') - }); - if (set) { + const identityId = +el.getAttribute('data-identity-id'); + /* Remove all Identity selections */ + [...document.querySelectorAll('.Identities .Selected')] + .forEach(el => el.classList.remove('Selected')); + const index = selectedIdentities.indexOf(identityId); + if (index !== -1) { + setSelectedIdentities([]) + } else { el.classList.add('Selected'); + setSelectedIdentities([ identityId ]); } - const tmp = [...document.querySelectorAll('.Identities .Selected')] - .map((face: any) => +face.getAttribute('data-identity-id')); - setSelectedIdentities(tmp); return; } @@ -898,7 +907,7 @@ const App = () => { loadIdentity(identityId); } - } + }, [setSelectedIdentities, selectedIdentities]); return (
@@ -911,9 +920,8 @@ const App = () => { setIdentity, identities, setIdentities, - setImage, selected, - setSelected, + onFaceClick: onClusterFaceClicked }} />
{ selected.length === 1 && <>