mirror of
https://github.com/immich-app/immich.git
synced 2025-12-20 01:11:46 +03:00
feat(server,web): improve performances in person page (1) (#4387)
* feat: improve performances in people page * feat: add loadingspinner when searching * fix: reset people on error * fix: case insensitive * feat: better sql query * fix: reset people list before api request * fix: format
This commit is contained in:
@@ -22,6 +22,7 @@ export interface IPersonRepository {
|
||||
getAllForUser(userId: string, options: PersonSearchOptions): Promise<PersonEntity[]>;
|
||||
getAllWithoutFaces(): Promise<PersonEntity[]>;
|
||||
getById(personId: string): Promise<PersonEntity | null>;
|
||||
getByName(userId: string, personName: string): Promise<PersonEntity[]>;
|
||||
|
||||
getAssets(personId: string): Promise<AssetEntity[]>;
|
||||
prepareReassignFaces(data: UpdateFacesData): Promise<string[]>;
|
||||
|
||||
@@ -85,3 +85,9 @@ export class SearchDto {
|
||||
@Transform(toBoolean)
|
||||
motion?: boolean;
|
||||
}
|
||||
|
||||
export class SearchPeopleDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
name!: string;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { AssetResponseDto, mapAsset } from '../asset';
|
||||
import { AuthUserDto } from '../auth';
|
||||
import { usePagination } from '../domain.util';
|
||||
import { IAssetFaceJob, IBulkEntityJob, JOBS_ASSET_PAGINATION_SIZE, JobName } from '../job';
|
||||
import { PersonResponseDto } from '../person/person.dto';
|
||||
import {
|
||||
AssetFaceId,
|
||||
IAlbumRepository,
|
||||
@@ -21,7 +22,7 @@ import {
|
||||
SearchStrategy,
|
||||
} from '../repositories';
|
||||
import { FeatureFlag, SystemConfigCore } from '../system-config';
|
||||
import { SearchDto } from './dto';
|
||||
import { SearchDto, SearchPeopleDto } from './dto';
|
||||
import { SearchResponseDto } from './response-dto';
|
||||
|
||||
interface SyncQueue {
|
||||
@@ -158,6 +159,10 @@ export class SearchService {
|
||||
};
|
||||
}
|
||||
|
||||
async searchPerson(authUser: AuthUserDto, dto: SearchPeopleDto): Promise<PersonResponseDto[]> {
|
||||
return await this.personRepository.getByName(authUser.id, dto.name);
|
||||
}
|
||||
|
||||
async handleIndexAlbums() {
|
||||
if (!this.enabled) {
|
||||
return false;
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
import { AuthUserDto, SearchDto, SearchExploreResponseDto, SearchResponseDto, SearchService } from '@app/domain';
|
||||
import {
|
||||
AuthUserDto,
|
||||
PersonResponseDto,
|
||||
SearchDto,
|
||||
SearchExploreResponseDto,
|
||||
SearchPeopleDto,
|
||||
SearchResponseDto,
|
||||
SearchService,
|
||||
} from '@app/domain';
|
||||
import { Controller, Get, Query } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { AuthUser, Authenticated } from '../app.guard';
|
||||
@@ -11,6 +19,11 @@ import { UseValidation } from '../app.utils';
|
||||
export class SearchController {
|
||||
constructor(private service: SearchService) {}
|
||||
|
||||
@Get('person')
|
||||
searchPerson(@AuthUser() authUser: AuthUserDto, @Query() dto: SearchPeopleDto): Promise<PersonResponseDto[]> {
|
||||
return this.service.searchPerson(authUser, dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
search(@AuthUser() authUser: AuthUserDto, @Query() dto: SearchDto): Promise<SearchResponseDto> {
|
||||
return this.service.search(authUser, dto);
|
||||
|
||||
@@ -95,6 +95,16 @@ export class PersonRepository implements IPersonRepository {
|
||||
return this.personRepository.findOne({ where: { id: personId } });
|
||||
}
|
||||
|
||||
getByName(userId: string, personName: string): Promise<PersonEntity[]> {
|
||||
return this.personRepository
|
||||
.createQueryBuilder('person')
|
||||
.leftJoin('person.faces', 'face')
|
||||
.where('person.ownerId = :userId', { userId })
|
||||
.andWhere('LOWER(person.name) LIKE :name', { name: `${personName.toLowerCase()}%` })
|
||||
.limit(20)
|
||||
.getMany();
|
||||
}
|
||||
|
||||
getAssets(personId: string): Promise<AssetEntity[]> {
|
||||
return this.assetRepository.find({
|
||||
where: {
|
||||
|
||||
Reference in New Issue
Block a user