diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index 4a7d516a9d..1f2e62356c 100644 --- a/mobile/openapi/README.md +++ b/mobile/openapi/README.md @@ -340,6 +340,7 @@ Class | Method | HTTP request | Description - [AssetMetadataUpsertDto](doc//AssetMetadataUpsertDto.md) - [AssetMetadataUpsertItemDto](doc//AssetMetadataUpsertItemDto.md) - [AssetOrder](doc//AssetOrder.md) + - [AssetOrderBy](doc//AssetOrderBy.md) - [AssetResponseDto](doc//AssetResponseDto.md) - [AssetStackResponseDto](doc//AssetStackResponseDto.md) - [AssetStatsResponseDto](doc//AssetStatsResponseDto.md) diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index df2c2226b1..27a3393271 100644 --- a/mobile/openapi/lib/api.dart +++ b/mobile/openapi/lib/api.dart @@ -111,6 +111,7 @@ part 'model/asset_metadata_response_dto.dart'; part 'model/asset_metadata_upsert_dto.dart'; part 'model/asset_metadata_upsert_item_dto.dart'; part 'model/asset_order.dart'; +part 'model/asset_order_by.dart'; part 'model/asset_response_dto.dart'; part 'model/asset_stack_response_dto.dart'; part 'model/asset_stats_response_dto.dart'; diff --git a/mobile/openapi/lib/api/timeline_api.dart b/mobile/openapi/lib/api/timeline_api.dart index 70ac076c9d..8f6bf4ec85 100644 --- a/mobile/openapi/lib/api/timeline_api.dart +++ b/mobile/openapi/lib/api/timeline_api.dart @@ -39,6 +39,9 @@ class TimelineApi { /// * [AssetOrder] order: /// Sort order for assets within time buckets (ASC for oldest first, DESC for newest first) /// + /// * [AssetOrderBy] orderBy: + /// Sort order by for assets within time buckets (DATE_TAKEN, DATE_ADDED, DATE_DELETED) + /// /// * [String] personId: /// Filter assets containing a specific person (face recognition) /// @@ -61,7 +64,7 @@ class TimelineApi { /// /// * [bool] withStacked: /// Include stacked assets in the response. When true, only primary assets from stacks are returned. - Future getTimeBucketWithHttpInfo(String timeBucket, { String? albumId, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { + Future getTimeBucketWithHttpInfo(String timeBucket, { String? albumId, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { // ignore: prefer_const_declarations final apiPath = r'/timeline/bucket'; @@ -87,6 +90,9 @@ class TimelineApi { if (order != null) { queryParams.addAll(_queryParams('', 'order', order)); } + if (orderBy != null) { + queryParams.addAll(_queryParams('', 'orderBy', orderBy)); + } if (personId != null) { queryParams.addAll(_queryParams('', 'personId', personId)); } @@ -148,6 +154,9 @@ class TimelineApi { /// * [AssetOrder] order: /// Sort order for assets within time buckets (ASC for oldest first, DESC for newest first) /// + /// * [AssetOrderBy] orderBy: + /// Sort order by for assets within time buckets (DATE_TAKEN, DATE_ADDED, DATE_DELETED) + /// /// * [String] personId: /// Filter assets containing a specific person (face recognition) /// @@ -170,8 +179,8 @@ class TimelineApi { /// /// * [bool] withStacked: /// Include stacked assets in the response. When true, only primary assets from stacks are returned. - Future getTimeBucket(String timeBucket, { String? albumId, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { - final response = await getTimeBucketWithHttpInfo(timeBucket, albumId: albumId, isFavorite: isFavorite, isTrashed: isTrashed, key: key, order: order, personId: personId, slug: slug, tagId: tagId, userId: userId, visibility: visibility, withCoordinates: withCoordinates, withPartners: withPartners, withStacked: withStacked, ); + Future getTimeBucket(String timeBucket, { String? albumId, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { + final response = await getTimeBucketWithHttpInfo(timeBucket, albumId: albumId, isFavorite: isFavorite, isTrashed: isTrashed, key: key, order: order, orderBy: orderBy, personId: personId, slug: slug, tagId: tagId, userId: userId, visibility: visibility, withCoordinates: withCoordinates, withPartners: withPartners, withStacked: withStacked, ); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -205,6 +214,9 @@ class TimelineApi { /// * [AssetOrder] order: /// Sort order for assets within time buckets (ASC for oldest first, DESC for newest first) /// + /// * [AssetOrderBy] orderBy: + /// Sort order by for assets within time buckets (DATE_TAKEN, DATE_ADDED, DATE_DELETED) + /// /// * [String] personId: /// Filter assets containing a specific person (face recognition) /// @@ -227,7 +239,7 @@ class TimelineApi { /// /// * [bool] withStacked: /// Include stacked assets in the response. When true, only primary assets from stacks are returned. - Future getTimeBucketsWithHttpInfo({ String? albumId, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { + Future getTimeBucketsWithHttpInfo({ String? albumId, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { // ignore: prefer_const_declarations final apiPath = r'/timeline/buckets'; @@ -253,6 +265,9 @@ class TimelineApi { if (order != null) { queryParams.addAll(_queryParams('', 'order', order)); } + if (orderBy != null) { + queryParams.addAll(_queryParams('', 'orderBy', orderBy)); + } if (personId != null) { queryParams.addAll(_queryParams('', 'personId', personId)); } @@ -310,6 +325,9 @@ class TimelineApi { /// * [AssetOrder] order: /// Sort order for assets within time buckets (ASC for oldest first, DESC for newest first) /// + /// * [AssetOrderBy] orderBy: + /// Sort order by for assets within time buckets (DATE_TAKEN, DATE_ADDED, DATE_DELETED) + /// /// * [String] personId: /// Filter assets containing a specific person (face recognition) /// @@ -332,8 +350,8 @@ class TimelineApi { /// /// * [bool] withStacked: /// Include stacked assets in the response. When true, only primary assets from stacks are returned. - Future?> getTimeBuckets({ String? albumId, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { - final response = await getTimeBucketsWithHttpInfo( albumId: albumId, isFavorite: isFavorite, isTrashed: isTrashed, key: key, order: order, personId: personId, slug: slug, tagId: tagId, userId: userId, visibility: visibility, withCoordinates: withCoordinates, withPartners: withPartners, withStacked: withStacked, ); + Future?> getTimeBuckets({ String? albumId, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { + final response = await getTimeBucketsWithHttpInfo( albumId: albumId, isFavorite: isFavorite, isTrashed: isTrashed, key: key, order: order, orderBy: orderBy, personId: personId, slug: slug, tagId: tagId, userId: userId, visibility: visibility, withCoordinates: withCoordinates, withPartners: withPartners, withStacked: withStacked, ); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index 06d27593c9..5db430a43e 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -276,6 +276,8 @@ class ApiClient { return AssetMetadataUpsertItemDto.fromJson(value); case 'AssetOrder': return AssetOrderTypeTransformer().decode(value); + case 'AssetOrderBy': + return AssetOrderByTypeTransformer().decode(value); case 'AssetResponseDto': return AssetResponseDto.fromJson(value); case 'AssetStackResponseDto': diff --git a/mobile/openapi/lib/api_helper.dart b/mobile/openapi/lib/api_helper.dart index b34e9210c8..064bb0df41 100644 --- a/mobile/openapi/lib/api_helper.dart +++ b/mobile/openapi/lib/api_helper.dart @@ -73,6 +73,9 @@ String parameterToString(dynamic value) { if (value is AssetOrder) { return AssetOrderTypeTransformer().encode(value).toString(); } + if (value is AssetOrderBy) { + return AssetOrderByTypeTransformer().encode(value).toString(); + } if (value is AssetTypeEnum) { return AssetTypeEnumTypeTransformer().encode(value).toString(); } diff --git a/mobile/openapi/lib/model/asset_order_by.dart b/mobile/openapi/lib/model/asset_order_by.dart new file mode 100644 index 0000000000..1301fc38d6 --- /dev/null +++ b/mobile/openapi/lib/model/asset_order_by.dart @@ -0,0 +1,88 @@ +// +// 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 AssetOrderBy { + /// Instantiate a new enum with the provided [value]. + const AssetOrderBy._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const ADDED = AssetOrderBy._(r'DATE_ADDED'); + static const DELETED = AssetOrderBy._(r'DATE_DELETED'); + static const TAKEN = AssetOrderBy._(r'DATE_TAKEN'); + + /// List of all possible values in this [enum][AssetOrderBy]. + static const values = [ + ADDED, + DELETED, + TAKEN, + ]; + + static AssetOrderBy? fromJson(dynamic value) => AssetOrderByTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = AssetOrderBy.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [AssetOrderBy] to String, +/// and [decode] dynamic data back to [AssetOrderBy]. +class AssetOrderByTypeTransformer { + factory AssetOrderByTypeTransformer() => _instance ??= const AssetOrderByTypeTransformer._(); + + const AssetOrderByTypeTransformer._(); + + String encode(AssetOrderBy data) => data.value; + + /// Decodes a [dynamic value][data] to a AssetOrderBy. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + AssetOrderBy? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'DATE_ADDED': return AssetOrderBy.ADDED; + case r'DATE_DELETED': return AssetOrderBy.DELETED; + case r'DATE_TAKEN': return AssetOrderBy.TAKEN; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [AssetOrderByTypeTransformer] instance. + static AssetOrderByTypeTransformer? _instance; +} + diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index b574bc6624..1efff570f6 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -8841,6 +8841,15 @@ "$ref": "#/components/schemas/AssetOrder" } }, + { + "name": "orderBy", + "required": false, + "in": "query", + "description": "Sort order by for assets within time buckets (DATE_TAKEN, DATE_ADDED, DATE_DELETED)", + "schema": { + "$ref": "#/components/schemas/AssetOrderBy" + } + }, { "name": "personId", "required": false, @@ -9005,6 +9014,15 @@ "$ref": "#/components/schemas/AssetOrder" } }, + { + "name": "orderBy", + "required": false, + "in": "query", + "description": "Sort order by for assets within time buckets (DATE_TAKEN, DATE_ADDED, DATE_DELETED)", + "schema": { + "$ref": "#/components/schemas/AssetOrderBy" + } + }, { "name": "personId", "required": false, @@ -11050,6 +11068,14 @@ ], "type": "string" }, + "AssetOrderBy": { + "enum": [ + "DATE_ADDED", + "DATE_DELETED", + "DATE_TAKEN" + ], + "type": "string" + }, "AssetResponseDto": { "properties": { "checksum": { diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index c8a69dfe8c..2d89342c18 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -4301,12 +4301,13 @@ export function tagAssets({ id, bulkIdsDto }: { /** * This endpoint requires the `asset.read` permission. */ -export function getTimeBucket({ albumId, isFavorite, isTrashed, key, order, personId, slug, tagId, timeBucket, userId, visibility, withCoordinates, withPartners, withStacked }: { +export function getTimeBucket({ albumId, isFavorite, isTrashed, key, order, orderBy, personId, slug, tagId, timeBucket, userId, visibility, withCoordinates, withPartners, withStacked }: { albumId?: string; isFavorite?: boolean; isTrashed?: boolean; key?: string; order?: AssetOrder; + orderBy?: AssetOrderBy; personId?: string; slug?: string; tagId?: string; @@ -4326,6 +4327,7 @@ export function getTimeBucket({ albumId, isFavorite, isTrashed, key, order, pers isTrashed, key, order, + orderBy, personId, slug, tagId, @@ -4342,12 +4344,13 @@ export function getTimeBucket({ albumId, isFavorite, isTrashed, key, order, pers /** * This endpoint requires the `asset.read` permission. */ -export function getTimeBuckets({ albumId, isFavorite, isTrashed, key, order, personId, slug, tagId, userId, visibility, withCoordinates, withPartners, withStacked }: { +export function getTimeBuckets({ albumId, isFavorite, isTrashed, key, order, orderBy, personId, slug, tagId, userId, visibility, withCoordinates, withPartners, withStacked }: { albumId?: string; isFavorite?: boolean; isTrashed?: boolean; key?: string; order?: AssetOrder; + orderBy?: AssetOrderBy; personId?: string; slug?: string; tagId?: string; @@ -4366,6 +4369,7 @@ export function getTimeBuckets({ albumId, isFavorite, isTrashed, key, order, per isTrashed, key, order, + orderBy, personId, slug, tagId, @@ -5040,3 +5044,8 @@ export enum OAuthTokenEndpointAuthMethod { ClientSecretPost = "client_secret_post", ClientSecretBasic = "client_secret_basic" } +export enum AssetOrderBy { + DateAdded = "DATE_ADDED", + DateDeleted = "DATE_DELETED", + DateTaken = "DATE_TAKEN" +}