1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-29 11:24:37 +02:00

fix(server, web): reassigning faces (#9265)

* fix: reassiging faces

* fix: rename
This commit is contained in:
martin 2024-05-05 20:16:44 +02:00 committed by GitHub
parent 090592e5ae
commit cf79bc9ed7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 50 additions and 27 deletions

View File

@ -5,7 +5,7 @@ import { ExifEntity } from 'src/entities/exif.entity';
import { ReverseGeocodeResult } from 'src/interfaces/metadata.interface';
import { AssetSearchOptions, SearchExploreItem } from 'src/interfaces/search.interface';
import { Paginated, PaginationOptions } from 'src/utils/pagination';
import { FindOptionsRelations, FindOptionsSelect } from 'typeorm';
import { FindOptionsOrder, FindOptionsRelations, FindOptionsSelect } from 'typeorm';
export type AssetStats = Record<AssetType, number>;
@ -162,7 +162,11 @@ export interface IAssetRepository {
getUploadAssetIdByChecksum(ownerId: string, checksum: Buffer): Promise<string | undefined>;
getByAlbumId(pagination: PaginationOptions, albumId: string): Paginated<AssetEntity>;
getByUserId(pagination: PaginationOptions, userId: string, options?: AssetSearchOptions): Paginated<AssetEntity>;
getById(id: string, relations?: FindOptionsRelations<AssetEntity>): Promise<AssetEntity | null>;
getById(
id: string,
relations?: FindOptionsRelations<AssetEntity>,
order?: FindOptionsOrder<AssetEntity>,
): Promise<AssetEntity | null>;
getWithout(pagination: PaginationOptions, property: WithoutProperty): Paginated<AssetEntity>;
getWith(pagination: PaginationOptions, property: WithProperty, libraryId?: string): Paginated<AssetEntity>;
getRandom(userId: string, count: number): Promise<AssetEntity[]>;

View File

@ -85,6 +85,8 @@ FROM
LEFT JOIN "person" "AssetFaceEntity__AssetFaceEntity_person" ON "AssetFaceEntity__AssetFaceEntity_person"."id" = "AssetFaceEntity"."personId"
WHERE
(("AssetFaceEntity"."assetId" = $1))
ORDER BY
"AssetFaceEntity"."boundingBoxX1" ASC
-- PersonRepository.getFaceById
SELECT DISTINCT

View File

@ -36,6 +36,7 @@ import { Instrumentation } from 'src/utils/instrumentation';
import { Paginated, PaginationMode, PaginationOptions, paginate, paginatedBuilder } from 'src/utils/pagination';
import {
Brackets,
FindOptionsOrder,
FindOptionsRelations,
FindOptionsSelect,
FindOptionsWhere,
@ -236,12 +237,17 @@ export class AssetRepository implements IAssetRepository {
}
@GenerateSql({ params: [DummyValue.UUID] })
getById(id: string, relations: FindOptionsRelations<AssetEntity>): Promise<AssetEntity | null> {
getById(
id: string,
relations: FindOptionsRelations<AssetEntity>,
order?: FindOptionsOrder<AssetEntity>,
): Promise<AssetEntity | null> {
return this.repository.findOne({
where: { id },
relations,
// We are specifically asking for this asset. Return it even if it is soft deleted
withDeleted: true,
order,
});
}

View File

@ -104,6 +104,9 @@ export class PersonRepository implements IPersonRepository {
relations: {
person: true,
},
order: {
boundingBoxX1: 'ASC',
},
});
}

View File

@ -227,21 +227,29 @@ export class AssetService {
async get(auth: AuthDto, id: string): Promise<AssetResponseDto | SanitizedAssetResponseDto> {
await this.access.requirePermission(auth, Permission.ASSET_READ, id);
const asset = await this.assetRepository.getById(id, {
exifInfo: true,
tags: true,
sharedLinks: true,
smartInfo: true,
owner: true,
faces: {
person: true,
},
stack: {
assets: {
exifInfo: true,
const asset = await this.assetRepository.getById(
id,
{
exifInfo: true,
tags: true,
sharedLinks: true,
smartInfo: true,
owner: true,
faces: {
person: true,
},
stack: {
assets: {
exifInfo: true,
},
},
},
});
{
faces: {
boundingBoxX1: 'ASC',
},
},
);
if (!asset) {
throw new BadRequestException('Asset not found');

View File

@ -36,6 +36,7 @@
let selectedPersonToReassign: Record<string, PersonResponseDto> = {};
let selectedPersonToCreate: Record<string, string> = {};
let editedPerson: PersonResponseDto;
let editedFace: AssetFaceResponseDto;
// loading spinners
let isShowLoadingDone = false;
@ -155,24 +156,23 @@
};
const handleCreatePerson = (newFeaturePhoto: string | null) => {
const personToUpdate = peopleWithFaces.find((face) => face.person?.id === editedPerson.id);
if (newFeaturePhoto && personToUpdate) {
selectedPersonToCreate[personToUpdate.id] = newFeaturePhoto;
if (newFeaturePhoto) {
selectedPersonToCreate[editedFace.id] = newFeaturePhoto;
}
showSelectedFaces = false;
};
const handleReassignFace = (person: PersonResponseDto | null) => {
const personToUpdate = peopleWithFaces.find((face) => face.person?.id === editedPerson.id);
if (person && personToUpdate) {
selectedPersonToReassign[personToUpdate.id] = person;
showSelectedFaces = false;
if (person) {
selectedPersonToReassign[editedFace.id] = person;
}
showSelectedFaces = false;
};
const handlePersonPicker = (person: PersonResponseDto | null) => {
if (person) {
editedPerson = person;
const handleFacePicker = (face: AssetFaceResponseDto) => {
if (face.person) {
editedFace = face;
editedPerson = face.person;
showSelectedFaces = true;
}
};
@ -285,7 +285,7 @@
size="18"
padding="1"
class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] transform"
on:click={() => handlePersonPicker(face.person)}
on:click={() => handleFacePicker(face)}
/>
{/if}
</div>