mirror of
https://github.com/immich-app/immich.git
synced 2026-03-22 11:09:21 +03:00
feat: getAssetEdits respond with edit IDs (#26445)
* feat: getAssetEdits respond with edit IDs * chore: cleanup typings for edit API * chore: cleanup types with jason * fix: openapi sync * fix: factory
This commit is contained in:
11
mobile/openapi/README.md
generated
11
mobile/openapi/README.md
generated
@@ -358,12 +358,11 @@ Class | Method | HTTP request | Description
|
|||||||
- [AssetDeltaSyncDto](doc//AssetDeltaSyncDto.md)
|
- [AssetDeltaSyncDto](doc//AssetDeltaSyncDto.md)
|
||||||
- [AssetDeltaSyncResponseDto](doc//AssetDeltaSyncResponseDto.md)
|
- [AssetDeltaSyncResponseDto](doc//AssetDeltaSyncResponseDto.md)
|
||||||
- [AssetEditAction](doc//AssetEditAction.md)
|
- [AssetEditAction](doc//AssetEditAction.md)
|
||||||
- [AssetEditActionCrop](doc//AssetEditActionCrop.md)
|
- [AssetEditActionItemDto](doc//AssetEditActionItemDto.md)
|
||||||
- [AssetEditActionListDto](doc//AssetEditActionListDto.md)
|
- [AssetEditActionItemDtoParameters](doc//AssetEditActionItemDtoParameters.md)
|
||||||
- [AssetEditActionListDtoEditsInner](doc//AssetEditActionListDtoEditsInner.md)
|
- [AssetEditActionItemResponseDto](doc//AssetEditActionItemResponseDto.md)
|
||||||
- [AssetEditActionMirror](doc//AssetEditActionMirror.md)
|
- [AssetEditsCreateDto](doc//AssetEditsCreateDto.md)
|
||||||
- [AssetEditActionRotate](doc//AssetEditActionRotate.md)
|
- [AssetEditsResponseDto](doc//AssetEditsResponseDto.md)
|
||||||
- [AssetEditsDto](doc//AssetEditsDto.md)
|
|
||||||
- [AssetFaceCreateDto](doc//AssetFaceCreateDto.md)
|
- [AssetFaceCreateDto](doc//AssetFaceCreateDto.md)
|
||||||
- [AssetFaceDeleteDto](doc//AssetFaceDeleteDto.md)
|
- [AssetFaceDeleteDto](doc//AssetFaceDeleteDto.md)
|
||||||
- [AssetFaceResponseDto](doc//AssetFaceResponseDto.md)
|
- [AssetFaceResponseDto](doc//AssetFaceResponseDto.md)
|
||||||
|
|||||||
11
mobile/openapi/lib/api.dart
generated
11
mobile/openapi/lib/api.dart
generated
@@ -97,12 +97,11 @@ part 'model/asset_copy_dto.dart';
|
|||||||
part 'model/asset_delta_sync_dto.dart';
|
part 'model/asset_delta_sync_dto.dart';
|
||||||
part 'model/asset_delta_sync_response_dto.dart';
|
part 'model/asset_delta_sync_response_dto.dart';
|
||||||
part 'model/asset_edit_action.dart';
|
part 'model/asset_edit_action.dart';
|
||||||
part 'model/asset_edit_action_crop.dart';
|
part 'model/asset_edit_action_item_dto.dart';
|
||||||
part 'model/asset_edit_action_list_dto.dart';
|
part 'model/asset_edit_action_item_dto_parameters.dart';
|
||||||
part 'model/asset_edit_action_list_dto_edits_inner.dart';
|
part 'model/asset_edit_action_item_response_dto.dart';
|
||||||
part 'model/asset_edit_action_mirror.dart';
|
part 'model/asset_edits_create_dto.dart';
|
||||||
part 'model/asset_edit_action_rotate.dart';
|
part 'model/asset_edits_response_dto.dart';
|
||||||
part 'model/asset_edits_dto.dart';
|
|
||||||
part 'model/asset_face_create_dto.dart';
|
part 'model/asset_face_create_dto.dart';
|
||||||
part 'model/asset_face_delete_dto.dart';
|
part 'model/asset_face_delete_dto.dart';
|
||||||
part 'model/asset_face_response_dto.dart';
|
part 'model/asset_face_response_dto.dart';
|
||||||
|
|||||||
18
mobile/openapi/lib/api/assets_api.dart
generated
18
mobile/openapi/lib/api/assets_api.dart
generated
@@ -421,14 +421,14 @@ class AssetsApi {
|
|||||||
///
|
///
|
||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
///
|
///
|
||||||
/// * [AssetEditActionListDto] assetEditActionListDto (required):
|
/// * [AssetEditsCreateDto] assetEditsCreateDto (required):
|
||||||
Future<Response> editAssetWithHttpInfo(String id, AssetEditActionListDto assetEditActionListDto,) async {
|
Future<Response> editAssetWithHttpInfo(String id, AssetEditsCreateDto assetEditsCreateDto,) async {
|
||||||
// ignore: prefer_const_declarations
|
// ignore: prefer_const_declarations
|
||||||
final apiPath = r'/assets/{id}/edits'
|
final apiPath = r'/assets/{id}/edits'
|
||||||
.replaceAll('{id}', id);
|
.replaceAll('{id}', id);
|
||||||
|
|
||||||
// ignore: prefer_final_locals
|
// ignore: prefer_final_locals
|
||||||
Object? postBody = assetEditActionListDto;
|
Object? postBody = assetEditsCreateDto;
|
||||||
|
|
||||||
final queryParams = <QueryParam>[];
|
final queryParams = <QueryParam>[];
|
||||||
final headerParams = <String, String>{};
|
final headerParams = <String, String>{};
|
||||||
@@ -456,9 +456,9 @@ class AssetsApi {
|
|||||||
///
|
///
|
||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
///
|
///
|
||||||
/// * [AssetEditActionListDto] assetEditActionListDto (required):
|
/// * [AssetEditsCreateDto] assetEditsCreateDto (required):
|
||||||
Future<AssetEditsDto?> editAsset(String id, AssetEditActionListDto assetEditActionListDto,) async {
|
Future<AssetEditsResponseDto?> editAsset(String id, AssetEditsCreateDto assetEditsCreateDto,) async {
|
||||||
final response = await editAssetWithHttpInfo(id, assetEditActionListDto,);
|
final response = await editAssetWithHttpInfo(id, assetEditsCreateDto,);
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
}
|
}
|
||||||
@@ -466,7 +466,7 @@ class AssetsApi {
|
|||||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||||
// FormatException when trying to decode an empty string.
|
// FormatException when trying to decode an empty string.
|
||||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AssetEditsDto',) as AssetEditsDto;
|
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AssetEditsResponseDto',) as AssetEditsResponseDto;
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -576,7 +576,7 @@ class AssetsApi {
|
|||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
Future<AssetEditsDto?> getAssetEdits(String id,) async {
|
Future<AssetEditsResponseDto?> getAssetEdits(String id,) async {
|
||||||
final response = await getAssetEditsWithHttpInfo(id,);
|
final response = await getAssetEditsWithHttpInfo(id,);
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
@@ -585,7 +585,7 @@ class AssetsApi {
|
|||||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||||
// FormatException when trying to decode an empty string.
|
// FormatException when trying to decode an empty string.
|
||||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AssetEditsDto',) as AssetEditsDto;
|
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AssetEditsResponseDto',) as AssetEditsResponseDto;
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
22
mobile/openapi/lib/api_client.dart
generated
22
mobile/openapi/lib/api_client.dart
generated
@@ -240,18 +240,16 @@ class ApiClient {
|
|||||||
return AssetDeltaSyncResponseDto.fromJson(value);
|
return AssetDeltaSyncResponseDto.fromJson(value);
|
||||||
case 'AssetEditAction':
|
case 'AssetEditAction':
|
||||||
return AssetEditActionTypeTransformer().decode(value);
|
return AssetEditActionTypeTransformer().decode(value);
|
||||||
case 'AssetEditActionCrop':
|
case 'AssetEditActionItemDto':
|
||||||
return AssetEditActionCrop.fromJson(value);
|
return AssetEditActionItemDto.fromJson(value);
|
||||||
case 'AssetEditActionListDto':
|
case 'AssetEditActionItemDtoParameters':
|
||||||
return AssetEditActionListDto.fromJson(value);
|
return AssetEditActionItemDtoParameters.fromJson(value);
|
||||||
case 'AssetEditActionListDtoEditsInner':
|
case 'AssetEditActionItemResponseDto':
|
||||||
return AssetEditActionListDtoEditsInner.fromJson(value);
|
return AssetEditActionItemResponseDto.fromJson(value);
|
||||||
case 'AssetEditActionMirror':
|
case 'AssetEditsCreateDto':
|
||||||
return AssetEditActionMirror.fromJson(value);
|
return AssetEditsCreateDto.fromJson(value);
|
||||||
case 'AssetEditActionRotate':
|
case 'AssetEditsResponseDto':
|
||||||
return AssetEditActionRotate.fromJson(value);
|
return AssetEditsResponseDto.fromJson(value);
|
||||||
case 'AssetEditsDto':
|
|
||||||
return AssetEditsDto.fromJson(value);
|
|
||||||
case 'AssetFaceCreateDto':
|
case 'AssetFaceCreateDto':
|
||||||
return AssetFaceCreateDto.fromJson(value);
|
return AssetFaceCreateDto.fromJson(value);
|
||||||
case 'AssetFaceDeleteDto':
|
case 'AssetFaceDeleteDto':
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
part of openapi.api;
|
part of openapi.api;
|
||||||
|
|
||||||
class AssetEditActionCrop {
|
class AssetEditActionItemDto {
|
||||||
/// Returns a new [AssetEditActionCrop] instance.
|
/// Returns a new [AssetEditActionItemDto] instance.
|
||||||
AssetEditActionCrop({
|
AssetEditActionItemDto({
|
||||||
required this.action,
|
required this.action,
|
||||||
required this.parameters,
|
required this.parameters,
|
||||||
});
|
});
|
||||||
@@ -20,10 +20,10 @@ class AssetEditActionCrop {
|
|||||||
/// Type of edit action to perform
|
/// Type of edit action to perform
|
||||||
AssetEditAction action;
|
AssetEditAction action;
|
||||||
|
|
||||||
CropParameters parameters;
|
AssetEditActionItemDtoParameters parameters;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is AssetEditActionCrop &&
|
bool operator ==(Object other) => identical(this, other) || other is AssetEditActionItemDto &&
|
||||||
other.action == action &&
|
other.action == action &&
|
||||||
other.parameters == parameters;
|
other.parameters == parameters;
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ class AssetEditActionCrop {
|
|||||||
(parameters.hashCode);
|
(parameters.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AssetEditActionCrop[action=$action, parameters=$parameters]';
|
String toString() => 'AssetEditActionItemDto[action=$action, parameters=$parameters]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@@ -43,27 +43,27 @@ class AssetEditActionCrop {
|
|||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new [AssetEditActionCrop] instance and imports its values from
|
/// Returns a new [AssetEditActionItemDto] instance and imports its values from
|
||||||
/// [value] if it's a [Map], null otherwise.
|
/// [value] if it's a [Map], null otherwise.
|
||||||
// ignore: prefer_constructors_over_static_methods
|
// ignore: prefer_constructors_over_static_methods
|
||||||
static AssetEditActionCrop? fromJson(dynamic value) {
|
static AssetEditActionItemDto? fromJson(dynamic value) {
|
||||||
upgradeDto(value, "AssetEditActionCrop");
|
upgradeDto(value, "AssetEditActionItemDto");
|
||||||
if (value is Map) {
|
if (value is Map) {
|
||||||
final json = value.cast<String, dynamic>();
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
return AssetEditActionCrop(
|
return AssetEditActionItemDto(
|
||||||
action: AssetEditAction.fromJson(json[r'action'])!,
|
action: AssetEditAction.fromJson(json[r'action'])!,
|
||||||
parameters: CropParameters.fromJson(json[r'parameters'])!,
|
parameters: AssetEditActionItemDtoParameters.fromJson(json[r'parameters'])!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<AssetEditActionCrop> listFromJson(dynamic json, {bool growable = false,}) {
|
static List<AssetEditActionItemDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
final result = <AssetEditActionCrop>[];
|
final result = <AssetEditActionItemDto>[];
|
||||||
if (json is List && json.isNotEmpty) {
|
if (json is List && json.isNotEmpty) {
|
||||||
for (final row in json) {
|
for (final row in json) {
|
||||||
final value = AssetEditActionCrop.fromJson(row);
|
final value = AssetEditActionItemDto.fromJson(row);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result.add(value);
|
result.add(value);
|
||||||
}
|
}
|
||||||
@@ -72,12 +72,12 @@ class AssetEditActionCrop {
|
|||||||
return result.toList(growable: growable);
|
return result.toList(growable: growable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, AssetEditActionCrop> mapFromJson(dynamic json) {
|
static Map<String, AssetEditActionItemDto> mapFromJson(dynamic json) {
|
||||||
final map = <String, AssetEditActionCrop>{};
|
final map = <String, AssetEditActionItemDto>{};
|
||||||
if (json is Map && json.isNotEmpty) {
|
if (json is Map && json.isNotEmpty) {
|
||||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
for (final entry in json.entries) {
|
for (final entry in json.entries) {
|
||||||
final value = AssetEditActionCrop.fromJson(entry.value);
|
final value = AssetEditActionItemDto.fromJson(entry.value);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
map[entry.key] = value;
|
map[entry.key] = value;
|
||||||
}
|
}
|
||||||
@@ -86,14 +86,14 @@ class AssetEditActionCrop {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
// maps a json object with a list of AssetEditActionCrop-objects as value to a dart map
|
// maps a json object with a list of AssetEditActionItemDto-objects as value to a dart map
|
||||||
static Map<String, List<AssetEditActionCrop>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
static Map<String, List<AssetEditActionItemDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
final map = <String, List<AssetEditActionCrop>>{};
|
final map = <String, List<AssetEditActionItemDto>>{};
|
||||||
if (json is Map && json.isNotEmpty) {
|
if (json is Map && json.isNotEmpty) {
|
||||||
// ignore: parameter_assignments
|
// ignore: parameter_assignments
|
||||||
json = json.cast<String, dynamic>();
|
json = json.cast<String, dynamic>();
|
||||||
for (final entry in json.entries) {
|
for (final entry in json.entries) {
|
||||||
map[entry.key] = AssetEditActionCrop.listFromJson(entry.value, growable: growable,);
|
map[entry.key] = AssetEditActionItemDto.listFromJson(entry.value, growable: growable,);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
153
mobile/openapi/lib/model/asset_edit_action_item_dto_parameters.dart
generated
Normal file
153
mobile/openapi/lib/model/asset_edit_action_item_dto_parameters.dart
generated
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.18
|
||||||
|
|
||||||
|
// 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 AssetEditActionItemDtoParameters {
|
||||||
|
/// Returns a new [AssetEditActionItemDtoParameters] instance.
|
||||||
|
AssetEditActionItemDtoParameters({
|
||||||
|
required this.height,
|
||||||
|
required this.width,
|
||||||
|
required this.x,
|
||||||
|
required this.y,
|
||||||
|
required this.angle,
|
||||||
|
required this.axis,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Height of the crop
|
||||||
|
///
|
||||||
|
/// Minimum value: 1
|
||||||
|
num height;
|
||||||
|
|
||||||
|
/// Width of the crop
|
||||||
|
///
|
||||||
|
/// Minimum value: 1
|
||||||
|
num width;
|
||||||
|
|
||||||
|
/// Top-Left X coordinate of crop
|
||||||
|
///
|
||||||
|
/// Minimum value: 0
|
||||||
|
num x;
|
||||||
|
|
||||||
|
/// Top-Left Y coordinate of crop
|
||||||
|
///
|
||||||
|
/// Minimum value: 0
|
||||||
|
num y;
|
||||||
|
|
||||||
|
/// Rotation angle in degrees
|
||||||
|
num angle;
|
||||||
|
|
||||||
|
/// Axis to mirror along
|
||||||
|
MirrorAxis axis;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => identical(this, other) || other is AssetEditActionItemDtoParameters &&
|
||||||
|
other.height == height &&
|
||||||
|
other.width == width &&
|
||||||
|
other.x == x &&
|
||||||
|
other.y == y &&
|
||||||
|
other.angle == angle &&
|
||||||
|
other.axis == axis;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
// ignore: unnecessary_parenthesis
|
||||||
|
(height.hashCode) +
|
||||||
|
(width.hashCode) +
|
||||||
|
(x.hashCode) +
|
||||||
|
(y.hashCode) +
|
||||||
|
(angle.hashCode) +
|
||||||
|
(axis.hashCode);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'AssetEditActionItemDtoParameters[height=$height, width=$width, x=$x, y=$y, angle=$angle, axis=$axis]';
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final json = <String, dynamic>{};
|
||||||
|
json[r'height'] = this.height;
|
||||||
|
json[r'width'] = this.width;
|
||||||
|
json[r'x'] = this.x;
|
||||||
|
json[r'y'] = this.y;
|
||||||
|
json[r'angle'] = this.angle;
|
||||||
|
json[r'axis'] = this.axis;
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new [AssetEditActionItemDtoParameters] instance and imports its values from
|
||||||
|
/// [value] if it's a [Map], null otherwise.
|
||||||
|
// ignore: prefer_constructors_over_static_methods
|
||||||
|
static AssetEditActionItemDtoParameters? fromJson(dynamic value) {
|
||||||
|
upgradeDto(value, "AssetEditActionItemDtoParameters");
|
||||||
|
if (value is Map) {
|
||||||
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
|
return AssetEditActionItemDtoParameters(
|
||||||
|
height: num.parse('${json[r'height']}'),
|
||||||
|
width: num.parse('${json[r'width']}'),
|
||||||
|
x: num.parse('${json[r'x']}'),
|
||||||
|
y: num.parse('${json[r'y']}'),
|
||||||
|
angle: num.parse('${json[r'angle']}'),
|
||||||
|
axis: MirrorAxis.fromJson(json[r'axis'])!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<AssetEditActionItemDtoParameters> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <AssetEditActionItemDtoParameters>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = AssetEditActionItemDtoParameters.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Map<String, AssetEditActionItemDtoParameters> mapFromJson(dynamic json) {
|
||||||
|
final map = <String, AssetEditActionItemDtoParameters>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
final value = AssetEditActionItemDtoParameters.fromJson(entry.value);
|
||||||
|
if (value != null) {
|
||||||
|
map[entry.key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maps a json object with a list of AssetEditActionItemDtoParameters-objects as value to a dart map
|
||||||
|
static Map<String, List<AssetEditActionItemDtoParameters>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final map = <String, List<AssetEditActionItemDtoParameters>>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
json = json.cast<String, dynamic>();
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
map[entry.key] = AssetEditActionItemDtoParameters.listFromJson(entry.value, growable: growable,);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The list of required keys that must be present in a JSON.
|
||||||
|
static const requiredKeys = <String>{
|
||||||
|
'height',
|
||||||
|
'width',
|
||||||
|
'x',
|
||||||
|
'y',
|
||||||
|
'angle',
|
||||||
|
'axis',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@@ -10,60 +10,67 @@
|
|||||||
|
|
||||||
part of openapi.api;
|
part of openapi.api;
|
||||||
|
|
||||||
class AssetEditActionListDtoEditsInner {
|
class AssetEditActionItemResponseDto {
|
||||||
/// Returns a new [AssetEditActionListDtoEditsInner] instance.
|
/// Returns a new [AssetEditActionItemResponseDto] instance.
|
||||||
AssetEditActionListDtoEditsInner({
|
AssetEditActionItemResponseDto({
|
||||||
required this.action,
|
required this.action,
|
||||||
|
required this.id,
|
||||||
required this.parameters,
|
required this.parameters,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Type of edit action to perform
|
/// Type of edit action to perform
|
||||||
AssetEditAction action;
|
AssetEditAction action;
|
||||||
|
|
||||||
MirrorParameters parameters;
|
String id;
|
||||||
|
|
||||||
|
AssetEditActionItemDtoParameters parameters;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is AssetEditActionListDtoEditsInner &&
|
bool operator ==(Object other) => identical(this, other) || other is AssetEditActionItemResponseDto &&
|
||||||
other.action == action &&
|
other.action == action &&
|
||||||
|
other.id == id &&
|
||||||
other.parameters == parameters;
|
other.parameters == parameters;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(action.hashCode) +
|
(action.hashCode) +
|
||||||
|
(id.hashCode) +
|
||||||
(parameters.hashCode);
|
(parameters.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AssetEditActionListDtoEditsInner[action=$action, parameters=$parameters]';
|
String toString() => 'AssetEditActionItemResponseDto[action=$action, id=$id, parameters=$parameters]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
json[r'action'] = this.action;
|
json[r'action'] = this.action;
|
||||||
|
json[r'id'] = this.id;
|
||||||
json[r'parameters'] = this.parameters;
|
json[r'parameters'] = this.parameters;
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new [AssetEditActionListDtoEditsInner] instance and imports its values from
|
/// Returns a new [AssetEditActionItemResponseDto] instance and imports its values from
|
||||||
/// [value] if it's a [Map], null otherwise.
|
/// [value] if it's a [Map], null otherwise.
|
||||||
// ignore: prefer_constructors_over_static_methods
|
// ignore: prefer_constructors_over_static_methods
|
||||||
static AssetEditActionListDtoEditsInner? fromJson(dynamic value) {
|
static AssetEditActionItemResponseDto? fromJson(dynamic value) {
|
||||||
upgradeDto(value, "AssetEditActionListDtoEditsInner");
|
upgradeDto(value, "AssetEditActionItemResponseDto");
|
||||||
if (value is Map) {
|
if (value is Map) {
|
||||||
final json = value.cast<String, dynamic>();
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
return AssetEditActionListDtoEditsInner(
|
return AssetEditActionItemResponseDto(
|
||||||
action: AssetEditAction.fromJson(json[r'action'])!,
|
action: AssetEditAction.fromJson(json[r'action'])!,
|
||||||
parameters: MirrorParameters.fromJson(json[r'parameters'])!,
|
id: mapValueOfType<String>(json, r'id')!,
|
||||||
|
parameters: AssetEditActionItemDtoParameters.fromJson(json[r'parameters'])!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<AssetEditActionListDtoEditsInner> listFromJson(dynamic json, {bool growable = false,}) {
|
static List<AssetEditActionItemResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
final result = <AssetEditActionListDtoEditsInner>[];
|
final result = <AssetEditActionItemResponseDto>[];
|
||||||
if (json is List && json.isNotEmpty) {
|
if (json is List && json.isNotEmpty) {
|
||||||
for (final row in json) {
|
for (final row in json) {
|
||||||
final value = AssetEditActionListDtoEditsInner.fromJson(row);
|
final value = AssetEditActionItemResponseDto.fromJson(row);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result.add(value);
|
result.add(value);
|
||||||
}
|
}
|
||||||
@@ -72,12 +79,12 @@ class AssetEditActionListDtoEditsInner {
|
|||||||
return result.toList(growable: growable);
|
return result.toList(growable: growable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, AssetEditActionListDtoEditsInner> mapFromJson(dynamic json) {
|
static Map<String, AssetEditActionItemResponseDto> mapFromJson(dynamic json) {
|
||||||
final map = <String, AssetEditActionListDtoEditsInner>{};
|
final map = <String, AssetEditActionItemResponseDto>{};
|
||||||
if (json is Map && json.isNotEmpty) {
|
if (json is Map && json.isNotEmpty) {
|
||||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
for (final entry in json.entries) {
|
for (final entry in json.entries) {
|
||||||
final value = AssetEditActionListDtoEditsInner.fromJson(entry.value);
|
final value = AssetEditActionItemResponseDto.fromJson(entry.value);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
map[entry.key] = value;
|
map[entry.key] = value;
|
||||||
}
|
}
|
||||||
@@ -86,14 +93,14 @@ class AssetEditActionListDtoEditsInner {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
// maps a json object with a list of AssetEditActionListDtoEditsInner-objects as value to a dart map
|
// maps a json object with a list of AssetEditActionItemResponseDto-objects as value to a dart map
|
||||||
static Map<String, List<AssetEditActionListDtoEditsInner>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
static Map<String, List<AssetEditActionItemResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
final map = <String, List<AssetEditActionListDtoEditsInner>>{};
|
final map = <String, List<AssetEditActionItemResponseDto>>{};
|
||||||
if (json is Map && json.isNotEmpty) {
|
if (json is Map && json.isNotEmpty) {
|
||||||
// ignore: parameter_assignments
|
// ignore: parameter_assignments
|
||||||
json = json.cast<String, dynamic>();
|
json = json.cast<String, dynamic>();
|
||||||
for (final entry in json.entries) {
|
for (final entry in json.entries) {
|
||||||
map[entry.key] = AssetEditActionListDtoEditsInner.listFromJson(entry.value, growable: growable,);
|
map[entry.key] = AssetEditActionItemResponseDto.listFromJson(entry.value, growable: growable,);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
@@ -102,6 +109,7 @@ class AssetEditActionListDtoEditsInner {
|
|||||||
/// The list of required keys that must be present in a JSON.
|
/// The list of required keys that must be present in a JSON.
|
||||||
static const requiredKeys = <String>{
|
static const requiredKeys = <String>{
|
||||||
'action',
|
'action',
|
||||||
|
'id',
|
||||||
'parameters',
|
'parameters',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
108
mobile/openapi/lib/model/asset_edit_action_mirror.dart
generated
108
mobile/openapi/lib/model/asset_edit_action_mirror.dart
generated
@@ -1,108 +0,0 @@
|
|||||||
//
|
|
||||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
|
||||||
//
|
|
||||||
// @dart=2.18
|
|
||||||
|
|
||||||
// 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 AssetEditActionMirror {
|
|
||||||
/// Returns a new [AssetEditActionMirror] instance.
|
|
||||||
AssetEditActionMirror({
|
|
||||||
required this.action,
|
|
||||||
required this.parameters,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Type of edit action to perform
|
|
||||||
AssetEditAction action;
|
|
||||||
|
|
||||||
MirrorParameters parameters;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) => identical(this, other) || other is AssetEditActionMirror &&
|
|
||||||
other.action == action &&
|
|
||||||
other.parameters == parameters;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
// ignore: unnecessary_parenthesis
|
|
||||||
(action.hashCode) +
|
|
||||||
(parameters.hashCode);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'AssetEditActionMirror[action=$action, parameters=$parameters]';
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
final json = <String, dynamic>{};
|
|
||||||
json[r'action'] = this.action;
|
|
||||||
json[r'parameters'] = this.parameters;
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a new [AssetEditActionMirror] instance and imports its values from
|
|
||||||
/// [value] if it's a [Map], null otherwise.
|
|
||||||
// ignore: prefer_constructors_over_static_methods
|
|
||||||
static AssetEditActionMirror? fromJson(dynamic value) {
|
|
||||||
upgradeDto(value, "AssetEditActionMirror");
|
|
||||||
if (value is Map) {
|
|
||||||
final json = value.cast<String, dynamic>();
|
|
||||||
|
|
||||||
return AssetEditActionMirror(
|
|
||||||
action: AssetEditAction.fromJson(json[r'action'])!,
|
|
||||||
parameters: MirrorParameters.fromJson(json[r'parameters'])!,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<AssetEditActionMirror> listFromJson(dynamic json, {bool growable = false,}) {
|
|
||||||
final result = <AssetEditActionMirror>[];
|
|
||||||
if (json is List && json.isNotEmpty) {
|
|
||||||
for (final row in json) {
|
|
||||||
final value = AssetEditActionMirror.fromJson(row);
|
|
||||||
if (value != null) {
|
|
||||||
result.add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result.toList(growable: growable);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Map<String, AssetEditActionMirror> mapFromJson(dynamic json) {
|
|
||||||
final map = <String, AssetEditActionMirror>{};
|
|
||||||
if (json is Map && json.isNotEmpty) {
|
|
||||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
|
||||||
for (final entry in json.entries) {
|
|
||||||
final value = AssetEditActionMirror.fromJson(entry.value);
|
|
||||||
if (value != null) {
|
|
||||||
map[entry.key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maps a json object with a list of AssetEditActionMirror-objects as value to a dart map
|
|
||||||
static Map<String, List<AssetEditActionMirror>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
|
||||||
final map = <String, List<AssetEditActionMirror>>{};
|
|
||||||
if (json is Map && json.isNotEmpty) {
|
|
||||||
// ignore: parameter_assignments
|
|
||||||
json = json.cast<String, dynamic>();
|
|
||||||
for (final entry in json.entries) {
|
|
||||||
map[entry.key] = AssetEditActionMirror.listFromJson(entry.value, growable: growable,);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The list of required keys that must be present in a JSON.
|
|
||||||
static const requiredKeys = <String>{
|
|
||||||
'action',
|
|
||||||
'parameters',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
108
mobile/openapi/lib/model/asset_edit_action_rotate.dart
generated
108
mobile/openapi/lib/model/asset_edit_action_rotate.dart
generated
@@ -1,108 +0,0 @@
|
|||||||
//
|
|
||||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
|
||||||
//
|
|
||||||
// @dart=2.18
|
|
||||||
|
|
||||||
// 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 AssetEditActionRotate {
|
|
||||||
/// Returns a new [AssetEditActionRotate] instance.
|
|
||||||
AssetEditActionRotate({
|
|
||||||
required this.action,
|
|
||||||
required this.parameters,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Type of edit action to perform
|
|
||||||
AssetEditAction action;
|
|
||||||
|
|
||||||
RotateParameters parameters;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) => identical(this, other) || other is AssetEditActionRotate &&
|
|
||||||
other.action == action &&
|
|
||||||
other.parameters == parameters;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
// ignore: unnecessary_parenthesis
|
|
||||||
(action.hashCode) +
|
|
||||||
(parameters.hashCode);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'AssetEditActionRotate[action=$action, parameters=$parameters]';
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
final json = <String, dynamic>{};
|
|
||||||
json[r'action'] = this.action;
|
|
||||||
json[r'parameters'] = this.parameters;
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a new [AssetEditActionRotate] instance and imports its values from
|
|
||||||
/// [value] if it's a [Map], null otherwise.
|
|
||||||
// ignore: prefer_constructors_over_static_methods
|
|
||||||
static AssetEditActionRotate? fromJson(dynamic value) {
|
|
||||||
upgradeDto(value, "AssetEditActionRotate");
|
|
||||||
if (value is Map) {
|
|
||||||
final json = value.cast<String, dynamic>();
|
|
||||||
|
|
||||||
return AssetEditActionRotate(
|
|
||||||
action: AssetEditAction.fromJson(json[r'action'])!,
|
|
||||||
parameters: RotateParameters.fromJson(json[r'parameters'])!,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<AssetEditActionRotate> listFromJson(dynamic json, {bool growable = false,}) {
|
|
||||||
final result = <AssetEditActionRotate>[];
|
|
||||||
if (json is List && json.isNotEmpty) {
|
|
||||||
for (final row in json) {
|
|
||||||
final value = AssetEditActionRotate.fromJson(row);
|
|
||||||
if (value != null) {
|
|
||||||
result.add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result.toList(growable: growable);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Map<String, AssetEditActionRotate> mapFromJson(dynamic json) {
|
|
||||||
final map = <String, AssetEditActionRotate>{};
|
|
||||||
if (json is Map && json.isNotEmpty) {
|
|
||||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
|
||||||
for (final entry in json.entries) {
|
|
||||||
final value = AssetEditActionRotate.fromJson(entry.value);
|
|
||||||
if (value != null) {
|
|
||||||
map[entry.key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maps a json object with a list of AssetEditActionRotate-objects as value to a dart map
|
|
||||||
static Map<String, List<AssetEditActionRotate>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
|
||||||
final map = <String, List<AssetEditActionRotate>>{};
|
|
||||||
if (json is Map && json.isNotEmpty) {
|
|
||||||
// ignore: parameter_assignments
|
|
||||||
json = json.cast<String, dynamic>();
|
|
||||||
for (final entry in json.entries) {
|
|
||||||
map[entry.key] = AssetEditActionRotate.listFromJson(entry.value, growable: growable,);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The list of required keys that must be present in a JSON.
|
|
||||||
static const requiredKeys = <String>{
|
|
||||||
'action',
|
|
||||||
'parameters',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -10,17 +10,17 @@
|
|||||||
|
|
||||||
part of openapi.api;
|
part of openapi.api;
|
||||||
|
|
||||||
class AssetEditActionListDto {
|
class AssetEditsCreateDto {
|
||||||
/// Returns a new [AssetEditActionListDto] instance.
|
/// Returns a new [AssetEditsCreateDto] instance.
|
||||||
AssetEditActionListDto({
|
AssetEditsCreateDto({
|
||||||
this.edits = const [],
|
this.edits = const [],
|
||||||
});
|
});
|
||||||
|
|
||||||
/// List of edit actions to apply (crop, rotate, or mirror)
|
/// List of edit actions to apply (crop, rotate, or mirror)
|
||||||
List<AssetEditActionListDtoEditsInner> edits;
|
List<AssetEditActionItemDto> edits;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is AssetEditActionListDto &&
|
bool operator ==(Object other) => identical(this, other) || other is AssetEditsCreateDto &&
|
||||||
_deepEquality.equals(other.edits, edits);
|
_deepEquality.equals(other.edits, edits);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -29,7 +29,7 @@ class AssetEditActionListDto {
|
|||||||
(edits.hashCode);
|
(edits.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AssetEditActionListDto[edits=$edits]';
|
String toString() => 'AssetEditsCreateDto[edits=$edits]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@@ -37,26 +37,26 @@ class AssetEditActionListDto {
|
|||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new [AssetEditActionListDto] instance and imports its values from
|
/// Returns a new [AssetEditsCreateDto] instance and imports its values from
|
||||||
/// [value] if it's a [Map], null otherwise.
|
/// [value] if it's a [Map], null otherwise.
|
||||||
// ignore: prefer_constructors_over_static_methods
|
// ignore: prefer_constructors_over_static_methods
|
||||||
static AssetEditActionListDto? fromJson(dynamic value) {
|
static AssetEditsCreateDto? fromJson(dynamic value) {
|
||||||
upgradeDto(value, "AssetEditActionListDto");
|
upgradeDto(value, "AssetEditsCreateDto");
|
||||||
if (value is Map) {
|
if (value is Map) {
|
||||||
final json = value.cast<String, dynamic>();
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
return AssetEditActionListDto(
|
return AssetEditsCreateDto(
|
||||||
edits: AssetEditActionListDtoEditsInner.listFromJson(json[r'edits']),
|
edits: AssetEditActionItemDto.listFromJson(json[r'edits']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<AssetEditActionListDto> listFromJson(dynamic json, {bool growable = false,}) {
|
static List<AssetEditsCreateDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
final result = <AssetEditActionListDto>[];
|
final result = <AssetEditsCreateDto>[];
|
||||||
if (json is List && json.isNotEmpty) {
|
if (json is List && json.isNotEmpty) {
|
||||||
for (final row in json) {
|
for (final row in json) {
|
||||||
final value = AssetEditActionListDto.fromJson(row);
|
final value = AssetEditsCreateDto.fromJson(row);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result.add(value);
|
result.add(value);
|
||||||
}
|
}
|
||||||
@@ -65,12 +65,12 @@ class AssetEditActionListDto {
|
|||||||
return result.toList(growable: growable);
|
return result.toList(growable: growable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, AssetEditActionListDto> mapFromJson(dynamic json) {
|
static Map<String, AssetEditsCreateDto> mapFromJson(dynamic json) {
|
||||||
final map = <String, AssetEditActionListDto>{};
|
final map = <String, AssetEditsCreateDto>{};
|
||||||
if (json is Map && json.isNotEmpty) {
|
if (json is Map && json.isNotEmpty) {
|
||||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
for (final entry in json.entries) {
|
for (final entry in json.entries) {
|
||||||
final value = AssetEditActionListDto.fromJson(entry.value);
|
final value = AssetEditsCreateDto.fromJson(entry.value);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
map[entry.key] = value;
|
map[entry.key] = value;
|
||||||
}
|
}
|
||||||
@@ -79,14 +79,14 @@ class AssetEditActionListDto {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
// maps a json object with a list of AssetEditActionListDto-objects as value to a dart map
|
// maps a json object with a list of AssetEditsCreateDto-objects as value to a dart map
|
||||||
static Map<String, List<AssetEditActionListDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
static Map<String, List<AssetEditsCreateDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
final map = <String, List<AssetEditActionListDto>>{};
|
final map = <String, List<AssetEditsCreateDto>>{};
|
||||||
if (json is Map && json.isNotEmpty) {
|
if (json is Map && json.isNotEmpty) {
|
||||||
// ignore: parameter_assignments
|
// ignore: parameter_assignments
|
||||||
json = json.cast<String, dynamic>();
|
json = json.cast<String, dynamic>();
|
||||||
for (final entry in json.entries) {
|
for (final entry in json.entries) {
|
||||||
map[entry.key] = AssetEditActionListDto.listFromJson(entry.value, growable: growable,);
|
map[entry.key] = AssetEditsCreateDto.listFromJson(entry.value, growable: growable,);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
@@ -10,21 +10,21 @@
|
|||||||
|
|
||||||
part of openapi.api;
|
part of openapi.api;
|
||||||
|
|
||||||
class AssetEditsDto {
|
class AssetEditsResponseDto {
|
||||||
/// Returns a new [AssetEditsDto] instance.
|
/// Returns a new [AssetEditsResponseDto] instance.
|
||||||
AssetEditsDto({
|
AssetEditsResponseDto({
|
||||||
required this.assetId,
|
required this.assetId,
|
||||||
this.edits = const [],
|
this.edits = const [],
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Asset ID to apply edits to
|
/// Asset ID these edits belong to
|
||||||
String assetId;
|
String assetId;
|
||||||
|
|
||||||
/// List of edit actions to apply (crop, rotate, or mirror)
|
/// List of edit actions applied to the asset
|
||||||
List<AssetEditActionListDtoEditsInner> edits;
|
List<AssetEditActionItemResponseDto> edits;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is AssetEditsDto &&
|
bool operator ==(Object other) => identical(this, other) || other is AssetEditsResponseDto &&
|
||||||
other.assetId == assetId &&
|
other.assetId == assetId &&
|
||||||
_deepEquality.equals(other.edits, edits);
|
_deepEquality.equals(other.edits, edits);
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ class AssetEditsDto {
|
|||||||
(edits.hashCode);
|
(edits.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AssetEditsDto[assetId=$assetId, edits=$edits]';
|
String toString() => 'AssetEditsResponseDto[assetId=$assetId, edits=$edits]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@@ -44,27 +44,27 @@ class AssetEditsDto {
|
|||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new [AssetEditsDto] instance and imports its values from
|
/// Returns a new [AssetEditsResponseDto] instance and imports its values from
|
||||||
/// [value] if it's a [Map], null otherwise.
|
/// [value] if it's a [Map], null otherwise.
|
||||||
// ignore: prefer_constructors_over_static_methods
|
// ignore: prefer_constructors_over_static_methods
|
||||||
static AssetEditsDto? fromJson(dynamic value) {
|
static AssetEditsResponseDto? fromJson(dynamic value) {
|
||||||
upgradeDto(value, "AssetEditsDto");
|
upgradeDto(value, "AssetEditsResponseDto");
|
||||||
if (value is Map) {
|
if (value is Map) {
|
||||||
final json = value.cast<String, dynamic>();
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
return AssetEditsDto(
|
return AssetEditsResponseDto(
|
||||||
assetId: mapValueOfType<String>(json, r'assetId')!,
|
assetId: mapValueOfType<String>(json, r'assetId')!,
|
||||||
edits: AssetEditActionListDtoEditsInner.listFromJson(json[r'edits']),
|
edits: AssetEditActionItemResponseDto.listFromJson(json[r'edits']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<AssetEditsDto> listFromJson(dynamic json, {bool growable = false,}) {
|
static List<AssetEditsResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
final result = <AssetEditsDto>[];
|
final result = <AssetEditsResponseDto>[];
|
||||||
if (json is List && json.isNotEmpty) {
|
if (json is List && json.isNotEmpty) {
|
||||||
for (final row in json) {
|
for (final row in json) {
|
||||||
final value = AssetEditsDto.fromJson(row);
|
final value = AssetEditsResponseDto.fromJson(row);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result.add(value);
|
result.add(value);
|
||||||
}
|
}
|
||||||
@@ -73,12 +73,12 @@ class AssetEditsDto {
|
|||||||
return result.toList(growable: growable);
|
return result.toList(growable: growable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, AssetEditsDto> mapFromJson(dynamic json) {
|
static Map<String, AssetEditsResponseDto> mapFromJson(dynamic json) {
|
||||||
final map = <String, AssetEditsDto>{};
|
final map = <String, AssetEditsResponseDto>{};
|
||||||
if (json is Map && json.isNotEmpty) {
|
if (json is Map && json.isNotEmpty) {
|
||||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
for (final entry in json.entries) {
|
for (final entry in json.entries) {
|
||||||
final value = AssetEditsDto.fromJson(entry.value);
|
final value = AssetEditsResponseDto.fromJson(entry.value);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
map[entry.key] = value;
|
map[entry.key] = value;
|
||||||
}
|
}
|
||||||
@@ -87,14 +87,14 @@ class AssetEditsDto {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
// maps a json object with a list of AssetEditsDto-objects as value to a dart map
|
// maps a json object with a list of AssetEditsResponseDto-objects as value to a dart map
|
||||||
static Map<String, List<AssetEditsDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
static Map<String, List<AssetEditsResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
final map = <String, List<AssetEditsDto>>{};
|
final map = <String, List<AssetEditsResponseDto>>{};
|
||||||
if (json is Map && json.isNotEmpty) {
|
if (json is Map && json.isNotEmpty) {
|
||||||
// ignore: parameter_assignments
|
// ignore: parameter_assignments
|
||||||
json = json.cast<String, dynamic>();
|
json = json.cast<String, dynamic>();
|
||||||
for (final entry in json.entries) {
|
for (final entry in json.entries) {
|
||||||
map[entry.key] = AssetEditsDto.listFromJson(entry.value, growable: growable,);
|
map[entry.key] = AssetEditsResponseDto.listFromJson(entry.value, growable: growable,);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
@@ -3703,7 +3703,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/AssetEditsDto"
|
"$ref": "#/components/schemas/AssetEditsResponseDto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3756,7 +3756,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/AssetEditActionListDto"
|
"$ref": "#/components/schemas/AssetEditsCreateDto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3767,7 +3767,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/AssetEditsDto"
|
"$ref": "#/components/schemas/AssetEditsResponseDto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16082,7 +16082,7 @@
|
|||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"AssetEditActionCrop": {
|
"AssetEditActionItemDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"action": {
|
"action": {
|
||||||
"allOf": [
|
"allOf": [
|
||||||
@@ -16093,7 +16093,18 @@
|
|||||||
"description": "Type of edit action to perform"
|
"description": "Type of edit action to perform"
|
||||||
},
|
},
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"$ref": "#/components/schemas/CropParameters"
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/CropParameters"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/RotateParameters"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/MirrorParameters"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "List of edit actions to apply (crop, rotate, or mirror)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@@ -16102,30 +16113,48 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"AssetEditActionListDto": {
|
"AssetEditActionItemResponseDto": {
|
||||||
|
"properties": {
|
||||||
|
"action": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/AssetEditAction"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Type of edit action to perform"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"format": "uuid",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/CropParameters"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/RotateParameters"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/MirrorParameters"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "List of edit actions to apply (crop, rotate, or mirror)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"action",
|
||||||
|
"id",
|
||||||
|
"parameters"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"AssetEditsCreateDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"edits": {
|
"edits": {
|
||||||
"description": "List of edit actions to apply (crop, rotate, or mirror)",
|
"description": "List of edit actions to apply (crop, rotate, or mirror)",
|
||||||
"items": {
|
"items": {
|
||||||
"anyOf": [
|
"$ref": "#/components/schemas/AssetEditActionItemDto"
|
||||||
{
|
|
||||||
"$ref": "#/components/schemas/AssetEditActionCrop"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$ref": "#/components/schemas/AssetEditActionRotate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$ref": "#/components/schemas/AssetEditActionMirror"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"discriminator": {
|
|
||||||
"mapping": {
|
|
||||||
"crop": "#/components/schemas/AssetEditActionCrop",
|
|
||||||
"mirror": "#/components/schemas/AssetEditActionMirror",
|
|
||||||
"rotate": "#/components/schemas/AssetEditActionRotate"
|
|
||||||
},
|
|
||||||
"propertyName": "action"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"minItems": 1,
|
"minItems": 1,
|
||||||
"type": "array"
|
"type": "array"
|
||||||
@@ -16136,77 +16165,18 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"AssetEditActionMirror": {
|
"AssetEditsResponseDto": {
|
||||||
"properties": {
|
|
||||||
"action": {
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/components/schemas/AssetEditAction"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Type of edit action to perform"
|
|
||||||
},
|
|
||||||
"parameters": {
|
|
||||||
"$ref": "#/components/schemas/MirrorParameters"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"action",
|
|
||||||
"parameters"
|
|
||||||
],
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
"AssetEditActionRotate": {
|
|
||||||
"properties": {
|
|
||||||
"action": {
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/components/schemas/AssetEditAction"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Type of edit action to perform"
|
|
||||||
},
|
|
||||||
"parameters": {
|
|
||||||
"$ref": "#/components/schemas/RotateParameters"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"action",
|
|
||||||
"parameters"
|
|
||||||
],
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
"AssetEditsDto": {
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"assetId": {
|
"assetId": {
|
||||||
"description": "Asset ID to apply edits to",
|
"description": "Asset ID these edits belong to",
|
||||||
"format": "uuid",
|
"format": "uuid",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"edits": {
|
"edits": {
|
||||||
"description": "List of edit actions to apply (crop, rotate, or mirror)",
|
"description": "List of edit actions applied to the asset",
|
||||||
"items": {
|
"items": {
|
||||||
"anyOf": [
|
"$ref": "#/components/schemas/AssetEditActionItemResponseDto"
|
||||||
{
|
|
||||||
"$ref": "#/components/schemas/AssetEditActionCrop"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$ref": "#/components/schemas/AssetEditActionRotate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$ref": "#/components/schemas/AssetEditActionMirror"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"discriminator": {
|
|
||||||
"mapping": {
|
|
||||||
"crop": "#/components/schemas/AssetEditActionCrop",
|
|
||||||
"mirror": "#/components/schemas/AssetEditActionMirror",
|
|
||||||
"rotate": "#/components/schemas/AssetEditActionRotate"
|
|
||||||
},
|
|
||||||
"propertyName": "action"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"minItems": 1,
|
|
||||||
"type": "array"
|
"type": "array"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -959,38 +959,36 @@ export type CropParameters = {
|
|||||||
/** Top-Left Y coordinate of crop */
|
/** Top-Left Y coordinate of crop */
|
||||||
y: number;
|
y: number;
|
||||||
};
|
};
|
||||||
export type AssetEditActionCrop = {
|
|
||||||
/** Type of edit action to perform */
|
|
||||||
action: AssetEditAction;
|
|
||||||
parameters: CropParameters;
|
|
||||||
};
|
|
||||||
export type RotateParameters = {
|
export type RotateParameters = {
|
||||||
/** Rotation angle in degrees */
|
/** Rotation angle in degrees */
|
||||||
angle: number;
|
angle: number;
|
||||||
};
|
};
|
||||||
export type AssetEditActionRotate = {
|
|
||||||
/** Type of edit action to perform */
|
|
||||||
action: AssetEditAction;
|
|
||||||
parameters: RotateParameters;
|
|
||||||
};
|
|
||||||
export type MirrorParameters = {
|
export type MirrorParameters = {
|
||||||
/** Axis to mirror along */
|
/** Axis to mirror along */
|
||||||
axis: MirrorAxis;
|
axis: MirrorAxis;
|
||||||
};
|
};
|
||||||
export type AssetEditActionMirror = {
|
export type AssetEditActionItemResponseDto = {
|
||||||
/** Type of edit action to perform */
|
/** Type of edit action to perform */
|
||||||
action: AssetEditAction;
|
action: AssetEditAction;
|
||||||
parameters: MirrorParameters;
|
id: string;
|
||||||
|
/** List of edit actions to apply (crop, rotate, or mirror) */
|
||||||
|
parameters: CropParameters | RotateParameters | MirrorParameters;
|
||||||
};
|
};
|
||||||
export type AssetEditsDto = {
|
export type AssetEditsResponseDto = {
|
||||||
/** Asset ID to apply edits to */
|
/** Asset ID these edits belong to */
|
||||||
assetId: string;
|
assetId: string;
|
||||||
/** List of edit actions to apply (crop, rotate, or mirror) */
|
/** List of edit actions applied to the asset */
|
||||||
edits: (AssetEditActionCrop | AssetEditActionRotate | AssetEditActionMirror)[];
|
edits: AssetEditActionItemResponseDto[];
|
||||||
};
|
};
|
||||||
export type AssetEditActionListDto = {
|
export type AssetEditActionItemDto = {
|
||||||
|
/** Type of edit action to perform */
|
||||||
|
action: AssetEditAction;
|
||||||
/** List of edit actions to apply (crop, rotate, or mirror) */
|
/** List of edit actions to apply (crop, rotate, or mirror) */
|
||||||
edits: (AssetEditActionCrop | AssetEditActionRotate | AssetEditActionMirror)[];
|
parameters: CropParameters | RotateParameters | MirrorParameters;
|
||||||
|
};
|
||||||
|
export type AssetEditsCreateDto = {
|
||||||
|
/** List of edit actions to apply (crop, rotate, or mirror) */
|
||||||
|
edits: AssetEditActionItemDto[];
|
||||||
};
|
};
|
||||||
export type AssetMetadataResponseDto = {
|
export type AssetMetadataResponseDto = {
|
||||||
/** Metadata key */
|
/** Metadata key */
|
||||||
@@ -4149,7 +4147,7 @@ export function getAssetEdits({ id }: {
|
|||||||
}, opts?: Oazapfts.RequestOpts) {
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
status: 200;
|
status: 200;
|
||||||
data: AssetEditsDto;
|
data: AssetEditsResponseDto;
|
||||||
}>(`/assets/${encodeURIComponent(id)}/edits`, {
|
}>(`/assets/${encodeURIComponent(id)}/edits`, {
|
||||||
...opts
|
...opts
|
||||||
}));
|
}));
|
||||||
@@ -4157,17 +4155,17 @@ export function getAssetEdits({ id }: {
|
|||||||
/**
|
/**
|
||||||
* Apply edits to an existing asset
|
* Apply edits to an existing asset
|
||||||
*/
|
*/
|
||||||
export function editAsset({ id, assetEditActionListDto }: {
|
export function editAsset({ id, assetEditsCreateDto }: {
|
||||||
id: string;
|
id: string;
|
||||||
assetEditActionListDto: AssetEditActionListDto;
|
assetEditsCreateDto: AssetEditsCreateDto;
|
||||||
}, opts?: Oazapfts.RequestOpts) {
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
status: 200;
|
status: 200;
|
||||||
data: AssetEditsDto;
|
data: AssetEditsResponseDto;
|
||||||
}>(`/assets/${encodeURIComponent(id)}/edits`, oazapfts.json({
|
}>(`/assets/${encodeURIComponent(id)}/edits`, oazapfts.json({
|
||||||
...opts,
|
...opts,
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: assetEditActionListDto
|
body: assetEditsCreateDto
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -369,6 +369,31 @@ describe(AssetController.name, () => {
|
|||||||
expect(body).toEqual(factory.responses.badRequest(expect.arrayContaining(['id must be a UUID'])));
|
expect(body).toEqual(factory.responses.badRequest(expect.arrayContaining(['id must be a UUID'])));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should check the action and parameters discriminator', async () => {
|
||||||
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
|
.put(`/assets/${factory.uuid()}/edits`)
|
||||||
|
.send({
|
||||||
|
edits: [
|
||||||
|
{
|
||||||
|
action: 'rotate',
|
||||||
|
parameters: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(status).toBe(400);
|
||||||
|
expect(body).toEqual(
|
||||||
|
factory.responses.badRequest(
|
||||||
|
expect.arrayContaining([expect.stringContaining('parameters.angle must be one of the following values')]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should require at least one edit', async () => {
|
it('should require at least one edit', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.put(`/assets/${factory.uuid()}/edits`)
|
.put(`/assets/${factory.uuid()}/edits`)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
UpdateAssetDto,
|
UpdateAssetDto,
|
||||||
} from 'src/dtos/asset.dto';
|
} from 'src/dtos/asset.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { AssetEditActionListDto, AssetEditsDto } from 'src/dtos/editing.dto';
|
import { AssetEditsCreateDto, AssetEditsResponseDto } from 'src/dtos/editing.dto';
|
||||||
import { AssetOcrResponseDto } from 'src/dtos/ocr.dto';
|
import { AssetOcrResponseDto } from 'src/dtos/ocr.dto';
|
||||||
import { ApiTag, Permission, RouteKey } from 'src/enum';
|
import { ApiTag, Permission, RouteKey } from 'src/enum';
|
||||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||||
@@ -235,7 +235,7 @@ export class AssetController {
|
|||||||
description: 'Retrieve a series of edit actions (crop, rotate, mirror) associated with the specified asset.',
|
description: 'Retrieve a series of edit actions (crop, rotate, mirror) associated with the specified asset.',
|
||||||
history: new HistoryBuilder().added('v2.5.0').beta('v2.5.0'),
|
history: new HistoryBuilder().added('v2.5.0').beta('v2.5.0'),
|
||||||
})
|
})
|
||||||
getAssetEdits(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetEditsDto> {
|
getAssetEdits(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetEditsResponseDto> {
|
||||||
return this.service.getAssetEdits(auth, id);
|
return this.service.getAssetEdits(auth, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,8 +249,8 @@ export class AssetController {
|
|||||||
editAsset(
|
editAsset(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
@Param() { id }: UUIDParamDto,
|
@Param() { id }: UUIDParamDto,
|
||||||
@Body() dto: AssetEditActionListDto,
|
@Body() dto: AssetEditsCreateDto,
|
||||||
): Promise<AssetEditsDto> {
|
): Promise<AssetEditsResponseDto> {
|
||||||
return this.service.editAsset(auth, id, dto);
|
return this.service.editAsset(auth, id, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { ApiExtraModels, ApiProperty, getSchemaPath } from '@nestjs/swagger';
|
import { ApiProperty, getSchemaPath } from '@nestjs/swagger';
|
||||||
import { ClassConstructor, plainToInstance, Transform, Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
import { ArrayMinSize, IsEnum, IsInt, Min, ValidateNested } from 'class-validator';
|
import { ArrayMinSize, IsEnum, IsInt, Min, ValidateNested } from 'class-validator';
|
||||||
import { IsAxisAlignedRotation, IsUniqueEditActions, ValidateUUID } from 'src/validation';
|
import { ExtraModel } from 'src/dtos/sync.dto';
|
||||||
|
import { IsAxisAlignedRotation, IsUniqueEditActions, ValidateEnum, ValidateUUID } from 'src/validation';
|
||||||
|
|
||||||
export enum AssetEditAction {
|
export enum AssetEditAction {
|
||||||
Crop = 'crop',
|
Crop = 'crop',
|
||||||
@@ -14,6 +15,7 @@ export enum MirrorAxis {
|
|||||||
Vertical = 'vertical',
|
Vertical = 'vertical',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExtraModel()
|
||||||
export class CropParameters {
|
export class CropParameters {
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@@ -36,48 +38,21 @@ export class CropParameters {
|
|||||||
height!: number;
|
height!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExtraModel()
|
||||||
export class RotateParameters {
|
export class RotateParameters {
|
||||||
@IsAxisAlignedRotation()
|
@IsAxisAlignedRotation()
|
||||||
@ApiProperty({ description: 'Rotation angle in degrees' })
|
@ApiProperty({ description: 'Rotation angle in degrees' })
|
||||||
angle!: number;
|
angle!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExtraModel()
|
||||||
export class MirrorParameters {
|
export class MirrorParameters {
|
||||||
@IsEnum(MirrorAxis)
|
@IsEnum(MirrorAxis)
|
||||||
@ApiProperty({ enum: MirrorAxis, enumName: 'MirrorAxis', description: 'Axis to mirror along' })
|
@ApiProperty({ enum: MirrorAxis, enumName: 'MirrorAxis', description: 'Axis to mirror along' })
|
||||||
axis!: MirrorAxis;
|
axis!: MirrorAxis;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AssetEditActionBase {
|
export type AssetEditParameters = CropParameters | RotateParameters | MirrorParameters;
|
||||||
@IsEnum(AssetEditAction)
|
|
||||||
@ApiProperty({ enum: AssetEditAction, enumName: 'AssetEditAction', description: 'Type of edit action to perform' })
|
|
||||||
action!: AssetEditAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AssetEditActionCrop extends AssetEditActionBase {
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => CropParameters)
|
|
||||||
// Description lives on schema to avoid duplication
|
|
||||||
@ApiProperty({ description: undefined })
|
|
||||||
parameters!: CropParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AssetEditActionRotate extends AssetEditActionBase {
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => RotateParameters)
|
|
||||||
// Description lives on schema to avoid duplication
|
|
||||||
@ApiProperty({ description: undefined })
|
|
||||||
parameters!: RotateParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AssetEditActionMirror extends AssetEditActionBase {
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => MirrorParameters)
|
|
||||||
// Description lives on schema to avoid duplication
|
|
||||||
@ApiProperty({ description: undefined })
|
|
||||||
parameters!: MirrorParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AssetEditActionItem =
|
export type AssetEditActionItem =
|
||||||
| {
|
| {
|
||||||
action: AssetEditAction.Crop;
|
action: AssetEditAction.Crop;
|
||||||
@@ -92,47 +67,48 @@ export type AssetEditActionItem =
|
|||||||
parameters: MirrorParameters;
|
parameters: MirrorParameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AssetEditActionParameter = {
|
export class AssetEditActionItemDto {
|
||||||
[AssetEditAction.Crop]: CropParameters;
|
@ValidateEnum({ name: 'AssetEditAction', enum: AssetEditAction, description: 'Type of edit action to perform' })
|
||||||
[AssetEditAction.Rotate]: RotateParameters;
|
action!: AssetEditAction;
|
||||||
[AssetEditAction.Mirror]: MirrorParameters;
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'List of edit actions to apply (crop, rotate, or mirror)',
|
||||||
|
anyOf: [CropParameters, RotateParameters, MirrorParameters].map((type) => ({
|
||||||
|
$ref: getSchemaPath(type),
|
||||||
|
})),
|
||||||
|
})
|
||||||
|
@ValidateNested()
|
||||||
|
@Type((options) => actionParameterMap[options?.object.action as keyof AssetEditActionParameter])
|
||||||
|
parameters!: AssetEditActionItem['parameters'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AssetEditActionItemResponseDto extends AssetEditActionItemDto {
|
||||||
|
@ValidateUUID()
|
||||||
|
id!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AssetEditActionParameter = typeof actionParameterMap;
|
||||||
|
const actionParameterMap = {
|
||||||
|
[AssetEditAction.Crop]: CropParameters,
|
||||||
|
[AssetEditAction.Rotate]: RotateParameters,
|
||||||
|
[AssetEditAction.Mirror]: MirrorParameters,
|
||||||
};
|
};
|
||||||
|
|
||||||
type AssetEditActions = AssetEditActionCrop | AssetEditActionRotate | AssetEditActionMirror;
|
export class AssetEditsCreateDto {
|
||||||
const actionToClass: Record<AssetEditAction, ClassConstructor<AssetEditActions>> = {
|
|
||||||
[AssetEditAction.Crop]: AssetEditActionCrop,
|
|
||||||
[AssetEditAction.Rotate]: AssetEditActionRotate,
|
|
||||||
[AssetEditAction.Mirror]: AssetEditActionMirror,
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
const getActionClass = (item: { action: AssetEditAction }): ClassConstructor<AssetEditActions> =>
|
|
||||||
actionToClass[item.action];
|
|
||||||
|
|
||||||
@ApiExtraModels(AssetEditActionRotate, AssetEditActionMirror, AssetEditActionCrop)
|
|
||||||
export class AssetEditActionListDto {
|
|
||||||
/** list of edits */
|
|
||||||
@ArrayMinSize(1)
|
@ArrayMinSize(1)
|
||||||
@IsUniqueEditActions()
|
@IsUniqueEditActions()
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Transform(({ value: edits }) =>
|
@Type(() => AssetEditActionItemDto)
|
||||||
Array.isArray(edits) ? edits.map((item) => plainToInstance(getActionClass(item), item)) : edits,
|
@ApiProperty({ description: 'List of edit actions to apply (crop, rotate, or mirror)' })
|
||||||
)
|
edits!: AssetEditActionItemDto[];
|
||||||
@ApiProperty({
|
|
||||||
items: {
|
|
||||||
anyOf: Object.values(actionToClass).map((type) => ({ $ref: getSchemaPath(type) })),
|
|
||||||
discriminator: {
|
|
||||||
propertyName: 'action',
|
|
||||||
mapping: Object.fromEntries(
|
|
||||||
Object.entries(actionToClass).map(([action, type]) => [action, getSchemaPath(type)]),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: 'List of edit actions to apply (crop, rotate, or mirror)',
|
|
||||||
})
|
|
||||||
edits!: AssetEditActionItem[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AssetEditsDto extends AssetEditActionListDto {
|
export class AssetEditsResponseDto {
|
||||||
@ValidateUUID({ description: 'Asset ID to apply edits to' })
|
@ValidateUUID({ description: 'Asset ID these edits belong to' })
|
||||||
assetId!: string;
|
assetId!: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'List of edit actions applied to the asset',
|
||||||
|
})
|
||||||
|
edits!: AssetEditActionItemResponseDto[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ rollback
|
|||||||
|
|
||||||
-- AssetEditRepository.getAll
|
-- AssetEditRepository.getAll
|
||||||
select
|
select
|
||||||
|
"id",
|
||||||
"action",
|
"action",
|
||||||
"parameters"
|
"parameters"
|
||||||
from
|
from
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AssetEditActionItem } from 'src/dtos/editing.dto';
|
import { AssetEditActionItem, AssetEditActionItemResponseDto } from 'src/dtos/editing.dto';
|
||||||
import { DB } from 'src/schema';
|
import { DB } from 'src/schema';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -12,7 +12,7 @@ export class AssetEditRepository {
|
|||||||
@GenerateSql({
|
@GenerateSql({
|
||||||
params: [DummyValue.UUID],
|
params: [DummyValue.UUID],
|
||||||
})
|
})
|
||||||
replaceAll(assetId: string, edits: AssetEditActionItem[]): Promise<AssetEditActionItem[]> {
|
replaceAll(assetId: string, edits: AssetEditActionItem[]): Promise<AssetEditActionItemResponseDto[]> {
|
||||||
return this.db.transaction().execute(async (trx) => {
|
return this.db.transaction().execute(async (trx) => {
|
||||||
await trx.deleteFrom('asset_edit').where('assetId', '=', assetId).execute();
|
await trx.deleteFrom('asset_edit').where('assetId', '=', assetId).execute();
|
||||||
|
|
||||||
@@ -20,8 +20,8 @@ export class AssetEditRepository {
|
|||||||
return trx
|
return trx
|
||||||
.insertInto('asset_edit')
|
.insertInto('asset_edit')
|
||||||
.values(edits.map((edit, i) => ({ assetId, sequence: i, ...edit })))
|
.values(edits.map((edit, i) => ({ assetId, sequence: i, ...edit })))
|
||||||
.returning(['action', 'parameters'])
|
.returning(['id', 'action', 'parameters'])
|
||||||
.execute() as Promise<AssetEditActionItem[]>;
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
@@ -31,12 +31,12 @@ export class AssetEditRepository {
|
|||||||
@GenerateSql({
|
@GenerateSql({
|
||||||
params: [DummyValue.UUID],
|
params: [DummyValue.UUID],
|
||||||
})
|
})
|
||||||
getAll(assetId: string): Promise<AssetEditActionItem[]> {
|
getAll(assetId: string): Promise<AssetEditActionItemResponseDto[]> {
|
||||||
return this.db
|
return this.db
|
||||||
.selectFrom('asset_edit')
|
.selectFrom('asset_edit')
|
||||||
.select(['action', 'parameters'])
|
.select(['id', 'action', 'parameters'])
|
||||||
.where('assetId', '=', assetId)
|
.where('assetId', '=', assetId)
|
||||||
.orderBy('sequence', 'asc')
|
.orderBy('sequence', 'asc')
|
||||||
.execute() as Promise<AssetEditActionItem[]>;
|
.execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
Unique,
|
Unique,
|
||||||
} from '@immich/sql-tools';
|
} from '@immich/sql-tools';
|
||||||
import { AssetEditAction, AssetEditActionParameter } from 'src/dtos/editing.dto';
|
import { AssetEditAction, AssetEditParameters } from 'src/dtos/editing.dto';
|
||||||
import { asset_edit_delete, asset_edit_insert } from 'src/schema/functions';
|
import { asset_edit_delete, asset_edit_insert } from 'src/schema/functions';
|
||||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ import { AssetTable } from 'src/schema/tables/asset.table';
|
|||||||
when: 'pg_trigger_depth() = 0',
|
when: 'pg_trigger_depth() = 0',
|
||||||
})
|
})
|
||||||
@Unique({ columns: ['assetId', 'sequence'] })
|
@Unique({ columns: ['assetId', 'sequence'] })
|
||||||
export class AssetEditTable<T extends AssetEditAction = AssetEditAction> {
|
export class AssetEditTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: Generated<string>;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@@ -29,10 +29,10 @@ export class AssetEditTable<T extends AssetEditAction = AssetEditAction> {
|
|||||||
assetId!: string;
|
assetId!: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
action!: T;
|
action!: AssetEditAction;
|
||||||
|
|
||||||
@Column({ type: 'jsonb' })
|
@Column({ type: 'jsonb' })
|
||||||
parameters!: AssetEditActionParameter[T];
|
parameters!: AssetEditParameters;
|
||||||
|
|
||||||
@Column({ type: 'integer' })
|
@Column({ type: 'integer' })
|
||||||
sequence!: number;
|
sequence!: number;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
mapStats,
|
mapStats,
|
||||||
} from 'src/dtos/asset.dto';
|
} from 'src/dtos/asset.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { AssetEditAction, AssetEditActionCrop, AssetEditActionListDto, AssetEditsDto } from 'src/dtos/editing.dto';
|
import { AssetEditAction, AssetEditActionItem, AssetEditsCreateDto, AssetEditsResponseDto } from 'src/dtos/editing.dto';
|
||||||
import { AssetOcrResponseDto } from 'src/dtos/ocr.dto';
|
import { AssetOcrResponseDto } from 'src/dtos/ocr.dto';
|
||||||
import {
|
import {
|
||||||
AssetFileType,
|
AssetFileType,
|
||||||
@@ -543,7 +543,7 @@ export class AssetService extends BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAssetEdits(auth: AuthDto, id: string): Promise<AssetEditsDto> {
|
async getAssetEdits(auth: AuthDto, id: string): Promise<AssetEditsResponseDto> {
|
||||||
await this.requireAccess({ auth, permission: Permission.AssetRead, ids: [id] });
|
await this.requireAccess({ auth, permission: Permission.AssetRead, ids: [id] });
|
||||||
const edits = await this.assetEditRepository.getAll(id);
|
const edits = await this.assetEditRepository.getAll(id);
|
||||||
return {
|
return {
|
||||||
@@ -552,7 +552,7 @@ export class AssetService extends BaseService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async editAsset(auth: AuthDto, id: string, dto: AssetEditActionListDto): Promise<AssetEditsDto> {
|
async editAsset(auth: AuthDto, id: string, dto: AssetEditsCreateDto): Promise<AssetEditsResponseDto> {
|
||||||
await this.requireAccess({ auth, permission: Permission.AssetEditCreate, ids: [id] });
|
await this.requireAccess({ auth, permission: Permission.AssetEditCreate, ids: [id] });
|
||||||
|
|
||||||
const asset = await this.assetRepository.getForEdit(id);
|
const asset = await this.assetRepository.getForEdit(id);
|
||||||
@@ -587,12 +587,13 @@ export class AssetService extends BaseService {
|
|||||||
throw new BadRequestException('Asset dimensions are not available for editing');
|
throw new BadRequestException('Asset dimensions are not available for editing');
|
||||||
}
|
}
|
||||||
|
|
||||||
const cropIndex = dto.edits.findIndex((e) => e.action === AssetEditAction.Crop);
|
const edits = dto.edits as AssetEditActionItem[];
|
||||||
if (cropIndex > 0) {
|
const crop = edits.find((e) => e.action === AssetEditAction.Crop);
|
||||||
throw new BadRequestException('Crop action must be the first edit action');
|
|
||||||
}
|
|
||||||
const crop = cropIndex === -1 ? null : (dto.edits[cropIndex] as AssetEditActionCrop);
|
|
||||||
if (crop) {
|
if (crop) {
|
||||||
|
if (edits[0].action !== AssetEditAction.Crop) {
|
||||||
|
throw new BadRequestException('Crop action must be the first edit action');
|
||||||
|
}
|
||||||
|
|
||||||
// check that crop parameters will not go out of bounds
|
// check that crop parameters will not go out of bounds
|
||||||
const { width: assetWidth, height: assetHeight } = getDimensions(asset);
|
const { width: assetWidth, height: assetHeight } = getDimensions(asset);
|
||||||
|
|
||||||
@@ -606,7 +607,7 @@ export class AssetService extends BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const newEdits = await this.assetEditRepository.replaceAll(id, dto.edits);
|
const newEdits = await this.assetEditRepository.replaceAll(id, edits);
|
||||||
await this.jobRepository.queue({ name: JobName.AssetEditThumbnailGeneration, data: { id } });
|
await this.jobRepository.queue({ name: JobName.AssetEditThumbnailGeneration, data: { id } });
|
||||||
|
|
||||||
// Return the asset and its applied edits
|
// Return the asset and its applied edits
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Selectable } from 'kysely';
|
import { Selectable } from 'kysely';
|
||||||
import { AssetEditAction } from 'src/dtos/editing.dto';
|
import { AssetEditAction, AssetEditActionItem } from 'src/dtos/editing.dto';
|
||||||
import { AssetEditTable } from 'src/schema/tables/asset-edit.table';
|
import { AssetEditTable } from 'src/schema/tables/asset-edit.table';
|
||||||
import { AssetFactory } from 'test/factories/asset.factory';
|
import { AssetFactory } from 'test/factories/asset.factory';
|
||||||
import { build } from 'test/factories/builder.factory';
|
import { build } from 'test/factories/builder.factory';
|
||||||
@@ -33,6 +33,6 @@ export class AssetEditFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
return { ...this.value } as Selectable<AssetEditTable<AssetEditAction.Crop>>;
|
return { ...this.value } as Omit<Selectable<AssetEditTable>, 'action' | 'parameters'> & AssetEditActionItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Stats } from 'node:fs';
|
|||||||
import { Writable } from 'node:stream';
|
import { Writable } from 'node:stream';
|
||||||
import { AssetFace } from 'src/database';
|
import { AssetFace } from 'src/database';
|
||||||
import { AuthDto, LoginResponseDto } from 'src/dtos/auth.dto';
|
import { AuthDto, LoginResponseDto } from 'src/dtos/auth.dto';
|
||||||
import { AssetEditActionListDto } from 'src/dtos/editing.dto';
|
import { AssetEditActionItem, AssetEditsCreateDto } from 'src/dtos/editing.dto';
|
||||||
import {
|
import {
|
||||||
AlbumUserRole,
|
AlbumUserRole,
|
||||||
AssetType,
|
AssetType,
|
||||||
@@ -282,8 +282,8 @@ export class MediumTestContext<S extends BaseService = BaseService> {
|
|||||||
return { tagsAssets, result };
|
return { tagsAssets, result };
|
||||||
}
|
}
|
||||||
|
|
||||||
async newEdits(assetId: string, dto: AssetEditActionListDto) {
|
async newEdits(assetId: string, dto: AssetEditsCreateDto) {
|
||||||
const edits = await this.get(AssetEditRepository).replaceAll(assetId, dto.edits);
|
const edits = await this.get(AssetEditRepository).replaceAll(assetId, dto.edits as AssetEditActionItem[]);
|
||||||
return { edits };
|
return { edits };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -887,15 +887,16 @@ describe(AssetService.name, () => {
|
|||||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 42, exifImageWidth: 69, orientation: '1' });
|
await ctx.newExif({ assetId: asset.id, exifImageHeight: 42, exifImageWidth: 69, orientation: '1' });
|
||||||
|
|
||||||
const editAction = { action: AssetEditAction.Rotate, parameters: { angle: 90 } } as const;
|
const editAction = { action: AssetEditAction.Rotate, parameters: { angle: 90 } } as const;
|
||||||
|
const editResponse = { ...editAction, id: expect.any(String) };
|
||||||
await expect(sut.editAsset(auth, asset.id, { edits: [editAction] })).resolves.toEqual({
|
await expect(sut.editAsset(auth, asset.id, { edits: [editAction] })).resolves.toEqual({
|
||||||
assetId: asset.id,
|
assetId: asset.id,
|
||||||
edits: [editAction],
|
edits: [editResponse],
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(ctx.get(AssetRepository).getById(asset.id)).resolves.toEqual(
|
await expect(ctx.get(AssetRepository).getById(asset.id)).resolves.toEqual(
|
||||||
expect.objectContaining({ isEdited: true }),
|
expect.objectContaining({ isEdited: true }),
|
||||||
);
|
);
|
||||||
await expect(ctx.get(AssetEditRepository).getAll(asset.id)).resolves.toEqual([editAction]);
|
await expect(ctx.get(AssetEditRepository).getAll(asset.id)).resolves.toEqual([editResponse]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import { transformManager } from '$lib/managers/edit/transform-manager.svelte';
|
|||||||
import { eventManager } from '$lib/managers/event-manager.svelte';
|
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||||
import { waitForWebsocketEvent } from '$lib/stores/websocket';
|
import { waitForWebsocketEvent } from '$lib/stores/websocket';
|
||||||
import { getFormatter } from '$lib/utils/i18n';
|
import { getFormatter } from '$lib/utils/i18n';
|
||||||
import { editAsset, removeAssetEdits, type AssetEditsDto, type AssetResponseDto } from '@immich/sdk';
|
import { editAsset, removeAssetEdits, type AssetEditsCreateDto, type AssetResponseDto } from '@immich/sdk';
|
||||||
import { ConfirmModal, modalManager, toastManager } from '@immich/ui';
|
import { ConfirmModal, modalManager, toastManager } from '@immich/ui';
|
||||||
import { mdiCropRotate } from '@mdi/js';
|
import { mdiCropRotate } from '@mdi/js';
|
||||||
import type { Component } from 'svelte';
|
import type { Component } from 'svelte';
|
||||||
|
|
||||||
export type EditAction = AssetEditsDto['edits'][number];
|
export type EditAction = AssetEditsCreateDto['edits'][number];
|
||||||
export type EditActions = EditAction[];
|
export type EditActions = EditAction[];
|
||||||
|
|
||||||
export interface EditToolManager {
|
export interface EditToolManager {
|
||||||
@@ -84,7 +84,7 @@ export class EditManager {
|
|||||||
this.selectedTool = this.tools[0];
|
this.selectedTool = this.tools[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
async activateTool(toolType: EditToolType, asset: AssetResponseDto, edits: AssetEditsDto) {
|
async activateTool(toolType: EditToolType, asset: AssetResponseDto, edits: AssetEditsCreateDto) {
|
||||||
this.hasAppliedEdits = false;
|
this.hasAppliedEdits = false;
|
||||||
if (this.selectedTool?.type === toolType) {
|
if (this.selectedTool?.type === toolType) {
|
||||||
return;
|
return;
|
||||||
@@ -133,7 +133,7 @@ export class EditManager {
|
|||||||
? removeAssetEdits({ id: assetId })
|
? removeAssetEdits({ id: assetId })
|
||||||
: editAsset({
|
: editAsset({
|
||||||
id: assetId,
|
id: assetId,
|
||||||
assetEditActionListDto: {
|
assetEditsCreateDto: {
|
||||||
edits,
|
edits,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user