diff --git a/client/src/App.css b/client/src/App.css index 7eaa53a..70c65b6 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -19,12 +19,19 @@ div { height: 100%; } -.Resizer { +.Explorer .Resizer { width: 0.5rem; background-color: #ccc; border: 1px solid black; } +.ExplorerVertical .Resizer { + height: 0.5rem; + width: 100%; + background-color: #ccc; + border: 1px solid black; +} + .Explorer { display: flex; flex-direction: row; @@ -35,6 +42,16 @@ div { flex-grow: 1; } +.ExplorerVertical { + display: flex; + flex-direction: column; + justify-self: stretch; + align-self: stretch; + width: 100%; + height: auto !important; + flex-grow: 1; +} + .Actions { display: flex; flex-direction: row; @@ -48,7 +65,6 @@ div { .Identities { display: grid; user-select: none; - overflow-y: scroll; overflow-x: clip; width: 100%; max-height: 100%; /* scroll if too large */ @@ -61,6 +77,7 @@ div { .Identities { grid-template-columns: repeat(auto-fill, minmax(4.25rem, auto)); + overflow-y: scroll; } .Face { @@ -81,18 +98,26 @@ div { flex-direction: column; } -.Viewer { - display: flex; - flex-direction: column; - position: relative; - height: 100%; -} - .PhotoPanel { display: flex; flex-direction: column; justify-content: center; max-height: 100%; + overflow-y: auto; +} + +.PhotoPanel .FaceInfo { + padding: 0.25rem; + background-color: #444; + color: white; + margin-top: 0.25rem; +} + +.PhotoPanel .ImageInfo { + padding: 0.25rem; + background-color: #222; + color: white; + margin-top: 0.25rem; } .Guess { @@ -130,19 +155,7 @@ button { .Photo { display: flex; position: relative; -} - -.PhotoPanel .FaceInfo { - padding: 0.25rem; - background-color: #444; - color: white; - margin-top: 0.25rem;} - -.PhotoPanel .ImageInfo { - padding: 0.25rem; - background-color: #222; - color: white; - margin-top: 0.25rem; + flex-direction: column; } .PhotoFaces .UnknownFace, diff --git a/client/src/App.tsx b/client/src/App.tsx index 88e48da..edd8907 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -118,7 +118,6 @@ const Photo = ({ photoId, onFaceClick }: any) => { } }, [setDimensions, dimensions]); - useEffect(() => { let timer = setInterval(() => checkResize(), 250); return () => { clearInterval(timer); } @@ -152,6 +151,9 @@ const Photo = ({ photoId, onFaceClick }: any) => { }); await res.json(); setPhotoSelected([]); + photo.faces = photo.faces.filter( + face => photoSelected.findIndex(x => x.faceId === face.faceId) === -1 + ); setPhoto({...photo}); } catch (error) { console.error(error); @@ -196,7 +198,8 @@ const Photo = ({ photoId, onFaceClick }: any) => { return <> } - return (
+ return ( +
{photo.filename} {
- { photoSelected.length !== 0 &&
Selected faces (CTRL-CLICK to remove):
} + { photoSelected.length !== 0 &&
+ Selected faces (CTRL-CLICK to remove): +
}
{ photoSelected.map(face => {
- -
- {image === 0 &&
Select image to view
} - {image !== 0 && } - {guess !== undefined && guess.identity &&
- -
} -
-
+ <> + { image === 0 && +
Select image to view
+ } + { image !== 0 && + + } + { guess !== undefined && guess.identity &&
+ +
} +
{ !loaded &&
diff --git a/server/routes/identities.js b/server/routes/identities.js index 458e7a0..66a2bba 100755 --- a/server/routes/identities.js +++ b/server/routes/identities.js @@ -448,8 +448,12 @@ router.put("/faces/add/:id", async (req, res) => { /* Do not block on this call finishing -- update can occur * in the background */ Promise.map([identity, ...tuples], (x, i) => { + if (x.identityId === null) { + /* Moving from the Unknown group */ + return; + } try { - updateIdentityFaces(x); + updateIdentityFaces(x); } catch (error) { console.log(i, x); throw error; diff --git a/server/routes/photos.js b/server/routes/photos.js index 1c3f110..392aa37 100755 --- a/server/routes/photos.js +++ b/server/routes/photos.js @@ -1109,6 +1109,7 @@ router.get("/:id", async (req, res) => { ` SELECT faces.* FROM faces WHERE faces.photoId=:id + AND faces.classifiedBy NOT IN ('not-a-face', 'forget' ) `, { replacements: { id }, type: photoDB.Sequelize.QueryTypes.SELECT