1
Fork 0

Make people page translatable

This commit is contained in:
viktorstrate 2021-05-19 21:32:49 +02:00
parent e2f6bdb365
commit 360db25ec3
No known key found for this signature in database
GPG Key ID: 3F855605109C1E8A
16 changed files with 671 additions and 161 deletions

View File

@ -68,10 +68,58 @@
},
"people_page": {
"face_group": {
"action": {
"add_label": null,
"change_label": null,
"detach_face": null,
"merge_face": null,
"move_faces": null
},
"label_placeholder": "Navn",
"unlabeled": "Ikke navngivet"
"unlabeled": "Ikke navngivet",
"unlabeled_person": null
},
"recognize_unlabeled_faces_button": "Genkend ikke navngivede ansigter"
"modal": {
"action": {
"merge": null
},
"detach_image_faces": {
"action": {
"detach": null,
"select_images": null
},
"description": null,
"title": null
},
"merge_face_groups": {
"description": null,
"destination_table": {
"title": null
},
"title": null
},
"move_image_faces": {
"description": null,
"destination_face_group_table": {
"move_action": null,
"title": null
},
"image_select_table": {
"next_action": null,
"title": null
},
"title": null
}
},
"recognize_unlabeled_faces_button": "Genkend ikke navngivede ansigter",
"table": {
"select_face_group": {
"search_faces_placeholder": null
},
"select_image_faces": {
"search_images_placeholder": null
}
}
},
"photos_page": {
"title": "Billeder"

View File

@ -68,10 +68,58 @@
},
"people_page": {
"face_group": {
"action": {
"add_label": null,
"change_label": null,
"detach_face": null,
"merge_face": null,
"move_faces": null
},
"label_placeholder": "Zuordnung",
"unlabeled": "Nicht zugeordnet"
"unlabeled": "Nicht zugeordnet",
"unlabeled_person": null
},
"recognize_unlabeled_faces_button": "Nicht zugeordnete Gesichter erkennen"
"modal": {
"action": {
"merge": null
},
"detach_image_faces": {
"action": {
"detach": null,
"select_images": null
},
"description": null,
"title": null
},
"merge_face_groups": {
"description": null,
"destination_table": {
"title": null
},
"title": null
},
"move_image_faces": {
"description": null,
"destination_face_group_table": {
"move_action": null,
"title": null
},
"image_select_table": {
"next_action": null,
"title": null
},
"title": null
}
},
"recognize_unlabeled_faces_button": "Nicht zugeordnete Gesichter erkennen",
"table": {
"select_face_group": {
"search_faces_placeholder": null
},
"select_image_faces": {
"search_images_placeholder": null
}
}
},
"photos_page": {
"title": "Fotos"

View File

@ -68,10 +68,58 @@
},
"people_page": {
"face_group": {
"action": {
"add_label": "Add Label",
"change_label": "Change Label",
"detach_face": "Detach Face",
"merge_face": "Merge Face",
"move_faces": "Move Faces"
},
"label_placeholder": "Label",
"unlabeled": "Unlabeled"
"unlabeled": "Unlabeled",
"unlabeled_person": "Unlabeled person"
},
"recognize_unlabeled_faces_button": "Recognize unlabeled faces"
"modal": {
"action": {
"merge": "Merge"
},
"detach_image_faces": {
"action": {
"detach": "Detach image faces",
"select_images": "Select images to detach"
},
"description": "Detach selected images of this face group and move them to a new face groups",
"title": "Detach Image Faces"
},
"merge_face_groups": {
"description": "All images within this face group will be merged into the selected face group.",
"destination_table": {
"title": "Select the destination face"
},
"title": "Merge Face Groups"
},
"move_image_faces": {
"description": "Move selected images of this face group to another face group",
"destination_face_group_table": {
"move_action": "Move image faces",
"title": "Select destination face group"
},
"image_select_table": {
"next_action": "Next",
"title": "Select images to move"
},
"title": "Move Image Faces"
}
},
"recognize_unlabeled_faces_button": "Recognize unlabeled faces",
"table": {
"select_face_group": {
"search_faces_placeholder": "Search faces..."
},
"select_image_faces": {
"search_images_placeholder": "Search images..."
}
}
},
"photos_page": {
"title": "Photos"

View File

@ -68,10 +68,58 @@
},
"people_page": {
"face_group": {
"action": {
"add_label": null,
"change_label": null,
"detach_face": null,
"merge_face": null,
"move_faces": null
},
"label_placeholder": "Etiqueta",
"unlabeled": "Sin etiquetar"
"unlabeled": "Sin etiquetar",
"unlabeled_person": null
},
"recognize_unlabeled_faces_button": "Reconocer caras sin etiquetar"
"modal": {
"action": {
"merge": null
},
"detach_image_faces": {
"action": {
"detach": null,
"select_images": null
},
"description": null,
"title": null
},
"merge_face_groups": {
"description": null,
"destination_table": {
"title": null
},
"title": null
},
"move_image_faces": {
"description": null,
"destination_face_group_table": {
"move_action": null,
"title": null
},
"image_select_table": {
"next_action": null,
"title": null
},
"title": null
}
},
"recognize_unlabeled_faces_button": "Reconocer caras sin etiquetar",
"table": {
"select_face_group": {
"search_faces_placeholder": null
},
"select_image_faces": {
"search_images_placeholder": null
}
}
},
"photos_page": {
"title": "Fotos"

View File

@ -68,10 +68,58 @@
},
"people_page": {
"face_group": {
"action": {
"add_label": null,
"change_label": null,
"detach_face": null,
"merge_face": null,
"move_faces": null
},
"label_placeholder": "Étiquette",
"unlabeled": "Sans étiquette"
"unlabeled": "Sans étiquette",
"unlabeled_person": null
},
"recognize_unlabeled_faces_button": "Reconnaître les visages sans étiquette"
"modal": {
"action": {
"merge": null
},
"detach_image_faces": {
"action": {
"detach": null,
"select_images": null
},
"description": null,
"title": null
},
"merge_face_groups": {
"description": null,
"destination_table": {
"title": null
},
"title": null
},
"move_image_faces": {
"description": null,
"destination_face_group_table": {
"move_action": null,
"title": null
},
"image_select_table": {
"next_action": null,
"title": null
},
"title": null
}
},
"recognize_unlabeled_faces_button": "Reconnaître les visages sans étiquette",
"table": {
"select_face_group": {
"search_faces_placeholder": null
},
"select_image_faces": {
"search_images_placeholder": null
}
}
},
"photos_page": {
"title": "Photos"

View File

@ -68,10 +68,58 @@
},
"people_page": {
"face_group": {
"action": {
"add_label": null,
"change_label": null,
"detach_face": null,
"merge_face": null,
"move_faces": null
},
"label_placeholder": "Etichetta",
"unlabeled": "Senza etichetta"
"unlabeled": "Senza etichetta",
"unlabeled_person": null
},
"recognize_unlabeled_faces_button": "Identifica facce senza etichetta"
"modal": {
"action": {
"merge": null
},
"detach_image_faces": {
"action": {
"detach": null,
"select_images": null
},
"description": null,
"title": null
},
"merge_face_groups": {
"description": null,
"destination_table": {
"title": null
},
"title": null
},
"move_image_faces": {
"description": null,
"destination_face_group_table": {
"move_action": null,
"title": null
},
"image_select_table": {
"next_action": null,
"title": null
},
"title": null
}
},
"recognize_unlabeled_faces_button": "Identifica facce senza etichetta",
"table": {
"select_face_group": {
"search_faces_placeholder": null
},
"select_image_faces": {
"search_images_placeholder": null
}
}
},
"photos_page": {
"title": "Foto"

View File

@ -68,10 +68,58 @@
},
"people_page": {
"face_group": {
"action": {
"add_label": null,
"change_label": null,
"detach_face": null,
"merge_face": null,
"move_faces": null
},
"label_placeholder": "Etykieta",
"unlabeled": "Nieoznakowany"
"unlabeled": "Nieoznakowany",
"unlabeled_person": null
},
"recognize_unlabeled_faces_button": "Rozpoznaj nieoznakowane twarze"
"modal": {
"action": {
"merge": null
},
"detach_image_faces": {
"action": {
"detach": null,
"select_images": null
},
"description": null,
"title": null
},
"merge_face_groups": {
"description": null,
"destination_table": {
"title": null
},
"title": null
},
"move_image_faces": {
"description": null,
"destination_face_group_table": {
"move_action": null,
"title": null
},
"image_select_table": {
"next_action": null,
"title": null
},
"title": null
}
},
"recognize_unlabeled_faces_button": "Rozpoznaj nieoznakowane twarze",
"table": {
"select_face_group": {
"search_faces_placeholder": null
},
"select_image_faces": {
"search_images_placeholder": null
}
}
},
"photos_page": {
"title": "Zdjęcia"

View File

@ -68,10 +68,58 @@
},
"people_page": {
"face_group": {
"action": {
"add_label": null,
"change_label": null,
"detach_face": null,
"merge_face": null,
"move_faces": null
},
"label_placeholder": "Märkning",
"unlabeled": "Omärkt"
"unlabeled": "Omärkt",
"unlabeled_person": null
},
"recognize_unlabeled_faces_button": "Känna igen omärkta ansikten"
"modal": {
"action": {
"merge": null
},
"detach_image_faces": {
"action": {
"detach": null,
"select_images": null
},
"description": null,
"title": null
},
"merge_face_groups": {
"description": null,
"destination_table": {
"title": null
},
"title": null
},
"move_image_faces": {
"description": null,
"destination_face_group_table": {
"move_action": null,
"title": null
},
"image_select_table": {
"next_action": null,
"title": null
},
"title": null
}
},
"recognize_unlabeled_faces_button": "Känna igen omärkta ansikten",
"table": {
"select_face_group": {
"search_faces_placeholder": null
},
"select_image_faces": {
"search_images_placeholder": null
}
}
},
"photos_page": {
"title": "Bilder"

View File

@ -1,10 +1,23 @@
import { gql, useMutation } from '@apollo/client'
import PropTypes from 'prop-types'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useHistory } from 'react-router-dom'
import { Button, Modal } from 'semantic-ui-react'
import { isNil } from '../../../helpers/utils'
import { MY_FACES_QUERY } from '../PeoplePage'
import {
myFaces_myFaceGroups,
myFaces_myFaceGroups_imageFaces,
} from '../__generated__/myFaces'
import SelectImageFacesTable from './SelectImageFacesTable'
import {
detachImageFaces,
detachImageFacesVariables,
} from './__generated__/detachImageFaces'
import {
singleFaceGroup_faceGroup,
singleFaceGroup_faceGroup_imageFaces,
} from './__generated__/singleFaceGroup'
const DETACH_IMAGE_FACES_MUTATION = gql`
mutation detachImageFaces($faceIDs: [ID!]!) {
@ -15,12 +28,28 @@ const DETACH_IMAGE_FACES_MUTATION = gql`
}
`
const DetachImageFacesModal = ({ open, setOpen, faceGroup }) => {
const [selectedImageFaces, setSelectedImageFaces] = useState([])
let history = useHistory()
type DetachImageFacesModalProps = {
open: boolean
setOpen(open: boolean): void
faceGroup: myFaces_myFaceGroups | singleFaceGroup_faceGroup
}
const [detachImageFacesMutation] = useMutation(DETACH_IMAGE_FACES_MUTATION, {
variables: {},
const DetachImageFacesModal = ({
open,
setOpen,
faceGroup,
}: DetachImageFacesModalProps) => {
const { t } = useTranslation()
const [selectedImageFaces, setSelectedImageFaces] = useState<
(myFaces_myFaceGroups_imageFaces | singleFaceGroup_faceGroup_imageFaces)[]
>([])
const history = useHistory()
const [detachImageFacesMutation] = useMutation<
detachImageFaces,
detachImageFacesVariables
>(DETACH_IMAGE_FACES_MUTATION, {
refetchQueries: [
{
query: MY_FACES_QUERY,
@ -44,6 +73,7 @@ const DetachImageFacesModal = ({ open, setOpen, faceGroup }) => {
faceIDs,
},
}).then(({ data }) => {
if (isNil(data)) throw new Error('Expected data not to be null')
setOpen(false)
history.push(`/people/${data.detachImageFaces.id}`)
})
@ -57,18 +87,25 @@ const DetachImageFacesModal = ({ open, setOpen, faceGroup }) => {
onOpen={() => setOpen(true)}
open={open}
>
<Modal.Header>Detach Image Faces</Modal.Header>
<Modal.Header>
{t('people_page.modal.detach_image_faces.title', 'Detach Image Faces')}
</Modal.Header>
<Modal.Content scrolling>
<Modal.Description>
<p>
Detach selected images of this face group and move them to a new
face group
{t(
'people_page.modal.detach_image_faces.description',
'Detach selected images of this face group and move them to a new face groups'
)}
</p>
<SelectImageFacesTable
imageFaces={imageFaces}
selectedImageFaces={selectedImageFaces}
setSelectedImageFaces={setSelectedImageFaces}
title="Select images to detach"
title={t(
'people_page.modal.detach_image_faces.action.select_images',
'Select images to detach'
)}
/>
</Modal.Description>
</Modal.Content>
@ -76,7 +113,10 @@ const DetachImageFacesModal = ({ open, setOpen, faceGroup }) => {
<Button onClick={() => setOpen(false)}>Cancel</Button>
<Button
disabled={selectedImageFaces.length == 0}
content="Detach image faces"
content={t(
'people_page.modal.detach_image_faces.action.detach',
'Detach image faces'
)}
labelPosition="right"
icon="checkmark"
onClick={() => detachImageFaces()}
@ -87,10 +127,4 @@ const DetachImageFacesModal = ({ open, setOpen, faceGroup }) => {
)
}
DetachImageFacesModal.propTypes = {
open: PropTypes.bool.isRequired,
setOpen: PropTypes.func.isRequired,
faceGroup: PropTypes.object,
}
export default DetachImageFacesModal

View File

@ -1,5 +1,6 @@
import { useMutation } from '@apollo/client'
import React, { useState, useEffect, createRef } from 'react'
import { useTranslation } from 'react-i18next'
import { Dropdown, Input } from 'semantic-ui-react'
import styled from 'styled-components'
import { isNil } from '../../../helpers/utils'
@ -38,6 +39,8 @@ type FaceGroupTitleProps = {
}
const FaceGroupTitle = ({ faceGroup }: FaceGroupTitleProps) => {
const { t } = useTranslation()
const [editLabel, setEditLabel] = useState(false)
const [inputValue, setInputValue] = useState(faceGroup?.label ?? '')
const inputRef = createRef<Input>()
@ -91,7 +94,8 @@ const FaceGroupTitle = ({ faceGroup }: FaceGroupTitleProps) => {
title = (
<TitleWrapper>
<TitleLabel labeled={!!faceGroup?.label}>
{faceGroup?.label ?? 'Unlabeled person'}
{faceGroup?.label ??
t('people_page.face_group.unlabeled_person', 'Unlabeled person')}
</TitleLabel>
<TitleDropdown
icon={{
@ -102,22 +106,32 @@ const FaceGroupTitle = ({ faceGroup }: FaceGroupTitleProps) => {
<Dropdown.Menu>
<Dropdown.Item
icon="pencil"
text={faceGroup?.label ? 'Change Label' : 'Add Label'}
text={
faceGroup?.label
? t(
'people_page.face_group.action.change_label',
'Change Label'
)
: t('people_page.face_group.action.add_label', 'Add Label')
}
onClick={() => setEditLabel(true)}
/>
<Dropdown.Item
icon="object group"
text="Merge Face"
text={t('people_page.face_group.action.merge_face', 'Merge Face')}
onClick={() => setMergeModalOpen(true)}
/>
<Dropdown.Item
icon="object ungroup"
text="Detach Faces"
text={t(
'people_page.face_group.action.detach_face',
'Detach Face'
)}
onClick={() => setDetachModalOpen(true)}
/>
<Dropdown.Item
icon="clone"
text="Move Faces"
text={t('people_page.face_group.action.move_faces', 'Move Faces')}
onClick={() => setMoveModalOpen(true)}
/>
</Dropdown.Menu>
@ -130,7 +144,7 @@ const FaceGroupTitle = ({ faceGroup }: FaceGroupTitleProps) => {
<Input
loading={setLabelLoading}
ref={inputRef}
placeholder="Label"
placeholder={t('people_page.face_group.label_placeholder', 'Label')}
icon="arrow right"
value={inputValue}
onKeyUp={onKeyUp}
@ -143,24 +157,33 @@ const FaceGroupTitle = ({ faceGroup }: FaceGroupTitleProps) => {
)
}
let modals = null
if (faceGroup) {
modals = (
<>
<MergeFaceGroupsModal
open={mergeModalOpen}
setOpen={setMergeModalOpen}
sourceFaceGroup={faceGroup}
/>
<MoveImageFacesModal
open={moveModalOpen}
setOpen={setMoveModalOpen}
faceGroup={faceGroup}
/>
<DetachImageFacesModal
open={detachModalOpen}
setOpen={setDetachModalOpen}
faceGroup={faceGroup}
/>
</>
)
}
return (
<>
{title}
<MergeFaceGroupsModal
open={mergeModalOpen}
setOpen={setMergeModalOpen}
sourceFaceGroup={faceGroup}
/>
<MoveImageFacesModal
open={moveModalOpen}
setOpen={setMoveModalOpen}
faceGroup={faceGroup}
/>
<DetachImageFacesModal
open={detachModalOpen}
setOpen={setDetachModalOpen}
faceGroup={faceGroup}
/>
{modals}
</>
)
}

View File

@ -1,94 +0,0 @@
import { gql, useMutation, useQuery } from '@apollo/client'
import PropTypes from 'prop-types'
import React, { useState } from 'react'
import { useHistory } from 'react-router-dom'
import { Button, Modal } from 'semantic-ui-react'
import { MY_FACES_QUERY } from '../PeoplePage'
import SelectFaceGroupTable from './SelectFaceGroupTable'
const COMBINE_FACES_MUTATION = gql`
mutation combineFaces($destID: ID!, $srcID: ID!) {
combineFaceGroups(
destinationFaceGroupID: $destID
sourceFaceGroupID: $srcID
) {
id
}
}
`
const MergeFaceGroupsModal = ({ open, setOpen, sourceFaceGroup }) => {
const [selectedFaceGroup, setSelectedFaceGroup] = useState(null)
let history = useHistory()
const { data } = useQuery(MY_FACES_QUERY)
const [combineFacesMutation] = useMutation(COMBINE_FACES_MUTATION, {
variables: {
srcID: sourceFaceGroup?.id,
},
refetchQueries: [
{
query: MY_FACES_QUERY,
},
],
})
if (open == false) return null
const filteredFaceGroups =
data?.myFaceGroups.filter(x => x.id != sourceFaceGroup?.id) ?? []
const mergeFaceGroups = () => {
combineFacesMutation({
variables: {
destID: selectedFaceGroup.id,
},
}).then(() => {
setOpen(false)
history.push(`/people/${selectedFaceGroup.id}`)
})
}
return (
<Modal
onClose={() => setOpen(false)}
onOpen={() => setOpen(true)}
open={open}
>
<Modal.Header>Merge Face Groups</Modal.Header>
<Modal.Content scrolling>
<Modal.Description>
<p>
All images within this face group will be merged into the selected
face group.
</p>
<SelectFaceGroupTable
title="Select the destination face"
faceGroups={filteredFaceGroups}
selectedFaceGroup={selectedFaceGroup}
setSelectedFaceGroup={setSelectedFaceGroup}
/>
</Modal.Description>
</Modal.Content>
<Modal.Actions>
<Button onClick={() => setOpen(false)}>Cancel</Button>
<Button
disabled={selectedFaceGroup == null}
content="Merge"
labelPosition="right"
icon="checkmark"
onClick={() => mergeFaceGroups()}
positive
/>
</Modal.Actions>
</Modal>
)
}
MergeFaceGroupsModal.propTypes = {
open: PropTypes.bool.isRequired,
setOpen: PropTypes.func.isRequired,
sourceFaceGroup: PropTypes.object,
}
export default MergeFaceGroupsModal

View File

@ -0,0 +1,124 @@
import { gql, useMutation, useQuery } from '@apollo/client'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useHistory } from 'react-router-dom'
import { Button, Modal } from 'semantic-ui-react'
import { isNil } from '../../../helpers/utils'
import { MY_FACES_QUERY } from '../PeoplePage'
import {
myFaces,
myFacesVariables,
myFaces_myFaceGroups,
} from '../__generated__/myFaces'
import SelectFaceGroupTable from './SelectFaceGroupTable'
import {
combineFaces,
combineFacesVariables,
} from './__generated__/combineFaces'
import { singleFaceGroup_faceGroup } from './__generated__/singleFaceGroup'
const COMBINE_FACES_MUTATION = gql`
mutation combineFaces($destID: ID!, $srcID: ID!) {
combineFaceGroups(
destinationFaceGroupID: $destID
sourceFaceGroupID: $srcID
) {
id
}
}
`
type MergeFaceGroupsModalProps = {
open: boolean
setOpen(open: boolean): void
sourceFaceGroup: myFaces_myFaceGroups | singleFaceGroup_faceGroup
}
const MergeFaceGroupsModal = ({
open,
setOpen,
sourceFaceGroup,
}: MergeFaceGroupsModalProps) => {
const { t } = useTranslation()
const [selectedFaceGroup, setSelectedFaceGroup] =
useState<myFaces_myFaceGroups | singleFaceGroup_faceGroup | null>(null)
const history = useHistory()
const { data } = useQuery<myFaces, myFacesVariables>(MY_FACES_QUERY)
const [combineFacesMutation] = useMutation<
combineFaces,
combineFacesVariables
>(COMBINE_FACES_MUTATION, {
refetchQueries: [
{
query: MY_FACES_QUERY,
},
],
})
if (open == false) return null
const filteredFaceGroups =
data?.myFaceGroups.filter(x => x.id != sourceFaceGroup?.id) ?? []
const mergeFaceGroups = () => {
if (isNil(selectedFaceGroup)) throw new Error('No selected face group')
combineFacesMutation({
variables: {
srcID: sourceFaceGroup.id,
destID: selectedFaceGroup.id,
},
}).then(() => {
setOpen(false)
history.push(`/people/${selectedFaceGroup.id}`)
})
}
return (
<Modal
onClose={() => setOpen(false)}
onOpen={() => setOpen(true)}
open={open}
>
<Modal.Header>
{t('people_page.modal.merge_face_groups.title', 'Merge Face Groups')}
</Modal.Header>
<Modal.Content scrolling>
<Modal.Description>
<p>
{t(
'people_page.modal.merge_face_groups.description',
'All images within this face group will be merged into the selected face group.'
)}
</p>
<SelectFaceGroupTable
title={t(
'people_page.modal.merge_face_groups.destination_table.title',
'Select the destination face'
)}
faceGroups={filteredFaceGroups}
selectedFaceGroup={selectedFaceGroup}
setSelectedFaceGroup={setSelectedFaceGroup}
/>
</Modal.Description>
</Modal.Content>
<Modal.Actions>
<Button onClick={() => setOpen(false)}>
{t('general.action.cancel', 'Cancel')}
</Button>
<Button
disabled={selectedFaceGroup == null}
content={t('people_page.modal.action.merge', 'Merge')}
labelPosition="right"
icon="checkmark"
onClick={() => mergeFaceGroups()}
positive
/>
</Modal.Actions>
</Modal>
)
}
export default MergeFaceGroupsModal

View File

@ -20,6 +20,7 @@ import {
moveImageFaces,
moveImageFacesVariables,
} from './__generated__/moveImageFaces'
import { useTranslation } from 'react-i18next'
const MOVE_IMAGE_FACES_MUTATION = gql`
mutation moveImageFaces($faceIDs: [ID!]!, $destFaceGroupID: ID!) {
@ -38,7 +39,7 @@ const MOVE_IMAGE_FACES_MUTATION = gql`
type MoveImageFacesModalProps = {
open: boolean
setOpen: React.Dispatch<React.SetStateAction<boolean>>
faceGroup?: singleFaceGroup_faceGroup
faceGroup: singleFaceGroup_faceGroup
}
const MoveImageFacesModal = ({
@ -46,6 +47,8 @@ const MoveImageFacesModal = ({
setOpen,
faceGroup,
}: MoveImageFacesModalProps) => {
const { t } = useTranslation()
const [selectedImageFaces, setSelectedImageFaces] = useState<
(singleFaceGroup_faceGroup_imageFaces | myFaces_myFaceGroups_imageFaces)[]
>([])
@ -102,7 +105,7 @@ const MoveImageFacesModal = ({
})
}
const imageFaces = faceGroup?.imageFaces ?? []
const imageFaces = faceGroup.imageFaces
let table = null
if (!imagesSelected) {
@ -111,7 +114,10 @@ const MoveImageFacesModal = ({
imageFaces={imageFaces}
selectedImageFaces={selectedImageFaces}
setSelectedImageFaces={setSelectedImageFaces}
title="Select images to move"
title={t(
'people_page.modal.move_image_faces.image_select_table.title',
'Select images to move'
)}
/>
)
} else {
@ -121,14 +127,17 @@ const MoveImageFacesModal = ({
)
table = (
<SelectFaceGroupTable
title="Select destination face group"
title={t(
'people_page.modal.move_image_faces.destination_face_group_table.title',
'Select destination face group'
)}
faceGroups={filteredFaceGroups}
selectedFaceGroup={selectedFaceGroup}
setSelectedFaceGroup={setSelectedFaceGroup}
/>
)
} else {
table = <div>Loading...</div>
table = <div>{t('general.loading.default', 'Loading...')}</div>
}
}
@ -137,7 +146,10 @@ const MoveImageFacesModal = ({
positiveButton = (
<Button
disabled={selectedImageFaces.length == 0}
content="Next"
content={t(
'people_page.modal.move_image_faces.image_select_table.next_action',
'Next'
)}
labelPosition="right"
icon="arrow right"
onClick={() => setImagesSelected(true)}
@ -148,7 +160,10 @@ const MoveImageFacesModal = ({
positiveButton = (
<Button
disabled={!selectedFaceGroup}
content="Move image faces"
content={t(
'people_page.modal.move_image_faces.destination_face_group_table.move_action',
'Move image faces'
)}
labelPosition="right"
icon="checkmark"
onClick={() => moveImageFaces()}
@ -163,15 +178,24 @@ const MoveImageFacesModal = ({
onOpen={() => setOpen(true)}
open={open}
>
<Modal.Header>Move Image Faces</Modal.Header>
<Modal.Header>
{t('people_page.modal.move_image_faces.title', 'Move Image Faces')}
</Modal.Header>
<Modal.Content scrolling>
<Modal.Description>
<p>Move selected images of this face group to another face group</p>
<p>
{t(
'people_page.modal.move_image_faces.description',
'Move selected images of this face group to another face group'
)}
</p>
{table}
</Modal.Description>
</Modal.Content>
<Modal.Actions>
<Button onClick={() => setOpen(false)}>Cancel</Button>
<Button onClick={() => setOpen(false)}>
{t('general.action.cancel', 'Cancel')}
</Button>
{positiveButton}
</Modal.Actions>
</Modal>

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { Input, Pagination, Table } from 'semantic-ui-react'
import styled from 'styled-components'
import FaceCircleImage from '../FaceCircleImage'
@ -66,6 +67,8 @@ const SelectFaceGroupTable = ({
setSelectedFaceGroup,
title,
}: SelectFaceGroupTableProps) => {
const { t } = useTranslation()
const PAGE_SIZE = 6
const [page, setPage] = useState(0)
@ -106,7 +109,10 @@ const SelectFaceGroupTable = ({
value={searchValue}
onChange={e => setSearchValue(e.target.value)}
icon="search"
placeholder="Search faces..."
placeholder={t(
'people_page.table.select_face_group.search_faces_placeholder',
'Search faces...'
)}
fluid
/>
</Table.HeaderCell>

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Checkbox, Input, Pagination, Table } from 'semantic-ui-react'
import styled from 'styled-components'
import { ProtectedImage } from '../../../components/photoGallery/ProtectedMedia'
@ -67,6 +68,8 @@ const SelectImageFacesTable = ({
setSelectedImageFaces,
title,
}: SelectImageFacesTable) => {
const { t } = useTranslation()
const PAGE_SIZE = 6
const [page, setPage] = useState(0)
@ -115,7 +118,10 @@ const SelectImageFacesTable = ({
value={searchValue}
onChange={e => setSearchValue(e.target.value)}
icon="search"
placeholder="Search images..."
placeholder={t(
'people_page.table.select_image_faces.search_images_placeholder',
'Search images...'
)}
fluid
/>
</Table.HeaderCell>

View File

@ -1,5 +1,6 @@
import { gql, useQuery } from '@apollo/client'
import React, { useEffect, useReducer } from 'react'
import { useTranslation } from 'react-i18next'
import PaginateLoader from '../../../components/PaginateLoader'
import PhotoGallery from '../../../components/photoGallery/PhotoGallery'
import { photoGalleryReducer } from '../../../components/photoGallery/photoGalleryReducer'
@ -47,6 +48,8 @@ type SingleFaceGroupProps = {
}
const SingleFaceGroup = ({ faceGroupID }: SingleFaceGroupProps) => {
const { t } = useTranslation()
const { data, error, loading, fetchMore } = useQuery<
singleFaceGroup,
singleFaceGroupVariables
@ -94,7 +97,7 @@ const SingleFaceGroup = ({ faceGroupID }: SingleFaceGroupProps) => {
/>
<PaginateLoader
active={!finishedLoadingMore && !loading}
text="Loading more photos"
text={t('general.loading.paginate.media', 'Loading more media')}
/>
</div>
</div>