Faces in VirtuoGrid are sizing correctly

Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
James Ketr 2023-01-27 16:49:50 -08:00
parent f1c1b79672
commit 34960de283
2 changed files with 56 additions and 43 deletions

View File

@ -50,6 +50,7 @@ div {
overflow-y: scroll; overflow-y: scroll;
overflow-x: clip; overflow-x: clip;
width: 100%; width: 100%;
max-height: 100%; /* scroll if too large */
gap: 0.25rem; gap: 0.25rem;
grid-template-columns: repeat(auto-fill, minmax(4.25rem, auto)); grid-template-columns: repeat(auto-fill, minmax(4.25rem, auto));
} }
@ -183,8 +184,10 @@ button {
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
justify-content: center; justify-content: center;
min-width: 8rem; min-width: 9.5rem;
min-height: 8rem; min-height: 9.5rem;
width: 100%;
height: 100%;
} }
.Cluster { .Cluster {
@ -211,18 +214,20 @@ button {
object-fit: contain; object-fit: contain;
max-width: 100%; max-width: 100%;
max-height: 100%; max-height: 100%;
position: relative;
} }
.Image img { .Image img {
object-fit: cover; /* contain */ object-fit: cover; /* contain */
width: 100%; width: 100%;
height: 100%; height: 100%;
position: absolute;
} }
.Cluster .Faces { .Cluster .Faces {
display: grid; display: grid;
gap: 0.25rem; gap: 0.25rem;
grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr)); grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
width: 100%; width: 100%;
flex-wrap: wrap; flex-wrap: wrap;
} }

View File

@ -206,17 +206,15 @@ type ClusterProps = {
setIdentity(identity: IdentityData): void, setIdentity(identity: IdentityData): void,
identities: IdentityData[], identities: IdentityData[],
setIdentities(identiteis: IdentityData[]): void, setIdentities(identiteis: IdentityData[]): void,
setImage(image: number): void,
selected: number[], selected: number[],
setSelected(selected: number[]): void, onFaceClick(e: any, face: FaceData): void
}; };
const Cluster = ({ const Cluster = ({
identity, setIdentity, identity, setIdentity,
identities, setIdentities, identities, setIdentities,
selected, selected,
setSelected, onFaceClick
setImage,
}: ClusterProps) => { }: ClusterProps) => {
const [lastName, setLastName] = useState<string>(identity.lastName); const [lastName, setLastName] = useState<string>(identity.lastName);
const [firstName, setFirstName] = useState<string>(identity.firstName); const [firstName, setFirstName] = useState<string>(identity.firstName);
@ -254,29 +252,6 @@ const Cluster = ({
setDisplayName(identity.displayName); setDisplayName(identity.displayName);
}, [identity]); }, [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 () => { const deleteIdentity = async () => {
if (!identity || identity.identityId === -1) { if (!identity || identity.identityId === -1) {
return; return;
@ -401,7 +376,7 @@ const Cluster = ({
(x: number) => x === face.faceId) !== -1 (x: number) => x === face.faceId) !== -1
} }
face={face} face={face}
onFaceClick={faceClicked} onFaceClick={onFaceClick}
title={face.distance} /> title={face.distance} />
)} )}
/> />
@ -811,6 +786,7 @@ const App = () => {
}); });
const faces = await res.json(); const faces = await res.json();
setGuess(faces[0]); setGuess(faces[0]);
setImage(0);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} }
@ -861,22 +837,55 @@ const App = () => {
const guessOnFaceClick = (e: any, face: FaceData) => { 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 identityId = face.identityId;
const el = e.currentTarget; const el = e.currentTarget;
/* Control -- select / deselect single item */ /* Control -- select / deselect single item */
if (e.ctrlKey) { if (e.ctrlKey) {
let set = !el.classList.contains('Selected'); const identityId = +el.getAttribute('data-identity-id');
[...document.querySelectorAll('.Identities .Selected')].forEach(item => { /* Remove all Identity selections */
item.classList.remove('Selected') [...document.querySelectorAll('.Identities .Selected')]
}); .forEach(el => el.classList.remove('Selected'));
if (set) { const index = selectedIdentities.indexOf(identityId);
if (index !== -1) {
setSelectedIdentities([])
} else {
el.classList.add('Selected'); el.classList.add('Selected');
setSelectedIdentities([ identityId ]);
} }
const tmp = [...document.querySelectorAll('.Identities .Selected')]
.map((face: any) => +face.getAttribute('data-identity-id'));
setSelectedIdentities(tmp);
return; return;
} }
@ -898,7 +907,7 @@ const App = () => {
loadIdentity(identityId); loadIdentity(identityId);
} }
} }, [setSelectedIdentities, selectedIdentities]);
return ( return (
<div className="App"> <div className="App">
@ -911,9 +920,8 @@ const App = () => {
setIdentity, setIdentity,
identities, identities,
setIdentities, setIdentities,
setImage,
selected, selected,
setSelected, onFaceClick: onClusterFaceClicked
}} /> }} />
<div className="Actions"> <div className="Actions">
{ selected.length === 1 && <> { selected.length === 1 && <>