Can now create blank identities

Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
James Ketr 2023-01-25 13:43:43 -08:00
parent df764ad342
commit b86c12fc92
3 changed files with 157 additions and 97 deletions

View File

@ -121,7 +121,15 @@ div {
.IdentityForm {
display: grid;
gap: 0.25rem;
grid-template-columns: 1fr 1fr;
align-items: center;
justify-items: flex-end;
}
.IdentityForm input {
min-height: 1rem;
padding: 0.25rem;
}
.Face.Active,
@ -145,11 +153,18 @@ div {
color: white;
}
.Info .Face .Image {
width: 10rem;
height: 10rem;
}
.Face .Image {
position: relative;
box-sizing: border-box;
display: flex;
justify-content: center;
min-width: 8rem;
min-height: 8rem;
}
.Cluster {
@ -175,8 +190,6 @@ div {
object-fit: cover; /* contain */
width: 100%;
height: 100%;
min-width: 8rem;
min-height: 8rem;
}
.Cluster .Faces {

View File

@ -209,7 +209,7 @@ const Face = ({ face, onFaceClick, title, isSelected }: any) => {
type ClusterProps = {
identity: IdentityData,
setIdentity(identity: IdentityData | undefined): void,
setIdentity(identity: IdentityData): void,
identities: IdentityData[],
setIdentities(identiteis: IdentityData[]): void,
setImage(image: number): void,
@ -275,7 +275,7 @@ const Cluster = ({
if (index !== -1) {
identities.splice(index, 1);
}
setIdentity(undefined);
setIdentity(EmptyIdentity);
setIdentities([...identities]);
} catch (error) {
console.error(error);
@ -338,6 +338,7 @@ const Cluster = ({
return (
<div className='Cluster'>
<div className="Info">
<div style={{ display: "flex", flexDirection: "row", gap: "0.25rem" }}>
<form className="IdentityForm">
<div>Last name:</div>
<input type="text"
@ -355,10 +356,19 @@ const Cluster = ({
value={identity.displayName}
onChange={displayNameChanged} />
</form>
<Face
face={identity.relatedFaces.length
? identity.relatedFaces[0]
: UnknownFace}
onFaceClick={() => {}}
title={`${identity.displayName} (${identity.facesCount})`} />
</div>
<div className="Actions">
<Button onClick={createIdentity}>Create</Button>
{ identity.identityId !== -1 && <>
<Button onClick={updateIdentity}>Update</Button>
<Button onClick={deleteIdentity}>Delete</Button>
</> }
</div>
</div>
<div>Faces: {identity.relatedFaces.length}</div>
@ -405,6 +415,32 @@ type IdentityData = {
faceId: number
};
const EmptyIdentity: IdentityData = {
lastName: '',
middleName: '',
firstName: '',
descriptors: [],
identityId: -1,
displayName: '',
relatedFaces: [],
facesCount: 0,
faceId: -1
};
const UnknownFace = {
faceId: -1,
photoId: -1,
identityId: -1,
distance: 0,
descriptors: [],
top: 0,
left: 0,
bottom: 0,
right: 0,
identity: EmptyIdentity
};
interface IdentitiesProps {
identities: IdentityData[],
onFaceClick(e: any, face: FaceData): void
@ -448,7 +484,7 @@ const App = () => {
const [identities, setIdentities] = useState<IdentityData[]>([]);
const { identityId, faceId } = useParams();
const [selectedIdentities, setSelectedIdentities] = useState<number[]>([]);
const [identity, setIdentity] = useState<IdentityData | undefined>(undefined);
const [identity, setIdentity] = useState<IdentityData>(EmptyIdentity);
const [image, setImage] = useState<number>(0);
const [guess, setGuess] = useState<FaceData|undefined>(undefined);
const { loading, data } = useApi( /* TODO: Switch away from using useApi */
@ -575,7 +611,7 @@ const App = () => {
if (index !== -1) {
identities.splice(index, 1);
}
setIdentity(undefined);
setIdentity(EmptyIdentity);
setIdentities([...identities]);
} catch (error) {
console.error(error);
@ -721,7 +757,6 @@ const App = () => {
autoSaveId="persistence" direction="horizontal">
<Panel defaultSize={50} className="ClusterEditor">
{loading && <div style={{ margin: '1rem' }}>Loading...</div>}
{ !loading && identity !== undefined &&
<Cluster {...{
identity,
setIdentity,
@ -730,7 +765,7 @@ const App = () => {
setImage,
selected,
setSelected,
}} /> }
}} />
{!loading && identity === undefined && <div className="Cluster">
Select identity to edit
</div>}

View File

@ -44,6 +44,7 @@ const upsertIdentity = async(id, {
replacements: identity
});
identity.identityId = lastId;
console.log('Created identity: ', identity)
} else {
await photoDB.sequelize.query(
`UPDATE identities ` +
@ -55,6 +56,7 @@ const upsertIdentity = async(id, {
'WHERE id=:identityId', {
replacements: identity
});
console.log('Updated identity: ', identity)
}
return identity;
@ -502,6 +504,8 @@ const updateIdentityFaces = async (identity) => {
.parseFloat(euclideanDistanceArray(identity.descriptors, average))
.toFixed(4);
const t = await photoDB.sequelize.transaction();
try {
/* If the average position has not changed, then face distances should
* not change either! */
await Promise.map(faces, async (face) => {
@ -518,7 +522,8 @@ const updateIdentityFaces = async (identity) => {
face.distance = distance;
await photoDB.sequelize.query(
'UPDATE faces SET distance=:distance WHERE id=:id', {
replacements: face
replacements: face,
transaction: t
}
);
}
@ -575,10 +580,17 @@ const updateIdentityFaces = async (identity) => {
await photoDB.sequelize.query(
`UPDATE identities SET ${sql} ` +
`WHERE id=:identityId`, {
replacements: identity
replacements: identity,
transaction: t
}
);
}
t.commit();
} catch (error) {
console.error(error);
t.rollback();
return;
}
};
router.get("/:id?", async (req, res) => {