Working fairly well
Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
parent
e5a55de73c
commit
a71fb177e9
@ -19,12 +19,19 @@ div {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Resizer {
|
.Explorer .Resizer {
|
||||||
width: 0.5rem;
|
width: 0.5rem;
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ExplorerVertical .Resizer {
|
||||||
|
height: 0.5rem;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #ccc;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
.Explorer {
|
.Explorer {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -35,6 +42,16 @@ div {
|
|||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ExplorerVertical {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-self: stretch;
|
||||||
|
align-self: stretch;
|
||||||
|
width: 100%;
|
||||||
|
height: auto !important;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.Actions {
|
.Actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -48,7 +65,6 @@ div {
|
|||||||
.Identities {
|
.Identities {
|
||||||
display: grid;
|
display: grid;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
overflow-y: scroll;
|
|
||||||
overflow-x: clip;
|
overflow-x: clip;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-height: 100%; /* scroll if too large */
|
max-height: 100%; /* scroll if too large */
|
||||||
@ -61,6 +77,7 @@ div {
|
|||||||
|
|
||||||
.Identities {
|
.Identities {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(4.25rem, auto));
|
grid-template-columns: repeat(auto-fill, minmax(4.25rem, auto));
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Face {
|
.Face {
|
||||||
@ -81,18 +98,26 @@ div {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Viewer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.PhotoPanel {
|
.PhotoPanel {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
max-height: 100%;
|
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 {
|
.Guess {
|
||||||
@ -130,19 +155,7 @@ button {
|
|||||||
.Photo {
|
.Photo {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
flex-direction: column;
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.PhotoFaces .UnknownFace,
|
.PhotoFaces .UnknownFace,
|
||||||
|
@ -118,7 +118,6 @@ const Photo = ({ photoId, onFaceClick }: any) => {
|
|||||||
}
|
}
|
||||||
}, [setDimensions, dimensions]);
|
}, [setDimensions, dimensions]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let timer = setInterval(() => checkResize(), 250);
|
let timer = setInterval(() => checkResize(), 250);
|
||||||
return () => { clearInterval(timer); }
|
return () => { clearInterval(timer); }
|
||||||
@ -152,6 +151,9 @@ const Photo = ({ photoId, onFaceClick }: any) => {
|
|||||||
});
|
});
|
||||||
await res.json();
|
await res.json();
|
||||||
setPhotoSelected([]);
|
setPhotoSelected([]);
|
||||||
|
photo.faces = photo.faces.filter(
|
||||||
|
face => photoSelected.findIndex(x => x.faceId === face.faceId) === -1
|
||||||
|
);
|
||||||
setPhoto({...photo});
|
setPhoto({...photo});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -196,7 +198,8 @@ const Photo = ({ photoId, onFaceClick }: any) => {
|
|||||||
return <></>
|
return <></>
|
||||||
}
|
}
|
||||||
|
|
||||||
return (<div className="PhotoPanel">
|
return (
|
||||||
|
<div className="PhotoPanel">
|
||||||
<div className="Photo" ref={ref}>
|
<div className="Photo" ref={ref}>
|
||||||
<img
|
<img
|
||||||
alt={photo.filename}
|
alt={photo.filename}
|
||||||
@ -217,7 +220,9 @@ const Photo = ({ photoId, onFaceClick }: any) => {
|
|||||||
<Button onClick={selectAll}>Select All</Button>
|
<Button onClick={selectAll}>Select All</Button>
|
||||||
<Button onClick={clearSelection}>Select None</Button>
|
<Button onClick={clearSelection}>Select None</Button>
|
||||||
</div>
|
</div>
|
||||||
{ photoSelected.length !== 0 && <div>Selected faces (CTRL-CLICK to remove):</div> }
|
{ photoSelected.length !== 0 && <div style={{ display: 'flex' }}>
|
||||||
|
Selected faces (CTRL-CLICK to remove):
|
||||||
|
</div> }
|
||||||
<div className="PhotoFaces">
|
<div className="PhotoFaces">
|
||||||
{ photoSelected.map(face =>
|
{ photoSelected.map(face =>
|
||||||
<Face
|
<Face
|
||||||
@ -1046,19 +1051,21 @@ const App = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Panel>
|
</Panel>
|
||||||
<PanelResizeHandle className="Resizer"/>
|
<PanelResizeHandle className="Resizer"/>
|
||||||
<Panel>
|
<Panel><>
|
||||||
<div className="Viewer">
|
{ image === 0 &&
|
||||||
{image === 0 && <div style={{ margin: '1rem' }}>Select image to view</div>}
|
<div style={{ margin: '1rem' }}>Select image to view</div>
|
||||||
{image !== 0 && <Photo onFaceClick={onFaceClick} photoId={image}/> }
|
}
|
||||||
{guess !== undefined && guess.identity && <div
|
{ image !== 0 &&
|
||||||
className="Guess">
|
<Photo onFaceClick={onFaceClick} photoId={image}/>
|
||||||
<Face
|
}
|
||||||
face={guess.identity.relatedFaces[0]}
|
{ guess !== undefined && guess.identity && <div
|
||||||
onFaceClick={guessOnFaceClick}
|
className="Guess">
|
||||||
title={`${guess.identity.displayName} (${guess.distance})`}/>
|
<Face
|
||||||
</div> }
|
face={guess.identity.relatedFaces[0]}
|
||||||
</div>
|
onFaceClick={guessOnFaceClick}
|
||||||
</Panel>
|
title={`${guess.identity.displayName} (${guess.distance})`}/>
|
||||||
|
</div> }
|
||||||
|
</></Panel>
|
||||||
<PanelResizeHandle className="Resizer" />
|
<PanelResizeHandle className="Resizer" />
|
||||||
<Panel defaultSize={8.5} minSize={8.5} className="IdentitiesList">
|
<Panel defaultSize={8.5} minSize={8.5} className="IdentitiesList">
|
||||||
{ !loaded && <div style={{ margin: '1rem' }}>
|
{ !loaded && <div style={{ margin: '1rem' }}>
|
||||||
|
@ -448,8 +448,12 @@ router.put("/faces/add/:id", async (req, res) => {
|
|||||||
/* Do not block on this call finishing -- update can occur
|
/* Do not block on this call finishing -- update can occur
|
||||||
* in the background */
|
* in the background */
|
||||||
Promise.map([identity, ...tuples], (x, i) => {
|
Promise.map([identity, ...tuples], (x, i) => {
|
||||||
|
if (x.identityId === null) {
|
||||||
|
/* Moving from the Unknown group */
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
updateIdentityFaces(x);
|
updateIdentityFaces(x);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(i, x);
|
console.log(i, x);
|
||||||
throw error;
|
throw error;
|
||||||
|
@ -1109,6 +1109,7 @@ router.get("/:id", async (req, res) => {
|
|||||||
`
|
`
|
||||||
SELECT faces.* FROM faces
|
SELECT faces.* FROM faces
|
||||||
WHERE faces.photoId=:id
|
WHERE faces.photoId=:id
|
||||||
|
AND faces.classifiedBy NOT IN ('not-a-face', 'forget' )
|
||||||
`, {
|
`, {
|
||||||
replacements: { id },
|
replacements: { id },
|
||||||
type: photoDB.Sequelize.QueryTypes.SELECT
|
type: photoDB.Sequelize.QueryTypes.SELECT
|
||||||
|
Loading…
x
Reference in New Issue
Block a user