feat: add number of unassigned faces
This commit is contained in:
parent
f42cf33605
commit
c8d173697f
19 changed files with 536 additions and 22 deletions
48
cli/src/api/open-api/api.ts
generated
48
cli/src/api/open-api/api.ts
generated
|
@ -819,10 +819,10 @@ export interface AssetResponseDto {
|
|||
'ownerId': string;
|
||||
/**
|
||||
*
|
||||
* @type {Array<PersonResponseDto>}
|
||||
* @type {Array<PeopleAssetResponseDto>}
|
||||
* @memberof AssetResponseDto
|
||||
*/
|
||||
'people'?: Array<PersonResponseDto>;
|
||||
'people'?: Array<PeopleAssetResponseDto>;
|
||||
/**
|
||||
*
|
||||
* @type {boolean}
|
||||
|
@ -871,6 +871,12 @@ export interface AssetResponseDto {
|
|||
* @memberof AssetResponseDto
|
||||
*/
|
||||
'type': AssetTypeEnum;
|
||||
/**
|
||||
*
|
||||
* @type {Array<UnassignedFacesResponseDto>}
|
||||
* @memberof AssetResponseDto
|
||||
*/
|
||||
'unassignedPeople'?: Array<UnassignedFacesResponseDto>;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
|
@ -2390,6 +2396,25 @@ export const PathType = {
|
|||
export type PathType = typeof PathType[keyof typeof PathType];
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface PeopleAssetResponseDto
|
||||
*/
|
||||
export interface PeopleAssetResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof PeopleAssetResponseDto
|
||||
*/
|
||||
'assetFaceId': string;
|
||||
/**
|
||||
*
|
||||
* @type {PersonResponseDto}
|
||||
* @memberof PeopleAssetResponseDto
|
||||
*/
|
||||
'person': PersonResponseDto;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
@ -4024,6 +4049,25 @@ export const TranscodePolicy = {
|
|||
export type TranscodePolicy = typeof TranscodePolicy[keyof typeof TranscodePolicy];
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface UnassignedFacesResponseDto
|
||||
*/
|
||||
export interface UnassignedFacesResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof UnassignedFacesResponseDto
|
||||
*/
|
||||
'assetFaceId': string;
|
||||
/**
|
||||
*
|
||||
* @type {AssetFaceBoxDto}
|
||||
* @memberof UnassignedFacesResponseDto
|
||||
*/
|
||||
'boudinxBox': AssetFaceBoxDto;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
|
6
mobile/openapi/.openapi-generator/FILES
generated
6
mobile/openapi/.openapi-generator/FILES
generated
|
@ -92,6 +92,7 @@ doc/OAuthConfigResponseDto.md
|
|||
doc/PartnerApi.md
|
||||
doc/PathEntityType.md
|
||||
doc/PathType.md
|
||||
doc/PeopleAssetResponseDto.md
|
||||
doc/PeopleResponseDto.md
|
||||
doc/PeopleUpdateDto.md
|
||||
doc/PeopleUpdateItem.md
|
||||
|
@ -150,6 +151,7 @@ doc/TimeBucketSize.md
|
|||
doc/ToneMapping.md
|
||||
doc/TranscodeHWAccel.md
|
||||
doc/TranscodePolicy.md
|
||||
doc/UnassignedFacesResponseDto.md
|
||||
doc/UpdateAlbumDto.md
|
||||
doc/UpdateAssetDto.md
|
||||
doc/UpdateLibraryDto.md
|
||||
|
@ -268,6 +270,7 @@ lib/model/o_auth_config_dto.dart
|
|||
lib/model/o_auth_config_response_dto.dart
|
||||
lib/model/path_entity_type.dart
|
||||
lib/model/path_type.dart
|
||||
lib/model/people_asset_response_dto.dart
|
||||
lib/model/people_response_dto.dart
|
||||
lib/model/people_update_dto.dart
|
||||
lib/model/people_update_item.dart
|
||||
|
@ -320,6 +323,7 @@ lib/model/time_bucket_size.dart
|
|||
lib/model/tone_mapping.dart
|
||||
lib/model/transcode_hw_accel.dart
|
||||
lib/model/transcode_policy.dart
|
||||
lib/model/unassigned_faces_response_dto.dart
|
||||
lib/model/update_album_dto.dart
|
||||
lib/model/update_asset_dto.dart
|
||||
lib/model/update_library_dto.dart
|
||||
|
@ -421,6 +425,7 @@ test/o_auth_config_response_dto_test.dart
|
|||
test/partner_api_test.dart
|
||||
test/path_entity_type_test.dart
|
||||
test/path_type_test.dart
|
||||
test/people_asset_response_dto_test.dart
|
||||
test/people_response_dto_test.dart
|
||||
test/people_update_dto_test.dart
|
||||
test/people_update_item_test.dart
|
||||
|
@ -479,6 +484,7 @@ test/time_bucket_size_test.dart
|
|||
test/tone_mapping_test.dart
|
||||
test/transcode_hw_accel_test.dart
|
||||
test/transcode_policy_test.dart
|
||||
test/unassigned_faces_response_dto_test.dart
|
||||
test/update_album_dto_test.dart
|
||||
test/update_asset_dto_test.dart
|
||||
test/update_library_dto_test.dart
|
||||
|
|
2
mobile/openapi/README.md
generated
2
mobile/openapi/README.md
generated
|
@ -283,6 +283,7 @@ Class | Method | HTTP request | Description
|
|||
- [OAuthConfigResponseDto](doc//OAuthConfigResponseDto.md)
|
||||
- [PathEntityType](doc//PathEntityType.md)
|
||||
- [PathType](doc//PathType.md)
|
||||
- [PeopleAssetResponseDto](doc//PeopleAssetResponseDto.md)
|
||||
- [PeopleResponseDto](doc//PeopleResponseDto.md)
|
||||
- [PeopleUpdateDto](doc//PeopleUpdateDto.md)
|
||||
- [PeopleUpdateItem](doc//PeopleUpdateItem.md)
|
||||
|
@ -335,6 +336,7 @@ Class | Method | HTTP request | Description
|
|||
- [ToneMapping](doc//ToneMapping.md)
|
||||
- [TranscodeHWAccel](doc//TranscodeHWAccel.md)
|
||||
- [TranscodePolicy](doc//TranscodePolicy.md)
|
||||
- [UnassignedFacesResponseDto](doc//UnassignedFacesResponseDto.md)
|
||||
- [UpdateAlbumDto](doc//UpdateAlbumDto.md)
|
||||
- [UpdateAssetDto](doc//UpdateAssetDto.md)
|
||||
- [UpdateLibraryDto](doc//UpdateLibraryDto.md)
|
||||
|
|
3
mobile/openapi/doc/AssetResponseDto.md
generated
3
mobile/openapi/doc/AssetResponseDto.md
generated
|
@ -30,7 +30,7 @@ Name | Type | Description | Notes
|
|||
**originalPath** | **String** | |
|
||||
**owner** | [**UserResponseDto**](UserResponseDto.md) | | [optional]
|
||||
**ownerId** | **String** | |
|
||||
**people** | [**List<PersonResponseDto>**](PersonResponseDto.md) | | [optional] [default to const []]
|
||||
**people** | [**List<PeopleAssetResponseDto>**](PeopleAssetResponseDto.md) | | [optional] [default to const []]
|
||||
**resized** | **bool** | |
|
||||
**smartInfo** | [**SmartInfoResponseDto**](SmartInfoResponseDto.md) | | [optional]
|
||||
**stack** | [**List<AssetResponseDto>**](AssetResponseDto.md) | | [optional] [default to const []]
|
||||
|
@ -39,6 +39,7 @@ Name | Type | Description | Notes
|
|||
**tags** | [**List<TagResponseDto>**](TagResponseDto.md) | | [optional] [default to const []]
|
||||
**thumbhash** | **String** | |
|
||||
**type** | [**AssetTypeEnum**](AssetTypeEnum.md) | |
|
||||
**unassignedPeople** | [**List<UnassignedFacesResponseDto>**](UnassignedFacesResponseDto.md) | | [optional] [default to const []]
|
||||
**updatedAt** | [**DateTime**](DateTime.md) | |
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
|
16
mobile/openapi/doc/PeopleAssetResponseDto.md
generated
Normal file
16
mobile/openapi/doc/PeopleAssetResponseDto.md
generated
Normal file
|
@ -0,0 +1,16 @@
|
|||
# openapi.model.PeopleAssetResponseDto
|
||||
|
||||
## Load the model package
|
||||
```dart
|
||||
import 'package:openapi/api.dart';
|
||||
```
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**assetFaceId** | **String** | |
|
||||
**person** | [**PersonResponseDto**](PersonResponseDto.md) | |
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
16
mobile/openapi/doc/UnassignedFacesResponseDto.md
generated
Normal file
16
mobile/openapi/doc/UnassignedFacesResponseDto.md
generated
Normal file
|
@ -0,0 +1,16 @@
|
|||
# openapi.model.UnassignedFacesResponseDto
|
||||
|
||||
## Load the model package
|
||||
```dart
|
||||
import 'package:openapi/api.dart';
|
||||
```
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**assetFaceId** | **String** | |
|
||||
**boudinxBox** | [**AssetFaceBoxDto**](AssetFaceBoxDto.md) | |
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
2
mobile/openapi/lib/api.dart
generated
2
mobile/openapi/lib/api.dart
generated
|
@ -125,6 +125,7 @@ part 'model/o_auth_config_dto.dart';
|
|||
part 'model/o_auth_config_response_dto.dart';
|
||||
part 'model/path_entity_type.dart';
|
||||
part 'model/path_type.dart';
|
||||
part 'model/people_asset_response_dto.dart';
|
||||
part 'model/people_response_dto.dart';
|
||||
part 'model/people_update_dto.dart';
|
||||
part 'model/people_update_item.dart';
|
||||
|
@ -177,6 +178,7 @@ part 'model/time_bucket_size.dart';
|
|||
part 'model/tone_mapping.dart';
|
||||
part 'model/transcode_hw_accel.dart';
|
||||
part 'model/transcode_policy.dart';
|
||||
part 'model/unassigned_faces_response_dto.dart';
|
||||
part 'model/update_album_dto.dart';
|
||||
part 'model/update_asset_dto.dart';
|
||||
part 'model/update_library_dto.dart';
|
||||
|
|
4
mobile/openapi/lib/api_client.dart
generated
4
mobile/openapi/lib/api_client.dart
generated
|
@ -341,6 +341,8 @@ class ApiClient {
|
|||
return PathEntityTypeTypeTransformer().decode(value);
|
||||
case 'PathType':
|
||||
return PathTypeTypeTransformer().decode(value);
|
||||
case 'PeopleAssetResponseDto':
|
||||
return PeopleAssetResponseDto.fromJson(value);
|
||||
case 'PeopleResponseDto':
|
||||
return PeopleResponseDto.fromJson(value);
|
||||
case 'PeopleUpdateDto':
|
||||
|
@ -445,6 +447,8 @@ class ApiClient {
|
|||
return TranscodeHWAccelTypeTransformer().decode(value);
|
||||
case 'TranscodePolicy':
|
||||
return TranscodePolicyTypeTransformer().decode(value);
|
||||
case 'UnassignedFacesResponseDto':
|
||||
return UnassignedFacesResponseDto.fromJson(value);
|
||||
case 'UpdateAlbumDto':
|
||||
return UpdateAlbumDto.fromJson(value);
|
||||
case 'UpdateAssetDto':
|
||||
|
|
13
mobile/openapi/lib/model/asset_response_dto.dart
generated
13
mobile/openapi/lib/model/asset_response_dto.dart
generated
|
@ -44,6 +44,7 @@ class AssetResponseDto {
|
|||
this.tags = const [],
|
||||
required this.thumbhash,
|
||||
required this.type,
|
||||
this.unassignedPeople = const [],
|
||||
required this.updatedAt,
|
||||
});
|
||||
|
||||
|
@ -104,7 +105,7 @@ class AssetResponseDto {
|
|||
|
||||
String ownerId;
|
||||
|
||||
List<PersonResponseDto> people;
|
||||
List<PeopleAssetResponseDto> people;
|
||||
|
||||
bool resized;
|
||||
|
||||
|
@ -128,6 +129,8 @@ class AssetResponseDto {
|
|||
|
||||
AssetTypeEnum type;
|
||||
|
||||
List<UnassignedFacesResponseDto> unassignedPeople;
|
||||
|
||||
DateTime updatedAt;
|
||||
|
||||
@override
|
||||
|
@ -163,6 +166,7 @@ class AssetResponseDto {
|
|||
other.tags == tags &&
|
||||
other.thumbhash == thumbhash &&
|
||||
other.type == type &&
|
||||
other.unassignedPeople == unassignedPeople &&
|
||||
other.updatedAt == updatedAt;
|
||||
|
||||
@override
|
||||
|
@ -199,10 +203,11 @@ class AssetResponseDto {
|
|||
(tags.hashCode) +
|
||||
(thumbhash == null ? 0 : thumbhash!.hashCode) +
|
||||
(type.hashCode) +
|
||||
(unassignedPeople.hashCode) +
|
||||
(updatedAt.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AssetResponseDto[checksum=$checksum, deviceAssetId=$deviceAssetId, deviceId=$deviceId, duration=$duration, exifInfo=$exifInfo, fileCreatedAt=$fileCreatedAt, fileModifiedAt=$fileModifiedAt, hasMetadata=$hasMetadata, id=$id, isArchived=$isArchived, isExternal=$isExternal, isFavorite=$isFavorite, isOffline=$isOffline, isReadOnly=$isReadOnly, isTrashed=$isTrashed, libraryId=$libraryId, livePhotoVideoId=$livePhotoVideoId, localDateTime=$localDateTime, originalFileName=$originalFileName, originalPath=$originalPath, owner=$owner, ownerId=$ownerId, people=$people, resized=$resized, smartInfo=$smartInfo, stack=$stack, stackCount=$stackCount, stackParentId=$stackParentId, tags=$tags, thumbhash=$thumbhash, type=$type, updatedAt=$updatedAt]';
|
||||
String toString() => 'AssetResponseDto[checksum=$checksum, deviceAssetId=$deviceAssetId, deviceId=$deviceId, duration=$duration, exifInfo=$exifInfo, fileCreatedAt=$fileCreatedAt, fileModifiedAt=$fileModifiedAt, hasMetadata=$hasMetadata, id=$id, isArchived=$isArchived, isExternal=$isExternal, isFavorite=$isFavorite, isOffline=$isOffline, isReadOnly=$isReadOnly, isTrashed=$isTrashed, libraryId=$libraryId, livePhotoVideoId=$livePhotoVideoId, localDateTime=$localDateTime, originalFileName=$originalFileName, originalPath=$originalPath, owner=$owner, ownerId=$ownerId, people=$people, resized=$resized, smartInfo=$smartInfo, stack=$stack, stackCount=$stackCount, stackParentId=$stackParentId, tags=$tags, thumbhash=$thumbhash, type=$type, unassignedPeople=$unassignedPeople, updatedAt=$updatedAt]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
|
@ -261,6 +266,7 @@ class AssetResponseDto {
|
|||
// json[r'thumbhash'] = null;
|
||||
}
|
||||
json[r'type'] = this.type;
|
||||
json[r'unassignedPeople'] = this.unassignedPeople;
|
||||
json[r'updatedAt'] = this.updatedAt.toUtc().toIso8601String();
|
||||
return json;
|
||||
}
|
||||
|
@ -295,7 +301,7 @@ class AssetResponseDto {
|
|||
originalPath: mapValueOfType<String>(json, r'originalPath')!,
|
||||
owner: UserResponseDto.fromJson(json[r'owner']),
|
||||
ownerId: mapValueOfType<String>(json, r'ownerId')!,
|
||||
people: PersonResponseDto.listFromJson(json[r'people']),
|
||||
people: PeopleAssetResponseDto.listFromJson(json[r'people']),
|
||||
resized: mapValueOfType<bool>(json, r'resized')!,
|
||||
smartInfo: SmartInfoResponseDto.fromJson(json[r'smartInfo']),
|
||||
stack: AssetResponseDto.listFromJson(json[r'stack']),
|
||||
|
@ -304,6 +310,7 @@ class AssetResponseDto {
|
|||
tags: TagResponseDto.listFromJson(json[r'tags']),
|
||||
thumbhash: mapValueOfType<String>(json, r'thumbhash'),
|
||||
type: AssetTypeEnum.fromJson(json[r'type'])!,
|
||||
unassignedPeople: UnassignedFacesResponseDto.listFromJson(json[r'unassignedPeople']),
|
||||
updatedAt: mapDateTime(json, r'updatedAt', '')!,
|
||||
);
|
||||
}
|
||||
|
|
106
mobile/openapi/lib/model/people_asset_response_dto.dart
generated
Normal file
106
mobile/openapi/lib/model/people_asset_response_dto.dart
generated
Normal file
|
@ -0,0 +1,106 @@
|
|||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.12
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class PeopleAssetResponseDto {
|
||||
/// Returns a new [PeopleAssetResponseDto] instance.
|
||||
PeopleAssetResponseDto({
|
||||
required this.assetFaceId,
|
||||
required this.person,
|
||||
});
|
||||
|
||||
String assetFaceId;
|
||||
|
||||
PersonResponseDto person;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is PeopleAssetResponseDto &&
|
||||
other.assetFaceId == assetFaceId &&
|
||||
other.person == person;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(assetFaceId.hashCode) +
|
||||
(person.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'PeopleAssetResponseDto[assetFaceId=$assetFaceId, person=$person]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'assetFaceId'] = this.assetFaceId;
|
||||
json[r'person'] = this.person;
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [PeopleAssetResponseDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static PeopleAssetResponseDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return PeopleAssetResponseDto(
|
||||
assetFaceId: mapValueOfType<String>(json, r'assetFaceId')!,
|
||||
person: PersonResponseDto.fromJson(json[r'person'])!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<PeopleAssetResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <PeopleAssetResponseDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = PeopleAssetResponseDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, PeopleAssetResponseDto> mapFromJson(dynamic json) {
|
||||
final map = <String, PeopleAssetResponseDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = PeopleAssetResponseDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of PeopleAssetResponseDto-objects as value to a dart map
|
||||
static Map<String, List<PeopleAssetResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<PeopleAssetResponseDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = PeopleAssetResponseDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'assetFaceId',
|
||||
'person',
|
||||
};
|
||||
}
|
||||
|
106
mobile/openapi/lib/model/unassigned_faces_response_dto.dart
generated
Normal file
106
mobile/openapi/lib/model/unassigned_faces_response_dto.dart
generated
Normal file
|
@ -0,0 +1,106 @@
|
|||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.12
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class UnassignedFacesResponseDto {
|
||||
/// Returns a new [UnassignedFacesResponseDto] instance.
|
||||
UnassignedFacesResponseDto({
|
||||
required this.assetFaceId,
|
||||
required this.boudinxBox,
|
||||
});
|
||||
|
||||
String assetFaceId;
|
||||
|
||||
AssetFaceBoxDto boudinxBox;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is UnassignedFacesResponseDto &&
|
||||
other.assetFaceId == assetFaceId &&
|
||||
other.boudinxBox == boudinxBox;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(assetFaceId.hashCode) +
|
||||
(boudinxBox.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'UnassignedFacesResponseDto[assetFaceId=$assetFaceId, boudinxBox=$boudinxBox]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'assetFaceId'] = this.assetFaceId;
|
||||
json[r'boudinxBox'] = this.boudinxBox;
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [UnassignedFacesResponseDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static UnassignedFacesResponseDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return UnassignedFacesResponseDto(
|
||||
assetFaceId: mapValueOfType<String>(json, r'assetFaceId')!,
|
||||
boudinxBox: AssetFaceBoxDto.fromJson(json[r'boudinxBox'])!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<UnassignedFacesResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <UnassignedFacesResponseDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = UnassignedFacesResponseDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, UnassignedFacesResponseDto> mapFromJson(dynamic json) {
|
||||
final map = <String, UnassignedFacesResponseDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = UnassignedFacesResponseDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of UnassignedFacesResponseDto-objects as value to a dart map
|
||||
static Map<String, List<UnassignedFacesResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<UnassignedFacesResponseDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = UnassignedFacesResponseDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'assetFaceId',
|
||||
'boudinxBox',
|
||||
};
|
||||
}
|
||||
|
7
mobile/openapi/test/asset_response_dto_test.dart
generated
7
mobile/openapi/test/asset_response_dto_test.dart
generated
|
@ -127,7 +127,7 @@ void main() {
|
|||
// TODO
|
||||
});
|
||||
|
||||
// List<PersonResponseDto> people (default value: const [])
|
||||
// List<PeopleAssetResponseDto> people (default value: const [])
|
||||
test('to test the property `people`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
@ -172,6 +172,11 @@ void main() {
|
|||
// TODO
|
||||
});
|
||||
|
||||
// List<UnassignedFacesResponseDto> unassignedPeople (default value: const [])
|
||||
test('to test the property `unassignedPeople`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime updatedAt
|
||||
test('to test the property `updatedAt`', () async {
|
||||
// TODO
|
||||
|
|
32
mobile/openapi/test/people_asset_response_dto_test.dart
generated
Normal file
32
mobile/openapi/test/people_asset_response_dto_test.dart
generated
Normal file
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.12
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
import 'package:openapi/api.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
// tests for PeopleAssetResponseDto
|
||||
void main() {
|
||||
// final instance = PeopleAssetResponseDto();
|
||||
|
||||
group('test PeopleAssetResponseDto', () {
|
||||
// String assetFaceId
|
||||
test('to test the property `assetFaceId`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// PersonResponseDto person
|
||||
test('to test the property `person`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
32
mobile/openapi/test/unassigned_faces_response_dto_test.dart
generated
Normal file
32
mobile/openapi/test/unassigned_faces_response_dto_test.dart
generated
Normal file
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.12
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
import 'package:openapi/api.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
// tests for UnassignedFacesResponseDto
|
||||
void main() {
|
||||
// final instance = UnassignedFacesResponseDto();
|
||||
|
||||
group('test UnassignedFacesResponseDto', () {
|
||||
// String assetFaceId
|
||||
test('to test the property `assetFaceId`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// AssetFaceBoxDto boudinxBox
|
||||
test('to test the property `boudinxBox`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
|
@ -6176,7 +6176,7 @@
|
|||
},
|
||||
"people": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PersonResponseDto"
|
||||
"$ref": "#/components/schemas/PeopleAssetResponseDto"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
|
@ -6212,6 +6212,12 @@
|
|||
"type": {
|
||||
"$ref": "#/components/schemas/AssetTypeEnum"
|
||||
},
|
||||
"unassignedPeople": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/UnassignedFacesResponseDto"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"updatedAt": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
|
@ -7480,6 +7486,21 @@
|
|||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PeopleAssetResponseDto": {
|
||||
"properties": {
|
||||
"assetFaceId": {
|
||||
"type": "string"
|
||||
},
|
||||
"person": {
|
||||
"$ref": "#/components/schemas/PersonResponseDto"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"assetFaceId",
|
||||
"person"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PeopleResponseDto": {
|
||||
"properties": {
|
||||
"people": {
|
||||
|
@ -8744,6 +8765,21 @@
|
|||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UnassignedFacesResponseDto": {
|
||||
"properties": {
|
||||
"assetFaceId": {
|
||||
"type": "string"
|
||||
},
|
||||
"boudinxBox": {
|
||||
"$ref": "#/components/schemas/AssetFaceBoxDto"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"assetFaceId",
|
||||
"boudinxBox"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UpdateAlbumDto": {
|
||||
"properties": {
|
||||
"albumName": {
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import { AssetEntity, AssetType } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { PersonResponseDto, mapFace } from '../../person/person.dto';
|
||||
import {
|
||||
PeopleAssetResponseDto,
|
||||
UnassignedFacesResponseDto,
|
||||
mapFace,
|
||||
mapUnassignedFace,
|
||||
} from '../../person/person.dto';
|
||||
import { TagResponseDto, mapTag } from '../../tag';
|
||||
import { UserResponseDto, mapUser } from '../../user/response-dto/user-response.dto';
|
||||
import { ExifResponseDto, mapExif } from './exif-response.dto';
|
||||
|
@ -39,7 +44,8 @@ export class AssetResponseDto extends SanitizedAssetResponseDto {
|
|||
exifInfo?: ExifResponseDto;
|
||||
smartInfo?: SmartInfoResponseDto;
|
||||
tags?: TagResponseDto[];
|
||||
people?: PersonResponseDto[];
|
||||
unassignedPeople?: UnassignedFacesResponseDto[];
|
||||
people?: PeopleAssetResponseDto[];
|
||||
/**base64 encoded sha1 hash */
|
||||
checksum!: string;
|
||||
stackParentId?: string | null;
|
||||
|
@ -96,9 +102,12 @@ export function mapAsset(entity: AssetEntity, options: AssetMapOptions = {}): As
|
|||
smartInfo: entity.smartInfo ? mapSmartInfo(entity.smartInfo) : undefined,
|
||||
livePhotoVideoId: entity.livePhotoVideoId,
|
||||
tags: entity.tags?.map(mapTag),
|
||||
unassignedPeople: entity.faces
|
||||
?.map(mapUnassignedFace)
|
||||
.filter((assetFace) => assetFace) as UnassignedFacesResponseDto[],
|
||||
people: entity.faces
|
||||
?.map(mapFace)
|
||||
.filter((person): person is PersonResponseDto => person !== null && !person.isHidden),
|
||||
.filter((assetFace) => assetFace && !assetFace.person.isHidden) as PeopleAssetResponseDto[],
|
||||
checksum: entity.checksum.toString('base64'),
|
||||
stackParentId: entity.stackParentId,
|
||||
stack: withStack ? entity.stack?.map((a) => mapAsset(a, { stripMetadata })) ?? undefined : undefined,
|
||||
|
|
|
@ -110,6 +110,16 @@ export class PersonResponseDto {
|
|||
isHidden!: boolean;
|
||||
}
|
||||
|
||||
export class PeopleAssetResponseDto {
|
||||
assetFaceId!: string;
|
||||
person!: PersonResponseDto;
|
||||
}
|
||||
|
||||
export class UnassignedFacesResponseDto {
|
||||
assetFaceId!: string;
|
||||
boudinxBox!: AssetFaceBoxDto;
|
||||
}
|
||||
|
||||
export class PersonStatisticsResponseDto {
|
||||
@ApiProperty({ type: 'integer' })
|
||||
assets!: number;
|
||||
|
@ -135,10 +145,31 @@ export function mapPerson(person: PersonEntity): PersonResponseDto {
|
|||
};
|
||||
}
|
||||
|
||||
export function mapFace(face: AssetFaceEntity): PersonResponseDto | null {
|
||||
export function mapFace(face: AssetFaceEntity): PeopleAssetResponseDto | null {
|
||||
if (face.person) {
|
||||
return mapPerson(face.person);
|
||||
return {
|
||||
assetFaceId: face.id,
|
||||
person: face.person,
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function mapUnassignedFace(face: AssetFaceEntity): UnassignedFacesResponseDto | null {
|
||||
if (face.person !== null) {
|
||||
return null;
|
||||
} else {
|
||||
return {
|
||||
assetFaceId: face.id,
|
||||
boudinxBox: {
|
||||
imageWidth: face.imageWidth,
|
||||
imageHeight: face.imageHeight,
|
||||
boundingBoxX1: face.boundingBoxX1,
|
||||
boundingBoxY1: face.boundingBoxY1,
|
||||
boundingBoxX2: face.boundingBoxX2,
|
||||
boundingBoxY2: face.boundingBoxY2,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
48
web/src/api/open-api/api.ts
generated
48
web/src/api/open-api/api.ts
generated
|
@ -819,10 +819,10 @@ export interface AssetResponseDto {
|
|||
'ownerId': string;
|
||||
/**
|
||||
*
|
||||
* @type {Array<PersonResponseDto>}
|
||||
* @type {Array<PeopleAssetResponseDto>}
|
||||
* @memberof AssetResponseDto
|
||||
*/
|
||||
'people'?: Array<PersonResponseDto>;
|
||||
'people'?: Array<PeopleAssetResponseDto>;
|
||||
/**
|
||||
*
|
||||
* @type {boolean}
|
||||
|
@ -871,6 +871,12 @@ export interface AssetResponseDto {
|
|||
* @memberof AssetResponseDto
|
||||
*/
|
||||
'type': AssetTypeEnum;
|
||||
/**
|
||||
*
|
||||
* @type {Array<UnassignedFacesResponseDto>}
|
||||
* @memberof AssetResponseDto
|
||||
*/
|
||||
'unassignedPeople'?: Array<UnassignedFacesResponseDto>;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
|
@ -2390,6 +2396,25 @@ export const PathType = {
|
|||
export type PathType = typeof PathType[keyof typeof PathType];
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface PeopleAssetResponseDto
|
||||
*/
|
||||
export interface PeopleAssetResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof PeopleAssetResponseDto
|
||||
*/
|
||||
'assetFaceId': string;
|
||||
/**
|
||||
*
|
||||
* @type {PersonResponseDto}
|
||||
* @memberof PeopleAssetResponseDto
|
||||
*/
|
||||
'person': PersonResponseDto;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
@ -4024,6 +4049,25 @@ export const TranscodePolicy = {
|
|||
export type TranscodePolicy = typeof TranscodePolicy[keyof typeof TranscodePolicy];
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface UnassignedFacesResponseDto
|
||||
*/
|
||||
export interface UnassignedFacesResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof UnassignedFacesResponseDto
|
||||
*/
|
||||
'assetFaceId': string;
|
||||
/**
|
||||
*
|
||||
* @type {AssetFaceBoxDto}
|
||||
* @memberof UnassignedFacesResponseDto
|
||||
*/
|
||||
'boudinxBox': AssetFaceBoxDto;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
|
|
@ -3,7 +3,14 @@
|
|||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { featureFlags, serverConfig } from '$lib/stores/server-config.store';
|
||||
import { getAssetFilename } from '$lib/utils/asset-utils';
|
||||
import { AlbumResponseDto, AssetResponseDto, ThumbnailFormat, api } from '@api';
|
||||
import {
|
||||
AlbumResponseDto,
|
||||
AssetResponseDto,
|
||||
PersonResponseDto,
|
||||
ThumbnailFormat,
|
||||
UnassignedFacesResponseDto,
|
||||
api,
|
||||
} from '@api';
|
||||
import type { LatLngTuple } from 'leaflet';
|
||||
import { DateTime } from 'luxon';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
@ -20,6 +27,8 @@
|
|||
|
||||
export let asset: AssetResponseDto;
|
||||
export let albums: AlbumResponseDto[] = [];
|
||||
let unassignedFaces: UnassignedFacesResponseDto[] = [];
|
||||
let people: PersonResponseDto[] = [];
|
||||
|
||||
let customFeaturePhoto = new Array<PersonToCreate | null>(asset.people?.length || 0);
|
||||
|
||||
|
@ -46,7 +55,13 @@
|
|||
// Get latest description from server
|
||||
if (asset.id && !api.isSharedLink && !showEditFaces) {
|
||||
api.assetApi.getAssetById({ id: asset.id }).then((res) => {
|
||||
people = res.data?.people || [];
|
||||
if (res.data && res.data.people) {
|
||||
unassignedFaces = res.data?.unassignedPeople || [];
|
||||
people = (res.data?.people || [])
|
||||
.map((peopleAsset) => peopleAsset.person)
|
||||
.filter((person): person is PersonResponseDto => person !== null);
|
||||
}
|
||||
|
||||
textarea.value = res.data?.exifInfo?.description || '';
|
||||
});
|
||||
}
|
||||
|
@ -64,8 +79,6 @@
|
|||
$: lat = latlng ? latlng[0] : undefined;
|
||||
$: lng = latlng ? latlng[1] : undefined;
|
||||
|
||||
let people = asset.people || [];
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const getMegapixel = (width: number, height: number): number | undefined => {
|
||||
|
@ -148,10 +161,12 @@
|
|||
<section class="px-4 py-4 text-sm">
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<h2 class="justify-self-start uppercase">People</h2>
|
||||
|
||||
<button class="justify-self-end" on:click={() => (showEditFaces = true)}>
|
||||
<Pencil size={18} />
|
||||
</button>
|
||||
{#if unassignedFaces.length > 0}
|
||||
<p>{`${unassignedFaces.length} face${unassignedFaces.length > 1 ? 's' : ''} available to add`}</p>
|
||||
{/if}
|
||||
</div>
|
||||
{#if people.length > 0}
|
||||
<div class="mt-4 flex flex-wrap gap-2">
|
||||
|
|
Loading…
Reference in a new issue