From 40be4a0a09d808de0c8164f90ce4062de8e5f804 Mon Sep 17 00:00:00 2001 From: timonrieger Date: Mon, 18 May 2026 14:11:23 +0200 Subject: [PATCH] migrate mobile call sites --- mobile/lib/extensions/asset_extensions.dart | 10 +-- .../repositories/search_api.repository.dart | 90 +++++++++++-------- .../repositories/sync_api.repository.dart | 2 +- .../repositories/sync_stream.repository.dart | 4 +- .../infrastructure/utils/exif.converter.dart | 36 ++++---- .../infrastructure/utils/user.converter.dart | 2 +- .../models/shared_link/shared_link.model.dart | 4 +- .../search/search_page_state.provider.dart | 2 +- .../repositories/activity_api.repository.dart | 6 +- .../repositories/asset_api.repository.dart | 24 +++-- .../lib/repositories/auth_api.repository.dart | 4 +- .../drift_album_api_repository.dart | 26 ++++-- .../repositories/partner_api.repository.dart | 2 +- .../repositories/person_api.repository.dart | 5 +- .../repositories/sessions_api.repository.dart | 10 ++- mobile/lib/routing/locked_guard.dart | 2 +- mobile/lib/services/oauth.service.dart | 8 +- mobile/lib/services/shared_link.service.dart | 48 +++++----- .../sync_stream_repository_test.dart | 2 +- mobile/test/fixtures/sync_stream.stub.dart | 4 +- 20 files changed, 168 insertions(+), 123 deletions(-) diff --git a/mobile/lib/extensions/asset_extensions.dart b/mobile/lib/extensions/asset_extensions.dart index 7e1bef1a1c..445af99e79 100644 --- a/mobile/lib/extensions/asset_extensions.dart +++ b/mobile/lib/extensions/asset_extensions.dart @@ -18,11 +18,11 @@ extension DTOToAsset on api.AssetResponseDto { height: height?.toInt(), width: width?.toInt(), isFavorite: isFavorite, - livePhotoVideoId: livePhotoVideoId, + livePhotoVideoId: livePhotoVideoId.orElse(null), thumbHash: thumbhash, localId: null, type: type.toAssetType(), - stackId: stack?.id, + stackId: stack.orElse(null)?.id, isEdited: isEdited, ); } @@ -41,13 +41,13 @@ extension DTOToAsset on api.AssetResponseDto { height: height?.toInt(), width: width?.toInt(), isFavorite: isFavorite, - livePhotoVideoId: livePhotoVideoId, + livePhotoVideoId: livePhotoVideoId.orElse(null), thumbHash: thumbhash, localId: null, type: type.toAssetType(), - stackId: stack?.id, + stackId: stack.orElse(null)?.id, isEdited: isEdited, - exifInfo: exifInfo != null ? ExifDtoConverter.fromDto(exifInfo!) : const ExifInfo(), + exifInfo: exifInfo.orElse(null) != null ? ExifDtoConverter.fromDto(exifInfo.orElse(null)!) : const ExifInfo(), ); } } diff --git a/mobile/lib/infrastructure/repositories/search_api.repository.dart b/mobile/lib/infrastructure/repositories/search_api.repository.dart index bcfddfce6e..e2f2af17eb 100644 --- a/mobile/lib/infrastructure/repositories/search_api.repository.dart +++ b/mobile/lib/infrastructure/repositories/search_api.repository.dart @@ -20,50 +20,64 @@ class SearchApiRepository extends ApiRepository { (filter.assetId != null && filter.assetId!.isNotEmpty)) { return _api.searchSmart( SmartSearchDto( - query: filter.context, - queryAssetId: filter.assetId, - language: filter.language, - country: filter.location.country, - state: filter.location.state, - city: filter.location.city, - make: filter.camera.make, - model: filter.camera.model, - takenAfter: filter.date.takenAfter, - takenBefore: filter.date.takenBefore, - visibility: filter.display.isArchive ? AssetVisibility.archive : AssetVisibility.timeline, - rating: filter.rating.rating, - isFavorite: filter.display.isFavorite ? true : null, - isNotInAlbum: filter.display.isNotInAlbum ? true : null, - personIds: filter.people.map((e) => e.id).toList(), - tagIds: filter.tagIds, - type: type, - page: page, - size: 100, + 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 == null ? const Optional.absent() : Optional.present(filter.rating.rating!), + 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: filter.tagIds == null ? const Optional.absent() : Optional.present(filter.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 ? filter.filename : null, - country: filter.location.country, - description: filter.description != null && filter.description!.isNotEmpty ? filter.description : null, - ocr: filter.ocr != null && filter.ocr!.isNotEmpty ? filter.ocr : null, - state: filter.location.state, - city: filter.location.city, - make: filter.camera.make, - model: filter.camera.model, - takenAfter: filter.date.takenAfter, - takenBefore: filter.date.takenBefore, - visibility: filter.display.isArchive ? AssetVisibility.archive : AssetVisibility.timeline, - rating: filter.rating.rating, - isFavorite: filter.display.isFavorite ? true : null, - isNotInAlbum: filter.display.isNotInAlbum ? true : null, - personIds: filter.people.map((e) => e.id).toList(), - tagIds: filter.tagIds, - type: type, - page: page, - size: 1000, + 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 == null ? const Optional.absent() : Optional.present(filter.rating.rating!), + 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: filter.tagIds == null ? const Optional.absent() : Optional.present(filter.tagIds!), + type: type == null ? const Optional.absent() : Optional.present(type), + page: Optional.present(page), + size: const Optional.present(1000), ), ); } diff --git a/mobile/lib/infrastructure/repositories/sync_api.repository.dart b/mobile/lib/infrastructure/repositories/sync_api.repository.dart index d9d262e64f..8b8475d31f 100644 --- a/mobile/lib/infrastructure/repositories/sync_api.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_api.repository.dart @@ -20,7 +20,7 @@ class SyncApiRepository { } Future deleteSyncAck(List types) { - return _api.syncApi.deleteSyncAck(SyncAckDeleteDto(types: types)); + return _api.syncApi.deleteSyncAck(SyncAckDeleteDto(types: Optional.present(types))); } Future streamChanges( diff --git a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart index b7593c3202..bd672171bc 100644 --- a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart @@ -91,7 +91,7 @@ class SyncStreamRepository extends DriftDatabaseRepository { email: Value(user.email), hasProfileImage: Value(user.hasProfileImage), profileChangedAt: Value(user.profileChangedAt), - avatarColor: Value(user.avatarColor?.toAvatarColor() ?? AvatarColor.primary), + avatarColor: Value(user.avatarColor.orElse(null)?.toAvatarColor() ?? AvatarColor.primary), isAdmin: Value(user.isAdmin), pinCode: Value(user.pinCode), quotaSizeInBytes: Value(user.quotaSizeInBytes ?? 0), @@ -133,7 +133,7 @@ class SyncStreamRepository extends DriftDatabaseRepository { email: Value(user.email), hasProfileImage: Value(user.hasProfileImage), profileChangedAt: Value(user.profileChangedAt), - avatarColor: Value(user.avatarColor?.toAvatarColor() ?? AvatarColor.primary), + avatarColor: Value(user.avatarColor.orElse(null)?.toAvatarColor() ?? AvatarColor.primary), ); batch.insert(_db.userEntity, companion.copyWith(id: Value(user.id)), onConflict: DoUpdate((_) => companion)); diff --git a/mobile/lib/infrastructure/utils/exif.converter.dart b/mobile/lib/infrastructure/utils/exif.converter.dart index 50639e8e42..9f9b6f9324 100644 --- a/mobile/lib/infrastructure/utils/exif.converter.dart +++ b/mobile/lib/infrastructure/utils/exif.converter.dart @@ -5,24 +5,24 @@ import 'package:openapi/api.dart'; abstract final class ExifDtoConverter { static ExifInfo fromDto(ExifResponseDto dto) { return ExifInfo( - fileSize: dto.fileSizeInByte, - description: dto.description, - orientation: dto.orientation, - timeZone: dto.timeZone, - dateTimeOriginal: dto.dateTimeOriginal, - isFlipped: isOrientationFlipped(dto.orientation), - latitude: dto.latitude?.toDouble(), - longitude: dto.longitude?.toDouble(), - city: dto.city, - state: dto.state, - country: dto.country, - make: dto.make, - model: dto.model, - lens: dto.lensModel, - f: dto.fNumber?.toDouble(), - mm: dto.focalLength?.toDouble(), - iso: dto.iso?.toInt(), - exposureSeconds: exposureTimeToSeconds(dto.exposureTime), + fileSize: dto.fileSizeInByte.orElse(null), + description: dto.description.orElse(null), + orientation: dto.orientation.orElse(null), + timeZone: dto.timeZone.orElse(null), + dateTimeOriginal: dto.dateTimeOriginal.orElse(null), + isFlipped: isOrientationFlipped(dto.orientation.orElse(null)), + latitude: dto.latitude.orElse(null)?.toDouble(), + longitude: dto.longitude.orElse(null)?.toDouble(), + city: dto.city.orElse(null), + state: dto.state.orElse(null), + country: dto.country.orElse(null), + make: dto.make.orElse(null), + model: dto.model.orElse(null), + lens: dto.lensModel.orElse(null), + f: dto.fNumber.orElse(null)?.toDouble(), + mm: dto.focalLength.orElse(null)?.toDouble(), + iso: dto.iso.orElse(null)?.toInt(), + exposureSeconds: exposureTimeToSeconds(dto.exposureTime.orElse(null)), ); } diff --git a/mobile/lib/infrastructure/utils/user.converter.dart b/mobile/lib/infrastructure/utils/user.converter.dart index 826649b247..7e8a2c6fcc 100644 --- a/mobile/lib/infrastructure/utils/user.converter.dart +++ b/mobile/lib/infrastructure/utils/user.converter.dart @@ -40,7 +40,7 @@ abstract final class UserConverter { updatedAt: DateTime.now(), avatarColor: dto.avatarColor.toAvatarColor(), memoryEnabled: false, - inTimeline: dto.inTimeline ?? false, + inTimeline: dto.inTimeline.orElse(null) ?? false, isPartnerSharedBy: false, isPartnerSharedWith: false, profileChangedAt: dto.profileChangedAt, diff --git a/mobile/lib/models/shared_link/shared_link.model.dart b/mobile/lib/models/shared_link/shared_link.model.dart index 4315cf616a..e7b65a96ef 100644 --- a/mobile/lib/models/shared_link/shared_link.model.dart +++ b/mobile/lib/models/shared_link/shared_link.model.dart @@ -73,10 +73,10 @@ class SharedLink { slug = dto.slug, type = dto.type == SharedLinkType.ALBUM ? SharedLinkSource.album : SharedLinkSource.individual, title = dto.type == SharedLinkType.ALBUM - ? dto.album?.albumName.toUpperCase() ?? "UNKNOWN SHARE" + ? dto.album.orElse(null)?.albumName.toUpperCase() ?? "UNKNOWN SHARE" : "INDIVIDUAL SHARE", thumbAssetId = dto.type == SharedLinkType.ALBUM - ? dto.album?.albumThumbnailAssetId + ? dto.album.orElse(null)?.albumThumbnailAssetId : dto.assets.isNotEmpty ? dto.assets[0].id : null; diff --git a/mobile/lib/providers/search/search_page_state.provider.dart b/mobile/lib/providers/search/search_page_state.provider.dart index 23d5606922..c6a72c922e 100644 --- a/mobile/lib/providers/search/search_page_state.provider.dart +++ b/mobile/lib/providers/search/search_page_state.provider.dart @@ -29,7 +29,7 @@ final getAllPlacesProvider = FutureProvider.autoDispose SearchCuratedContent(label: data.exifInfo!.city!, id: data.id)) + .map((data) => SearchCuratedContent(label: data.exifInfo.orElse(null)!.city.orElse(null)!, id: data.id)) .toList(); return curatedContent; diff --git a/mobile/lib/repositories/activity_api.repository.dart b/mobile/lib/repositories/activity_api.repository.dart index e8f9abc8c8..9ae83b0e7b 100644 --- a/mobile/lib/repositories/activity_api.repository.dart +++ b/mobile/lib/repositories/activity_api.repository.dart @@ -23,8 +23,8 @@ class ActivityApiRepository extends ApiRepository { final dto = ActivityCreateDto( albumId: albumId, type: type == ActivityType.comment ? ReactionType.comment : ReactionType.like, - assetId: assetId, - comment: comment, + assetId: assetId == null ? const Optional.absent() : Optional.present(assetId), + comment: comment == null ? const Optional.absent() : Optional.present(comment), ); final response = await checkNull(_api.createActivity(dto)); return _toActivity(response); @@ -45,6 +45,6 @@ class ActivityApiRepository extends ApiRepository { type: dto.type == ReactionType.comment ? ActivityType.comment : ActivityType.like, user: UserConverter.fromSimpleUserDto(dto.user), assetId: dto.assetId, - comment: dto.comment, + comment: dto.comment.orElse(null), ); } diff --git a/mobile/lib/repositories/asset_api.repository.dart b/mobile/lib/repositories/asset_api.repository.dart index fdb4e3323b..4a23ced504 100644 --- a/mobile/lib/repositories/asset_api.repository.dart +++ b/mobile/lib/repositories/asset_api.repository.dart @@ -24,7 +24,7 @@ class AssetApiRepository extends ApiRepository { AssetApiRepository(this._api, this._stacksApi, this._trashApi); Future delete(List ids, bool force) async { - return _api.deleteAssets(AssetBulkDeleteDto(ids: ids, force: force)); + return _api.deleteAssets(AssetBulkDeleteDto(ids: ids, force: Optional.present(force))); } Future restoreTrash(List ids) async { @@ -42,19 +42,27 @@ class AssetApiRepository extends ApiRepository { } Future updateVisibility(List ids, AssetVisibilityEnum visibility) async { - return _api.updateAssets(AssetBulkUpdateDto(ids: ids, visibility: _mapVisibility(visibility))); + return _api.updateAssets(AssetBulkUpdateDto(ids: ids, visibility: Optional.present(_mapVisibility(visibility)))); } Future updateFavorite(List ids, bool isFavorite) async { - return _api.updateAssets(AssetBulkUpdateDto(ids: ids, isFavorite: isFavorite)); + return _api.updateAssets(AssetBulkUpdateDto(ids: ids, isFavorite: Optional.present(isFavorite))); } Future updateLocation(List ids, LatLng location) async { - return _api.updateAssets(AssetBulkUpdateDto(ids: ids, latitude: location.latitude, longitude: location.longitude)); + return _api.updateAssets( + AssetBulkUpdateDto( + ids: ids, + latitude: Optional.present(location.latitude), + longitude: Optional.present(location.longitude), + ), + ); } Future updateDateTime(List ids, DateTime dateTime) async { - return _api.updateAssets(AssetBulkUpdateDto(ids: ids, dateTimeOriginal: dateTime.toIso8601String())); + return _api.updateAssets( + AssetBulkUpdateDto(ids: ids, dateTimeOriginal: Optional.present(dateTime.toIso8601String())), + ); } Future stack(List ids) async { @@ -82,15 +90,15 @@ class AssetApiRepository extends ApiRepository { final response = await checkNull(_api.getAssetInfo(assetId)); // we need to get the MIME of the thumbnail once that gets added to the API - return response.originalMimeType; + return response.originalMimeType.orElse(null); } Future updateDescription(String assetId, String description) { - return _api.updateAsset(assetId, UpdateAssetDto(description: description)); + return _api.updateAsset(assetId, UpdateAssetDto(description: Optional.present(description))); } Future updateRating(String assetId, int rating) { - return _api.updateAsset(assetId, UpdateAssetDto(rating: rating)); + return _api.updateAsset(assetId, UpdateAssetDto(rating: Optional.present(rating))); } Future editAsset(String assetId, List edits) { diff --git a/mobile/lib/repositories/auth_api.repository.dart b/mobile/lib/repositories/auth_api.repository.dart index 446aba68b3..05dc7f103a 100644 --- a/mobile/lib/repositories/auth_api.repository.dart +++ b/mobile/lib/repositories/auth_api.repository.dart @@ -13,7 +13,7 @@ class AuthApiRepository extends ApiRepository { AuthApiRepository(this._apiService); Future changePassword(String newPassword) async { - await _apiService.usersApi.updateMyUser(UserUpdateMeDto(password: newPassword)); + await _apiService.usersApi.updateMyUser(UserUpdateMeDto(password: Optional.present(newPassword))); } Future login(String email, String password) async { @@ -46,7 +46,7 @@ class AuthApiRepository extends ApiRepository { Future unlockPinCode(String pinCode) async { try { - await _apiService.authenticationApi.unlockAuthSession(SessionUnlockDto(pinCode: pinCode)); + await _apiService.authenticationApi.unlockAuthSession(SessionUnlockDto(pinCode: Optional.present(pinCode))); return true; } catch (_) { return false; diff --git a/mobile/lib/repositories/drift_album_api_repository.dart b/mobile/lib/repositories/drift_album_api_repository.dart index a0c7a3732a..445f5763a2 100644 --- a/mobile/lib/repositories/drift_album_api_repository.dart +++ b/mobile/lib/repositories/drift_album_api_repository.dart @@ -22,7 +22,13 @@ class DriftAlbumApiRepository extends ApiRepository { String? description, }) async { final responseDto = await checkNull( - _api.createAlbum(CreateAlbumDto(albumName: name, description: description, assetIds: assetIds.toList())), + _api.createAlbum( + CreateAlbumDto( + albumName: name, + description: description == null ? const Optional.absent() : Optional.present(description), + assetIds: Optional.present(assetIds.toList()), + ), + ), ); return responseDto.toRemoteAlbum(owner); @@ -73,11 +79,13 @@ class DriftAlbumApiRepository extends ApiRepository { _api.updateAlbumInfo( albumId, UpdateAlbumDto( - albumName: name, - description: description, - albumThumbnailAssetId: thumbnailAssetId, - isActivityEnabled: isActivityEnabled, - order: apiOrder, + albumName: name == null ? const Optional.absent() : Optional.present(name), + description: description == null ? const Optional.absent() : Optional.present(description), + albumThumbnailAssetId: thumbnailAssetId == null + ? const Optional.absent() + : Optional.present(thumbnailAssetId), + isActivityEnabled: isActivityEnabled == null ? const Optional.absent() : Optional.present(isActivityEnabled), + order: apiOrder == null ? const Optional.absent() : Optional.present(apiOrder), ), ), ); @@ -99,7 +107,9 @@ class DriftAlbumApiRepository extends ApiRepository { } Future setActivityStatus(String albumId, bool isEnabled) async { - final response = await checkNull(_api.updateAlbumInfo(albumId, UpdateAlbumDto(isActivityEnabled: isEnabled))); + final response = await checkNull( + _api.updateAlbumInfo(albumId, UpdateAlbumDto(isActivityEnabled: Optional.present(isEnabled))), + ); return response.isActivityEnabled; } } @@ -116,7 +126,7 @@ extension on AlbumResponseDto { updatedAt: updatedAt, thumbnailAssetId: albumThumbnailAssetId, isActivityEnabled: isActivityEnabled, - order: order == AssetOrder.asc ? AlbumAssetOrder.asc : AlbumAssetOrder.desc, + order: order.orElse(null) == AssetOrder.asc ? AlbumAssetOrder.asc : AlbumAssetOrder.desc, assetCount: assetCount, isShared: albumUsers.length > 2, ); diff --git a/mobile/lib/repositories/partner_api.repository.dart b/mobile/lib/repositories/partner_api.repository.dart index 69b6740cbe..eaca839bfd 100644 --- a/mobile/lib/repositories/partner_api.repository.dart +++ b/mobile/lib/repositories/partner_api.repository.dart @@ -16,7 +16,7 @@ class PartnerApiRepository extends ApiRepository { Future> getAll(Direction direction) async { final response = await checkNull( - _api.getPartners(direction == Direction.sharedByMe ? PartnerDirection.by : PartnerDirection.with_), + _api.getPartners(direction == Direction.sharedByMe ? PartnerDirection.sharedBy : PartnerDirection.sharedWith), ); return response.map(UserConverter.fromPartnerDto).toList(); } diff --git a/mobile/lib/repositories/person_api.repository.dart b/mobile/lib/repositories/person_api.repository.dart index bbf55e674a..26662601b7 100644 --- a/mobile/lib/repositories/person_api.repository.dart +++ b/mobile/lib/repositories/person_api.repository.dart @@ -18,7 +18,10 @@ class PersonApiRepository extends ApiRepository { Future update(String id, {String? name, DateTime? birthday}) async { final birthdayUtc = birthday == null ? null : DateTime.utc(birthday.year, birthday.month, birthday.day); - final dto = PersonUpdateDto(name: name, birthDate: birthdayUtc); + final dto = PersonUpdateDto( + name: name == null ? const Optional.absent() : Optional.present(name), + birthDate: birthdayUtc == null ? const Optional.absent() : Optional.present(birthdayUtc), + ); final response = await checkNull(_api.updatePerson(id, dto)); return _toPerson(response); } diff --git a/mobile/lib/repositories/sessions_api.repository.dart b/mobile/lib/repositories/sessions_api.repository.dart index f25e724f19..b2ed54c26c 100644 --- a/mobile/lib/repositories/sessions_api.repository.dart +++ b/mobile/lib/repositories/sessions_api.repository.dart @@ -15,7 +15,13 @@ class SessionsAPIRepository extends ApiRepository { Future createSession(String deviceType, String deviceOS, {int? duration}) async { final dto = await checkNull( - _api.createSession(SessionCreateDto(deviceType: deviceType, deviceOS: deviceOS, duration: duration)), + _api.createSession( + SessionCreateDto( + deviceType: Optional.present(deviceType), + deviceOS: Optional.present(deviceOS), + duration: duration == null ? const Optional.absent() : Optional.present(duration), + ), + ), ); return SessionCreateResponse( @@ -23,7 +29,7 @@ class SessionsAPIRepository extends ApiRepository { current: dto.current, deviceType: deviceType, deviceOS: deviceOS, - expiresAt: dto.expiresAt, + expiresAt: dto.expiresAt.orElse(null), createdAt: dto.createdAt, updatedAt: dto.updatedAt, token: dto.token, diff --git a/mobile/lib/routing/locked_guard.dart b/mobile/lib/routing/locked_guard.dart index ddb6a7e694..38484538e0 100644 --- a/mobile/lib/routing/locked_guard.dart +++ b/mobile/lib/routing/locked_guard.dart @@ -55,7 +55,7 @@ class LockedGuard extends AutoRouteGuard { return; } - await _apiService.authenticationApi.unlockAuthSession(SessionUnlockDto(pinCode: securePinCode)); + await _apiService.authenticationApi.unlockAuthSession(SessionUnlockDto(pinCode: Optional.present(securePinCode))); resolver.next(true); } on PlatformException catch (error) { diff --git a/mobile/lib/services/oauth.service.dart b/mobile/lib/services/oauth.service.dart index 99ceca3229..d8b1604e00 100644 --- a/mobile/lib/services/oauth.service.dart +++ b/mobile/lib/services/oauth.service.dart @@ -18,7 +18,11 @@ class OAuthService { log.info("Starting OAuth flow with redirect URI: $redirectUri"); final dto = await _apiService.oAuthApi.startOAuth( - OAuthConfigDto(redirectUri: redirectUri, state: state, codeChallenge: codeChallenge), + OAuthConfigDto( + redirectUri: redirectUri, + state: Optional.present(state), + codeChallenge: Optional.present(codeChallenge), + ), ); final authUrl = dto?.url; @@ -37,7 +41,7 @@ class OAuthService { } return await _apiService.oAuthApi.finishOAuth( - OAuthCallbackDto(url: result, state: state, codeVerifier: codeVerifier), + OAuthCallbackDto(url: result, state: Optional.present(state), codeVerifier: Optional.present(codeVerifier)), ); } } diff --git a/mobile/lib/services/shared_link.service.dart b/mobile/lib/services/shared_link.service.dart index 46e83f0fc4..009e922b38 100644 --- a/mobile/lib/services/shared_link.service.dart +++ b/mobile/lib/services/shared_link.service.dart @@ -48,26 +48,26 @@ class SharedLinkService { if (type == SharedLinkType.ALBUM) { dto = SharedLinkCreateDto( type: type, - albumId: albumId, - showMetadata: showMeta, - allowDownload: allowDownload, - allowUpload: allowUpload, - expiresAt: expiresAt, - description: description, - password: password, - slug: slug, + albumId: albumId == null ? const Optional.absent() : Optional.present(albumId), + showMetadata: Optional.present(showMeta), + allowDownload: Optional.present(allowDownload), + allowUpload: Optional.present(allowUpload), + expiresAt: expiresAt == null ? const Optional.absent() : Optional.present(expiresAt), + description: description == null ? const Optional.absent() : Optional.present(description), + password: password == null ? const Optional.absent() : Optional.present(password), + slug: slug == null ? const Optional.absent() : Optional.present(slug), ); } else if (assetIds != null) { dto = SharedLinkCreateDto( type: type, - showMetadata: showMeta, - allowDownload: allowDownload, - allowUpload: allowUpload, - expiresAt: expiresAt, - description: description, - password: password, - slug: slug, - assetIds: assetIds, + showMetadata: Optional.present(showMeta), + allowDownload: Optional.present(allowDownload), + allowUpload: Optional.present(allowUpload), + expiresAt: expiresAt == null ? const Optional.absent() : Optional.present(expiresAt), + description: description == null ? const Optional.absent() : Optional.present(description), + password: password == null ? const Optional.absent() : Optional.present(password), + slug: slug == null ? const Optional.absent() : Optional.present(slug), + assetIds: Optional.present(assetIds), ); } @@ -98,14 +98,14 @@ class SharedLinkService { final responseDto = await _apiService.sharedLinksApi.updateSharedLink( id, SharedLinkEditDto( - showMetadata: showMeta, - allowDownload: allowDownload, - allowUpload: allowUpload, - expiresAt: expiresAt, - description: description, - password: password, - slug: slug, - changeExpiryTime: changeExpiry, + showMetadata: showMeta == null ? const Optional.absent() : Optional.present(showMeta), + allowDownload: allowDownload == null ? const Optional.absent() : Optional.present(allowDownload), + allowUpload: allowUpload == null ? const Optional.absent() : Optional.present(allowUpload), + expiresAt: expiresAt == null ? const Optional.absent() : Optional.present(expiresAt), + description: description == null ? const Optional.absent() : Optional.present(description), + password: password == null ? const Optional.absent() : Optional.present(password), + slug: slug == null ? const Optional.absent() : Optional.present(slug), + changeExpiryTime: changeExpiry == null ? const Optional.absent() : Optional.present(changeExpiry), ), ); if (responseDto != null) { diff --git a/mobile/test/domain/repositories/sync_stream_repository_test.dart b/mobile/test/domain/repositories/sync_stream_repository_test.dart index 4199a5b756..bd47f63da5 100644 --- a/mobile/test/domain/repositories/sync_stream_repository_test.dart +++ b/mobile/test/domain/repositories/sync_stream_repository_test.dart @@ -15,7 +15,7 @@ SyncUserV1 _createUser({String id = 'user-1'}) { name: 'Test User', email: 'test@test.com', deletedAt: null, - avatarColor: null, + avatarColor: const Optional.absent(), hasProfileImage: false, profileChangedAt: DateTime(2024, 1, 1), ); diff --git a/mobile/test/fixtures/sync_stream.stub.dart b/mobile/test/fixtures/sync_stream.stub.dart index 6d8c0bfdf2..1691fbdc49 100644 --- a/mobile/test/fixtures/sync_stream.stub.dart +++ b/mobile/test/fixtures/sync_stream.stub.dart @@ -9,7 +9,7 @@ abstract final class SyncStreamStub { email: "admin@admin", id: "1", name: "Admin", - avatarColor: null, + avatarColor: const Optional.absent(), hasProfileImage: false, profileChangedAt: DateTime(2025), ), @@ -22,7 +22,7 @@ abstract final class SyncStreamStub { email: "user@user", id: "5", name: "User", - avatarColor: null, + avatarColor: const Optional.absent(), hasProfileImage: false, profileChangedAt: DateTime(2025), ),