feat(web): Show face box
This commit is contained in:
parent
d2bad1d553
commit
8cc6993926
16 changed files with 424 additions and 11 deletions
49
cli/src/api/open-api/api.ts
generated
49
cli/src/api/open-api/api.ts
generated
|
@ -1376,6 +1376,49 @@ export interface ExifResponseDto {
|
|||
*/
|
||||
'timeZone'?: string | null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface FaceGeometryDto
|
||||
*/
|
||||
export interface FaceGeometryDto {
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'boundingBoxX1': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'boundingBoxX2': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'boundingBoxY1': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'boundingBoxY2': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'imageHeight': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'imageWidth': number;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
@ -1883,6 +1926,12 @@ export interface PersonResponseDto {
|
|||
* @memberof PersonResponseDto
|
||||
*/
|
||||
'birthDate': string | null;
|
||||
/**
|
||||
*
|
||||
* @type {FaceGeometryDto}
|
||||
* @memberof PersonResponseDto
|
||||
*/
|
||||
'geometry'?: FaceGeometryDto;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
|
|
3
mobile/openapi/.openapi-generator/FILES
generated
3
mobile/openapi/.openapi-generator/FILES
generated
|
@ -51,6 +51,7 @@ doc/DownloadArchiveInfo.md
|
|||
doc/DownloadInfoDto.md
|
||||
doc/DownloadResponseDto.md
|
||||
doc/ExifResponseDto.md
|
||||
doc/FaceGeometryDto.md
|
||||
doc/ImportAssetDto.md
|
||||
doc/JobApi.md
|
||||
doc/JobCommand.md
|
||||
|
@ -197,6 +198,7 @@ lib/model/download_archive_info.dart
|
|||
lib/model/download_info_dto.dart
|
||||
lib/model/download_response_dto.dart
|
||||
lib/model/exif_response_dto.dart
|
||||
lib/model/face_geometry_dto.dart
|
||||
lib/model/import_asset_dto.dart
|
||||
lib/model/job_command.dart
|
||||
lib/model/job_command_dto.dart
|
||||
|
@ -314,6 +316,7 @@ test/download_archive_info_test.dart
|
|||
test/download_info_dto_test.dart
|
||||
test/download_response_dto_test.dart
|
||||
test/exif_response_dto_test.dart
|
||||
test/face_geometry_dto_test.dart
|
||||
test/import_asset_dto_test.dart
|
||||
test/job_api_test.dart
|
||||
test/job_command_dto_test.dart
|
||||
|
|
1
mobile/openapi/README.md
generated
1
mobile/openapi/README.md
generated
|
@ -225,6 +225,7 @@ Class | Method | HTTP request | Description
|
|||
- [DownloadInfoDto](doc//DownloadInfoDto.md)
|
||||
- [DownloadResponseDto](doc//DownloadResponseDto.md)
|
||||
- [ExifResponseDto](doc//ExifResponseDto.md)
|
||||
- [FaceGeometryDto](doc//FaceGeometryDto.md)
|
||||
- [ImportAssetDto](doc//ImportAssetDto.md)
|
||||
- [JobCommand](doc//JobCommand.md)
|
||||
- [JobCommandDto](doc//JobCommandDto.md)
|
||||
|
|
20
mobile/openapi/doc/FaceGeometryDto.md
generated
Normal file
20
mobile/openapi/doc/FaceGeometryDto.md
generated
Normal file
|
@ -0,0 +1,20 @@
|
|||
# openapi.model.FaceGeometryDto
|
||||
|
||||
## Load the model package
|
||||
```dart
|
||||
import 'package:openapi/api.dart';
|
||||
```
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**boundingBoxX1** | **int** | |
|
||||
**boundingBoxX2** | **int** | |
|
||||
**boundingBoxY1** | **int** | |
|
||||
**boundingBoxY2** | **int** | |
|
||||
**imageHeight** | **int** | |
|
||||
**imageWidth** | **int** | |
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
1
mobile/openapi/doc/PersonResponseDto.md
generated
1
mobile/openapi/doc/PersonResponseDto.md
generated
|
@ -9,6 +9,7 @@ import 'package:openapi/api.dart';
|
|||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**birthDate** | [**DateTime**](DateTime.md) | |
|
||||
**geometry** | [**FaceGeometryDto**](FaceGeometryDto.md) | | [optional]
|
||||
**id** | **String** | |
|
||||
**isHidden** | **bool** | |
|
||||
**name** | **String** | |
|
||||
|
|
1
mobile/openapi/lib/api.dart
generated
1
mobile/openapi/lib/api.dart
generated
|
@ -87,6 +87,7 @@ part 'model/download_archive_info.dart';
|
|||
part 'model/download_info_dto.dart';
|
||||
part 'model/download_response_dto.dart';
|
||||
part 'model/exif_response_dto.dart';
|
||||
part 'model/face_geometry_dto.dart';
|
||||
part 'model/import_asset_dto.dart';
|
||||
part 'model/job_command.dart';
|
||||
part 'model/job_command_dto.dart';
|
||||
|
|
2
mobile/openapi/lib/api_client.dart
generated
2
mobile/openapi/lib/api_client.dart
generated
|
@ -269,6 +269,8 @@ class ApiClient {
|
|||
return DownloadResponseDto.fromJson(value);
|
||||
case 'ExifResponseDto':
|
||||
return ExifResponseDto.fromJson(value);
|
||||
case 'FaceGeometryDto':
|
||||
return FaceGeometryDto.fromJson(value);
|
||||
case 'ImportAssetDto':
|
||||
return ImportAssetDto.fromJson(value);
|
||||
case 'JobCommand':
|
||||
|
|
138
mobile/openapi/lib/model/face_geometry_dto.dart
generated
Normal file
138
mobile/openapi/lib/model/face_geometry_dto.dart
generated
Normal file
|
@ -0,0 +1,138 @@
|
|||
//
|
||||
// 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 FaceGeometryDto {
|
||||
/// Returns a new [FaceGeometryDto] instance.
|
||||
FaceGeometryDto({
|
||||
required this.boundingBoxX1,
|
||||
required this.boundingBoxX2,
|
||||
required this.boundingBoxY1,
|
||||
required this.boundingBoxY2,
|
||||
required this.imageHeight,
|
||||
required this.imageWidth,
|
||||
});
|
||||
|
||||
int boundingBoxX1;
|
||||
|
||||
int boundingBoxX2;
|
||||
|
||||
int boundingBoxY1;
|
||||
|
||||
int boundingBoxY2;
|
||||
|
||||
int imageHeight;
|
||||
|
||||
int imageWidth;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is FaceGeometryDto &&
|
||||
other.boundingBoxX1 == boundingBoxX1 &&
|
||||
other.boundingBoxX2 == boundingBoxX2 &&
|
||||
other.boundingBoxY1 == boundingBoxY1 &&
|
||||
other.boundingBoxY2 == boundingBoxY2 &&
|
||||
other.imageHeight == imageHeight &&
|
||||
other.imageWidth == imageWidth;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(boundingBoxX1.hashCode) +
|
||||
(boundingBoxX2.hashCode) +
|
||||
(boundingBoxY1.hashCode) +
|
||||
(boundingBoxY2.hashCode) +
|
||||
(imageHeight.hashCode) +
|
||||
(imageWidth.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'FaceGeometryDto[boundingBoxX1=$boundingBoxX1, boundingBoxX2=$boundingBoxX2, boundingBoxY1=$boundingBoxY1, boundingBoxY2=$boundingBoxY2, imageHeight=$imageHeight, imageWidth=$imageWidth]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'boundingBoxX1'] = this.boundingBoxX1;
|
||||
json[r'boundingBoxX2'] = this.boundingBoxX2;
|
||||
json[r'boundingBoxY1'] = this.boundingBoxY1;
|
||||
json[r'boundingBoxY2'] = this.boundingBoxY2;
|
||||
json[r'imageHeight'] = this.imageHeight;
|
||||
json[r'imageWidth'] = this.imageWidth;
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [FaceGeometryDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static FaceGeometryDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return FaceGeometryDto(
|
||||
boundingBoxX1: mapValueOfType<int>(json, r'boundingBoxX1')!,
|
||||
boundingBoxX2: mapValueOfType<int>(json, r'boundingBoxX2')!,
|
||||
boundingBoxY1: mapValueOfType<int>(json, r'boundingBoxY1')!,
|
||||
boundingBoxY2: mapValueOfType<int>(json, r'boundingBoxY2')!,
|
||||
imageHeight: mapValueOfType<int>(json, r'imageHeight')!,
|
||||
imageWidth: mapValueOfType<int>(json, r'imageWidth')!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<FaceGeometryDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <FaceGeometryDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = FaceGeometryDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, FaceGeometryDto> mapFromJson(dynamic json) {
|
||||
final map = <String, FaceGeometryDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = FaceGeometryDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of FaceGeometryDto-objects as value to a dart map
|
||||
static Map<String, List<FaceGeometryDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<FaceGeometryDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = FaceGeometryDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'boundingBoxX1',
|
||||
'boundingBoxX2',
|
||||
'boundingBoxY1',
|
||||
'boundingBoxY2',
|
||||
'imageHeight',
|
||||
'imageWidth',
|
||||
};
|
||||
}
|
||||
|
19
mobile/openapi/lib/model/person_response_dto.dart
generated
19
mobile/openapi/lib/model/person_response_dto.dart
generated
|
@ -14,6 +14,7 @@ class PersonResponseDto {
|
|||
/// Returns a new [PersonResponseDto] instance.
|
||||
PersonResponseDto({
|
||||
required this.birthDate,
|
||||
this.geometry,
|
||||
required this.id,
|
||||
required this.isHidden,
|
||||
required this.name,
|
||||
|
@ -22,6 +23,14 @@ class PersonResponseDto {
|
|||
|
||||
DateTime? birthDate;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
FaceGeometryDto? geometry;
|
||||
|
||||
String id;
|
||||
|
||||
bool isHidden;
|
||||
|
@ -33,6 +42,7 @@ class PersonResponseDto {
|
|||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is PersonResponseDto &&
|
||||
other.birthDate == birthDate &&
|
||||
other.geometry == geometry &&
|
||||
other.id == id &&
|
||||
other.isHidden == isHidden &&
|
||||
other.name == name &&
|
||||
|
@ -42,13 +52,14 @@ class PersonResponseDto {
|
|||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||
(geometry == null ? 0 : geometry!.hashCode) +
|
||||
(id.hashCode) +
|
||||
(isHidden.hashCode) +
|
||||
(name.hashCode) +
|
||||
(thumbnailPath.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'PersonResponseDto[birthDate=$birthDate, id=$id, isHidden=$isHidden, name=$name, thumbnailPath=$thumbnailPath]';
|
||||
String toString() => 'PersonResponseDto[birthDate=$birthDate, geometry=$geometry, id=$id, isHidden=$isHidden, name=$name, thumbnailPath=$thumbnailPath]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
|
@ -56,6 +67,11 @@ class PersonResponseDto {
|
|||
json[r'birthDate'] = _dateFormatter.format(this.birthDate!.toUtc());
|
||||
} else {
|
||||
// json[r'birthDate'] = null;
|
||||
}
|
||||
if (this.geometry != null) {
|
||||
json[r'geometry'] = this.geometry;
|
||||
} else {
|
||||
// json[r'geometry'] = null;
|
||||
}
|
||||
json[r'id'] = this.id;
|
||||
json[r'isHidden'] = this.isHidden;
|
||||
|
@ -73,6 +89,7 @@ class PersonResponseDto {
|
|||
|
||||
return PersonResponseDto(
|
||||
birthDate: mapDateTime(json, r'birthDate', ''),
|
||||
geometry: FaceGeometryDto.fromJson(json[r'geometry']),
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
isHidden: mapValueOfType<bool>(json, r'isHidden')!,
|
||||
name: mapValueOfType<String>(json, r'name')!,
|
||||
|
|
|
@ -10,7 +10,7 @@ environment:
|
|||
sdk: '>=2.12.0 <3.0.0'
|
||||
dependencies:
|
||||
http: '>=0.13.0 <0.14.0'
|
||||
intl: '^0.18.0'
|
||||
intl: '^0.17.0'
|
||||
meta: '^1.1.8'
|
||||
dev_dependencies:
|
||||
test: '>=1.16.0 <1.18.0'
|
||||
|
|
52
mobile/openapi/test/face_geometry_dto_test.dart
generated
Normal file
52
mobile/openapi/test/face_geometry_dto_test.dart
generated
Normal file
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// 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 FaceGeometryDto
|
||||
void main() {
|
||||
// final instance = FaceGeometryDto();
|
||||
|
||||
group('test FaceGeometryDto', () {
|
||||
// int boundingBoxX1
|
||||
test('to test the property `boundingBoxX1`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int boundingBoxX2
|
||||
test('to test the property `boundingBoxX2`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int boundingBoxY1
|
||||
test('to test the property `boundingBoxY1`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int boundingBoxY2
|
||||
test('to test the property `boundingBoxY2`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int imageHeight
|
||||
test('to test the property `imageHeight`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int imageWidth
|
||||
test('to test the property `imageWidth`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
|
@ -21,6 +21,11 @@ void main() {
|
|||
// TODO
|
||||
});
|
||||
|
||||
// FaceGeometryDto geometry
|
||||
test('to test the property `geometry`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String id
|
||||
test('to test the property `id`', () async {
|
||||
// TODO
|
||||
|
|
|
@ -5814,6 +5814,37 @@
|
|||
},
|
||||
"type": "object"
|
||||
},
|
||||
"FaceGeometryDto": {
|
||||
"properties": {
|
||||
"boundingBoxX1": {
|
||||
"type": "integer"
|
||||
},
|
||||
"boundingBoxX2": {
|
||||
"type": "integer"
|
||||
},
|
||||
"boundingBoxY1": {
|
||||
"type": "integer"
|
||||
},
|
||||
"boundingBoxY2": {
|
||||
"type": "integer"
|
||||
},
|
||||
"imageHeight": {
|
||||
"type": "integer"
|
||||
},
|
||||
"imageWidth": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageWidth",
|
||||
"imageHeight",
|
||||
"boundingBoxX1",
|
||||
"boundingBoxY1",
|
||||
"boundingBoxX2",
|
||||
"boundingBoxY2"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ImportAssetDto": {
|
||||
"properties": {
|
||||
"assetPath": {
|
||||
|
@ -6211,6 +6242,9 @@
|
|||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"geometry": {
|
||||
"$ref": "#/components/schemas/FaceGeometryDto"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
@ -103,6 +103,21 @@ export class PersonSearchDto {
|
|||
withHidden?: boolean = false;
|
||||
}
|
||||
|
||||
export class FaceGeometryDto {
|
||||
@ApiProperty({ type: 'integer' })
|
||||
imageWidth!: number;
|
||||
@ApiProperty({ type: 'integer' })
|
||||
imageHeight!: number;
|
||||
@ApiProperty({ type: 'integer' })
|
||||
boundingBoxX1!: number;
|
||||
@ApiProperty({ type: 'integer' })
|
||||
boundingBoxY1!: number;
|
||||
@ApiProperty({ type: 'integer' })
|
||||
boundingBoxX2!: number;
|
||||
@ApiProperty({ type: 'integer' })
|
||||
boundingBoxY2!: number;
|
||||
}
|
||||
|
||||
export class PersonResponseDto {
|
||||
id!: string;
|
||||
name!: string;
|
||||
|
@ -110,6 +125,7 @@ export class PersonResponseDto {
|
|||
birthDate!: Date | null;
|
||||
thumbnailPath!: string;
|
||||
isHidden!: boolean;
|
||||
geometry?: FaceGeometryDto;
|
||||
}
|
||||
|
||||
export class PeopleResponseDto {
|
||||
|
@ -132,6 +148,23 @@ export function mapPerson(person: PersonEntity): PersonResponseDto {
|
|||
};
|
||||
}
|
||||
|
||||
export function mapFace(face: AssetFaceEntity): PersonResponseDto {
|
||||
return mapPerson(face.person);
|
||||
export function mapGeometry(entity: AssetFaceEntity) {
|
||||
return {
|
||||
imageWidth: entity.imageWidth,
|
||||
imageHeight: entity.imageHeight,
|
||||
boundingBoxX1: entity.boundingBoxX1,
|
||||
boundingBoxY1: entity.boundingBoxY1,
|
||||
boundingBoxX2: entity.boundingBoxX2,
|
||||
boundingBoxY2: entity.boundingBoxY2,
|
||||
};
|
||||
}
|
||||
export function mapFace(entity: AssetFaceEntity): PersonResponseDto {
|
||||
return {
|
||||
id: entity.person.id,
|
||||
name: entity.person.name,
|
||||
birthDate: entity.person.birthDate,
|
||||
thumbnailPath: entity.person.thumbnailPath,
|
||||
isHidden: entity.person.isHidden,
|
||||
geometry: mapGeometry(entity),
|
||||
};
|
||||
}
|
||||
|
|
49
web/src/api/open-api/api.ts
generated
49
web/src/api/open-api/api.ts
generated
|
@ -1376,6 +1376,49 @@ export interface ExifResponseDto {
|
|||
*/
|
||||
'timeZone'?: string | null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface FaceGeometryDto
|
||||
*/
|
||||
export interface FaceGeometryDto {
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'boundingBoxX1': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'boundingBoxX2': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'boundingBoxY1': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'boundingBoxY2': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'imageHeight': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FaceGeometryDto
|
||||
*/
|
||||
'imageWidth': number;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
@ -1883,6 +1926,12 @@ export interface PersonResponseDto {
|
|||
* @memberof PersonResponseDto
|
||||
*/
|
||||
'birthDate': string | null;
|
||||
/**
|
||||
*
|
||||
* @type {FaceGeometryDto}
|
||||
* @memberof PersonResponseDto
|
||||
*/
|
||||
'geometry'?: FaceGeometryDto;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
|
|
|
@ -77,23 +77,23 @@
|
|||
};
|
||||
</script>
|
||||
|
||||
<section class="p-2 dark:bg-immich-dark-bg dark:text-immich-dark-fg">
|
||||
<section class="dark:bg-immich-dark-bg dark:text-immich-dark-fg p-2">
|
||||
<div class="flex place-items-center gap-2">
|
||||
<button
|
||||
class="flex place-content-center place-items-center rounded-full p-3 transition-colors hover:bg-gray-200 dark:text-immich-dark-fg dark:hover:bg-gray-900"
|
||||
class="dark:text-immich-dark-fg flex place-content-center place-items-center rounded-full p-3 transition-colors hover:bg-gray-200 dark:hover:bg-gray-900"
|
||||
on:click={() => dispatch('close')}
|
||||
>
|
||||
<Close size="24" />
|
||||
</button>
|
||||
|
||||
<p class="text-lg text-immich-fg dark:text-immich-dark-fg">Info</p>
|
||||
<p class="text-immich-fg dark:text-immich-dark-fg text-lg">Info</p>
|
||||
</div>
|
||||
|
||||
<section class="mx-4 mt-10">
|
||||
<textarea
|
||||
bind:this={textarea}
|
||||
class="max-h-[500px]
|
||||
w-full resize-none overflow-hidden border-b border-gray-500 bg-transparent text-base text-black outline-none transition-all focus:border-b-2 focus:border-immich-primary disabled:border-none dark:text-white dark:focus:border-immich-dark-primary"
|
||||
class="focus:border-immich-primary
|
||||
dark:focus:border-immich-dark-primary max-h-[500px] w-full resize-none overflow-hidden border-b border-gray-500 bg-transparent text-base text-black outline-none transition-all focus:border-b-2 disabled:border-none dark:text-white"
|
||||
placeholder={$page?.data?.user?.id !== asset.ownerId ? '' : 'Add a description'}
|
||||
style:display={$page?.data?.user?.id !== asset.ownerId && textarea?.value == '' ? 'none' : 'block'}
|
||||
on:focusin={handleFocusIn}
|
||||
|
@ -110,7 +110,15 @@
|
|||
|
||||
<div class="mt-4 flex flex-wrap gap-2">
|
||||
{#each people as person (person.id)}
|
||||
<a href="/people/{person.id}" class="w-[90px]" on:click={() => dispatch('close-viewer')}>
|
||||
<a
|
||||
href="/people/{person.id}"
|
||||
class="w-[90px]"
|
||||
on:click={() => dispatch('close-viewer')}
|
||||
on:mouseover={() => {
|
||||
console.log(asset);
|
||||
}}
|
||||
on:focus={() => console.log('focus')}
|
||||
>
|
||||
<ImageThumbnail
|
||||
curve
|
||||
shadow
|
||||
|
@ -262,7 +270,7 @@
|
|||
</div>
|
||||
{/if}
|
||||
|
||||
<section class="p-2 dark:text-immich-dark-fg">
|
||||
<section class="dark:text-immich-dark-fg p-2">
|
||||
<div class="px-4 py-4">
|
||||
{#if albums.length > 0}
|
||||
<p class="pb-4 text-sm">APPEARS IN</p>
|
||||
|
|
Loading…
Reference in a new issue