* feat(mobile): mobile tags * fix(mobile); refactoring, replaced hook * tag provider through asset service * make search use a tag set * use tag action directly * use notification listener * untag action * handle untag response * fix tests and add untag action test * fix material error from tag picker dialog * fix(mobile): clip tag picker tiles and update tag overflow --------- Co-authored-by: Alex <alex.tran1502@gmail.com> Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Santo Shakil <shakil.mezbah@gmail.com> (cherry picked from commit 83c7ec50056bbefa10869c78457f8882c72275e2)
96 lines
5.1 KiB
Dart
96 lines
5.1 KiB
Dart
import 'package:immich_mobile/data/server/api_repository.dart';
|
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart' hide AssetVisibility;
|
|
import 'package:immich_mobile/models/search/search_filter.model.dart';
|
|
import 'package:immich_mobile/utils/option.dart';
|
|
import 'package:openapi/api.dart' hide SearchFilter;
|
|
|
|
class SearchApiRepository extends ApiRepository {
|
|
final SearchApi _api;
|
|
|
|
const SearchApiRepository(this._api);
|
|
|
|
Future<SearchResponseDto?> search(SearchFilter filter, int page) {
|
|
AssetTypeEnum? type;
|
|
if (filter.mediaType.index == AssetType.image.index) {
|
|
type = AssetTypeEnum.IMAGE;
|
|
} else if (filter.mediaType.index == AssetType.video.index) {
|
|
type = AssetTypeEnum.VIDEO;
|
|
}
|
|
|
|
final tagIds = filter.tags == null
|
|
? const Optional<List<String>>.absent()
|
|
: Optional.present(filter.tags!.map((tag) => tag.id).toList());
|
|
|
|
if ((filter.context != null && filter.context!.isNotEmpty) ||
|
|
(filter.assetId != null && filter.assetId!.isNotEmpty)) {
|
|
return _api.searchSmart(
|
|
SmartSearchDto(
|
|
query: filter.context == null ? const Optional.absent() : Optional.present(filter.context),
|
|
queryAssetId: filter.assetId == null ? const Optional.absent() : Optional.present(filter.assetId),
|
|
language: filter.language == null ? const Optional.absent() : Optional.present(filter.language),
|
|
country: filter.location.country == null
|
|
? const Optional.absent()
|
|
: Optional.present(filter.location.country),
|
|
state: filter.location.state == null ? const Optional.absent() : Optional.present(filter.location.state),
|
|
city: filter.location.city == null ? const Optional.absent() : Optional.present(filter.location.city),
|
|
make: filter.camera.make == null ? const Optional.absent() : Optional.present(filter.camera.make),
|
|
model: filter.camera.model == null ? const Optional.absent() : Optional.present(filter.camera.model),
|
|
takenAfter: filter.date.takenAfter == null
|
|
? const Optional.absent()
|
|
: Optional.present(filter.date.takenAfter),
|
|
takenBefore: filter.date.takenBefore == null
|
|
? const Optional.absent()
|
|
: Optional.present(filter.date.takenBefore),
|
|
visibility: Optional.present(filter.display.isArchive ? AssetVisibility.archive : AssetVisibility.timeline),
|
|
rating: filter.rating.rating.toOptional(),
|
|
isFavorite: filter.display.isFavorite ? const Optional.present(true) : const Optional.absent(),
|
|
isNotInAlbum: filter.display.isNotInAlbum ? const Optional.present(true) : const Optional.absent(),
|
|
personIds: Optional.present(filter.people.map((e) => e.id).toList()),
|
|
tagIds: tagIds,
|
|
type: type == null ? const Optional.absent() : Optional.present(type),
|
|
page: Optional.present(page),
|
|
size: const Optional.present(100),
|
|
),
|
|
);
|
|
}
|
|
|
|
return _api.searchAssets(
|
|
MetadataSearchDto(
|
|
originalFileName: filter.filename != null && filter.filename!.isNotEmpty
|
|
? Optional.present(filter.filename)
|
|
: const Optional.absent(),
|
|
country: filter.location.country == null ? const Optional.absent() : Optional.present(filter.location.country),
|
|
description: filter.description != null && filter.description!.isNotEmpty
|
|
? Optional.present(filter.description)
|
|
: const Optional.absent(),
|
|
ocr: filter.ocr != null && filter.ocr!.isNotEmpty ? Optional.present(filter.ocr) : const Optional.absent(),
|
|
state: filter.location.state == null ? const Optional.absent() : Optional.present(filter.location.state),
|
|
city: filter.location.city == null ? const Optional.absent() : Optional.present(filter.location.city),
|
|
make: filter.camera.make == null ? const Optional.absent() : Optional.present(filter.camera.make),
|
|
model: filter.camera.model == null ? const Optional.absent() : Optional.present(filter.camera.model),
|
|
takenAfter: filter.date.takenAfter == null ? const Optional.absent() : Optional.present(filter.date.takenAfter),
|
|
takenBefore: filter.date.takenBefore == null
|
|
? const Optional.absent()
|
|
: Optional.present(filter.date.takenBefore),
|
|
visibility: Optional.present(filter.display.isArchive ? AssetVisibility.archive : AssetVisibility.timeline),
|
|
rating: filter.rating.rating.toOptional(),
|
|
isFavorite: filter.display.isFavorite ? const Optional.present(true) : const Optional.absent(),
|
|
isNotInAlbum: filter.display.isNotInAlbum ? const Optional.present(true) : const Optional.absent(),
|
|
personIds: Optional.present(filter.people.map((e) => e.id).toList()),
|
|
tagIds: tagIds,
|
|
type: type == null ? const Optional.absent() : Optional.present(type),
|
|
page: Optional.present(page),
|
|
size: const Optional.present(1000),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<List<String>?> getSearchSuggestions(
|
|
SearchSuggestionType type, {
|
|
String? country,
|
|
String? state,
|
|
String? make,
|
|
String? model,
|
|
}) => _api.getSearchSuggestions(type, country: country, state: state, make: make, model: model);
|
|
}
|