From 9cf3b88f80b0d9736fc9cb121e0d768da736ce56 Mon Sep 17 00:00:00 2001 From: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> Date: Tue, 18 Mar 2025 21:35:37 +0530 Subject: [PATCH] refactor(mobile): remove int user id (#16814) * refactor: user entity * chore: rebase fixes * refactor: remove int user Id * refactor: migrate store userId from int to string * refactor: rename uid to id * fix: migration * pr feedback --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> --- .../lib/domain/interfaces/user.interface.dart | 4 +- mobile/lib/domain/models/user.model.dart | 16 +++---- .../lib/extensions/collection_extensions.dart | 7 +-- .../infrastructure/entities/user.entity.dart | 4 +- .../repositories/store.repository.dart | 6 ++- .../repositories/user.repository.dart | 9 +--- .../infrastructure/utils/user.converter.dart | 6 +-- mobile/lib/interfaces/asset.interface.dart | 14 +++--- mobile/lib/interfaces/etag.interface.dart | 2 +- mobile/lib/interfaces/timeline.interface.dart | 19 ++++---- ...additional_shared_user_selection.page.dart | 4 +- .../lib/pages/album/album_options.page.dart | 6 +-- mobile/lib/pages/albums/albums.page.dart | 2 +- mobile/lib/pages/common/activities.page.dart | 2 +- mobile/lib/providers/auth.provider.dart | 2 +- mobile/lib/providers/timeline.provider.dart | 5 ++- mobile/lib/providers/user.provider.dart | 6 +-- mobile/lib/repositories/album.repository.dart | 19 +++----- mobile/lib/repositories/asset.repository.dart | 43 ++++++++++--------- .../repositories/asset_media.repository.dart | 3 +- mobile/lib/repositories/etag.repository.dart | 2 +- .../lib/repositories/timeline.repository.dart | 38 ++++++++-------- mobile/lib/services/album.service.dart | 7 +-- mobile/lib/services/asset.service.dart | 4 +- mobile/lib/services/partner.service.dart | 12 +++--- mobile/lib/services/sync.service.dart | 26 +++++------ mobile/lib/services/timeline.service.dart | 14 +++--- mobile/lib/utils/migration.dart | 22 +++++++++- .../widgets/album/album_thumbnail_card.dart | 2 +- .../asset_viewer/bottom_gallery_bar.dart | 4 +- .../asset_viewer/description_input.dart | 3 +- .../widgets/asset_viewer/gallery_app_bar.dart | 6 ++- mobile/lib/widgets/common/user_avatar.dart | 2 +- .../widgets/common/user_circle_avatar.dart | 2 +- mobile/test/fixtures/user.stub.dart | 6 +-- .../modules/shared/sync_service_test.dart | 4 +- mobile/test/services/album.service_test.dart | 4 +- mobile/test/services/entity.service_test.dart | 2 +- 38 files changed, 182 insertions(+), 157 deletions(-) diff --git a/mobile/lib/domain/interfaces/user.interface.dart b/mobile/lib/domain/interfaces/user.interface.dart index 03f3ebb63e..05176731fd 100644 --- a/mobile/lib/domain/interfaces/user.interface.dart +++ b/mobile/lib/domain/interfaces/user.interface.dart @@ -4,8 +4,6 @@ import 'package:immich_mobile/domain/models/user.model.dart'; abstract interface class IUserRepository implements IDatabaseRepository { Future insert(UserDto user); - Future get(int id); - Future getByUserId(String id); Future> getByUserIds(List ids); @@ -16,7 +14,7 @@ abstract interface class IUserRepository implements IDatabaseRepository { Future update(UserDto user); - Future delete(List ids); + Future delete(List ids); Future deleteAll(); } diff --git a/mobile/lib/domain/models/user.model.dart b/mobile/lib/domain/models/user.model.dart index ceb65f313a..ad241a8c48 100644 --- a/mobile/lib/domain/models/user.model.dart +++ b/mobile/lib/domain/models/user.model.dart @@ -1,7 +1,5 @@ import 'dart:ui'; -import 'package:immich_mobile/utils/hash.dart'; - enum AvatarColor { // do not change this order or reuse indices for other purposes, adding is OK primary, @@ -32,7 +30,7 @@ enum AvatarColor { // TODO: Rename to User once Isar is removed class UserDto { - final String uid; + final String id; final String email; final String name; final bool isAdmin; @@ -50,11 +48,10 @@ class UserDto { final int quotaUsageInBytes; final int quotaSizeInBytes; - int get id => fastHash(uid); bool get hasQuota => quotaSizeInBytes > 0; const UserDto({ - required this.uid, + required this.id, required this.email, required this.name, required this.isAdmin, @@ -73,7 +70,6 @@ class UserDto { String toString() { return '''User: { id: $id, -uid: $uid, email: $email, name: $name, isAdmin: $isAdmin, @@ -90,7 +86,7 @@ quotaSizeInBytes: $quotaSizeInBytes, } UserDto copyWith({ - String? uid, + String? id, String? email, String? name, bool? isAdmin, @@ -105,7 +101,7 @@ quotaSizeInBytes: $quotaSizeInBytes, int? quotaSizeInBytes, }) => UserDto( - uid: uid ?? this.uid, + id: id ?? this.id, email: email ?? this.email, name: name ?? this.name, isAdmin: isAdmin ?? this.isAdmin, @@ -124,7 +120,7 @@ quotaSizeInBytes: $quotaSizeInBytes, bool operator ==(covariant UserDto other) { if (identical(this, other)) return true; - return other.uid == uid && + return other.id == id && other.updatedAt.isAtSameMomentAs(updatedAt) && other.avatarColor == avatarColor && other.email == email && @@ -141,7 +137,7 @@ quotaSizeInBytes: $quotaSizeInBytes, @override int get hashCode => - uid.hashCode ^ + id.hashCode ^ name.hashCode ^ email.hashCode ^ updatedAt.hashCode ^ diff --git a/mobile/lib/extensions/collection_extensions.dart b/mobile/lib/extensions/collection_extensions.dart index e02582588b..95d2f74df8 100644 --- a/mobile/lib/extensions/collection_extensions.dart +++ b/mobile/lib/extensions/collection_extensions.dart @@ -3,6 +3,7 @@ import 'dart:typed_data'; import 'package:collection/collection.dart'; import 'package:immich_mobile/domain/models/user.model.dart'; import 'package:immich_mobile/entities/asset.entity.dart'; +import 'package:immich_mobile/utils/hash.dart'; extension ListExtension on List { List uniqueConsecutive({ @@ -62,11 +63,11 @@ extension AssetListExtension on Iterable { void Function()? errorCallback, }) { if (owner == null) return []; - final userId = owner.id; - final bool onlyOwned = every((e) => e.ownerId == userId); + final isarUserId = fastHash(owner.id); + final bool onlyOwned = every((e) => e.ownerId == isarUserId); if (!onlyOwned) { if (errorCallback != null) errorCallback(); - return where((a) => a.ownerId == userId); + return where((a) => a.ownerId == isarUserId); } return this; } diff --git a/mobile/lib/infrastructure/entities/user.entity.dart b/mobile/lib/infrastructure/entities/user.entity.dart index 834559b936..710856d9f7 100644 --- a/mobile/lib/infrastructure/entities/user.entity.dart +++ b/mobile/lib/infrastructure/entities/user.entity.dart @@ -40,7 +40,7 @@ class User { }); static User fromDto(UserDto dto) => User( - id: dto.uid, + id: dto.id, updatedAt: dto.updatedAt, email: dto.email, name: dto.name, @@ -56,7 +56,7 @@ class User { ); UserDto toDto() => UserDto( - uid: id, + id: id, email: email, name: name, isAdmin: isAdmin, diff --git a/mobile/lib/infrastructure/repositories/store.repository.dart b/mobile/lib/infrastructure/repositories/store.repository.dart index 1e5a5335d5..86dfaf4452 100644 --- a/mobile/lib/infrastructure/repositories/store.repository.dart +++ b/mobile/lib/infrastructure/repositories/store.repository.dart @@ -78,7 +78,9 @@ class IsarStoreRepository extends IsarDatabaseRepository const (DateTime) => entity.intValue == null ? null : DateTime.fromMillisecondsSinceEpoch(entity.intValue!), - const (UserDto) => await IsarUserRepository(_db).get(entity.intValue!), + const (UserDto) => entity.strValue == null + ? null + : await IsarUserRepository(_db).getByUserId(entity.strValue!), _ => null, } as T?; @@ -89,8 +91,8 @@ class IsarStoreRepository extends IsarDatabaseRepository const (bool) => ((value as bool) ? 1 : 0, null), const (DateTime) => ((value as DateTime).millisecondsSinceEpoch, null), const (UserDto) => ( - (await IsarUserRepository(_db).update(value as UserDto)).id, null, + (await IsarUserRepository(_db).update(value as UserDto)).id, ), _ => throw UnsupportedError( "Unsupported primitive type: ${key.type} for key: ${key.name}", diff --git a/mobile/lib/infrastructure/repositories/user.repository.dart b/mobile/lib/infrastructure/repositories/user.repository.dart index 2cb8023b2a..f12b95f64b 100644 --- a/mobile/lib/infrastructure/repositories/user.repository.dart +++ b/mobile/lib/infrastructure/repositories/user.repository.dart @@ -11,9 +11,9 @@ class IsarUserRepository extends IsarDatabaseRepository const IsarUserRepository(super.db) : _db = db; @override - Future delete(List ids) async { + Future delete(List ids) async { await transaction(() async { - await _db.users.deleteAll(ids); + await _db.users.deleteAllById(ids); }); } @@ -24,11 +24,6 @@ class IsarUserRepository extends IsarDatabaseRepository }); } - @override - Future get(int id) async { - return (await _db.users.get(id))?.toDto(); - } - @override Future> getAll({SortUserBy? sortBy}) async { return (await _db.users diff --git a/mobile/lib/infrastructure/utils/user.converter.dart b/mobile/lib/infrastructure/utils/user.converter.dart index 11f9ddec33..fcf7ede51c 100644 --- a/mobile/lib/infrastructure/utils/user.converter.dart +++ b/mobile/lib/infrastructure/utils/user.converter.dart @@ -4,7 +4,7 @@ import 'package:openapi/api.dart'; abstract final class UserConverter { /// Base user dto used where the complete user object is not required static UserDto fromSimpleUserDto(UserResponseDto dto) => UserDto( - uid: dto.id, + id: dto.id, email: dto.email, name: dto.name, isAdmin: false, @@ -18,7 +18,7 @@ abstract final class UserConverter { UserPreferencesResponseDto? preferenceDto, ]) => UserDto( - uid: adminDto.id, + id: adminDto.id, email: adminDto.email, name: adminDto.name, isAdmin: adminDto.isAdmin, @@ -34,7 +34,7 @@ abstract final class UserConverter { ); static UserDto fromPartnerDto(PartnerResponseDto dto) => UserDto( - uid: dto.id, + id: dto.id, email: dto.email, name: dto.name, isAdmin: false, diff --git a/mobile/lib/interfaces/asset.interface.dart b/mobile/lib/interfaces/asset.interface.dart index 83a020f843..ed524c4f35 100644 --- a/mobile/lib/interfaces/asset.interface.dart +++ b/mobile/lib/interfaces/asset.interface.dart @@ -19,7 +19,7 @@ abstract interface class IAssetRepository implements IDatabaseRepository { ); Future> getAll({ - required int ownerId, + required String ownerId, AssetState? state, AssetSort? sortBy, int? limit, @@ -29,8 +29,8 @@ abstract interface class IAssetRepository implements IDatabaseRepository { Future> getByAlbum( Album album, { - Iterable notOwnedBy = const [], - int? ownerId, + Iterable notOwnedBy = const [], + String? ownerId, AssetState? state, AssetSort? sortBy, }); @@ -45,7 +45,7 @@ abstract interface class IAssetRepository implements IDatabaseRepository { Future> getMatches({ required List assets, - required int ownerId, + required String ownerId, AssetState? state, int limit = 100, }); @@ -64,10 +64,10 @@ abstract interface class IAssetRepository implements IDatabaseRepository { Stream watchAsset(int id, {bool fireImmediately = false}); - Future> getTrashAssets(int userId); + Future> getTrashAssets(String userId); - Future> getRecentlyAddedAssets(int userId); - Future> getMotionAssets(int userId); + Future> getRecentlyAddedAssets(String userId); + Future> getMotionAssets(String userId); } enum AssetSort { checksum, ownerIdChecksum } diff --git a/mobile/lib/interfaces/etag.interface.dart b/mobile/lib/interfaces/etag.interface.dart index 22942b0e34..8b4b5806c9 100644 --- a/mobile/lib/interfaces/etag.interface.dart +++ b/mobile/lib/interfaces/etag.interface.dart @@ -2,7 +2,7 @@ import 'package:immich_mobile/entities/etag.entity.dart'; import 'package:immich_mobile/interfaces/database.interface.dart'; abstract interface class IETagRepository implements IDatabaseRepository { - Future get(int id); + Future get(String id); Future getById(String id); diff --git a/mobile/lib/interfaces/timeline.interface.dart b/mobile/lib/interfaces/timeline.interface.dart index d43f87ed5b..bc486a785f 100644 --- a/mobile/lib/interfaces/timeline.interface.dart +++ b/mobile/lib/interfaces/timeline.interface.dart @@ -3,22 +3,25 @@ import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart'; abstract class ITimelineRepository { - Future> getTimelineUserIds(int id); + Future> getTimelineUserIds(String id); - Stream> watchTimelineUsers(int id); + Stream> watchTimelineUsers(String id); - Stream watchArchiveTimeline(int userId); - Stream watchFavoriteTimeline(int userId); - Stream watchTrashTimeline(int userId); + Stream watchArchiveTimeline(String userId); + Stream watchFavoriteTimeline(String userId); + Stream watchTrashTimeline(String userId); Stream watchAlbumTimeline( Album album, GroupAssetsBy groupAssetsBy, ); Stream watchAllVideosTimeline(); - Stream watchHomeTimeline(int userId, GroupAssetsBy groupAssetsBy); + Stream watchHomeTimeline( + String userId, + GroupAssetsBy groupAssetsBy, + ); Stream watchMultiUsersTimeline( - List userIds, + List userIds, GroupAssetsBy groupAssetsBy, ); @@ -27,5 +30,5 @@ abstract class ITimelineRepository { GroupAssetsBy getGroupByOption, ); - Stream watchAssetSelectionTimeline(int userId); + Stream watchAssetSelectionTimeline(String userId); } diff --git a/mobile/lib/pages/album/album_additional_shared_user_selection.page.dart b/mobile/lib/pages/album/album_additional_shared_user_selection.page.dart index 2dc41b396d..194f749a32 100644 --- a/mobile/lib/pages/album/album_additional_shared_user_selection.page.dart +++ b/mobile/lib/pages/album/album_additional_shared_user_selection.page.dart @@ -26,7 +26,7 @@ class AlbumAdditionalSharedUserSelectionPage extends HookConsumerWidget { final sharedUsersList = useState>({}); addNewUsersHandler() { - context.maybePop(sharedUsersList.value.map((e) => e.uid).toList()); + context.maybePop(sharedUsersList.value.map((e) => e.id).toList()); } buildTileIcon(UserDto user) { @@ -151,7 +151,7 @@ class AlbumAdditionalSharedUserSelectionPage extends HookConsumerWidget { onData: (users) { for (var sharedUsers in album.sharedUsers) { users.removeWhere( - (u) => u.uid == sharedUsers.id || u.uid == album.ownerId, + (u) => u.id == sharedUsers.id || u.id == album.ownerId, ); } diff --git a/mobile/lib/pages/album/album_options.page.dart b/mobile/lib/pages/album/album_options.page.dart index a765be50b3..73a03154f6 100644 --- a/mobile/lib/pages/album/album_options.page.dart +++ b/mobile/lib/pages/album/album_options.page.dart @@ -85,7 +85,7 @@ class AlbumOptionsPage extends HookConsumerWidget { void handleUserClick(UserDto user) { var actions = []; - if (user.uid == userId) { + if (user.id == userId) { actions = [ ListTile( leading: const Icon(Icons.exit_to_app_rounded), @@ -170,10 +170,10 @@ class AlbumOptionsPage extends HookConsumerWidget { color: context.colorScheme.onSurfaceSecondary, ), ), - trailing: userId == user.uid || isOwner + trailing: userId == user.id || isOwner ? const Icon(Icons.more_horiz_rounded) : const SizedBox(), - onTap: userId == user.uid || isOwner + onTap: userId == user.id || isOwner ? () => handleUserClick(user) : null, ); diff --git a/mobile/lib/pages/albums/albums.page.dart b/mobile/lib/pages/albums/albums.page.dart index acdfbf385f..e5758c959c 100644 --- a/mobile/lib/pages/albums/albums.page.dart +++ b/mobile/lib/pages/albums/albums.page.dart @@ -33,7 +33,7 @@ class AlbumsPage extends HookConsumerWidget { final searchController = useTextEditingController(); final debounceTimer = useRef(null); final filterMode = useState(QuickFilterMode.all); - final userId = ref.watch(currentUserProvider)?.uid; + final userId = ref.watch(currentUserProvider)?.id; final searchFocusNode = useFocusNode(); toggleViewMode() { diff --git a/mobile/lib/pages/common/activities.page.dart b/mobile/lib/pages/common/activities.page.dart index 84a8622fa5..776ee9977b 100644 --- a/mobile/lib/pages/common/activities.page.dart +++ b/mobile/lib/pages/common/activities.page.dart @@ -72,7 +72,7 @@ class ActivitiesPage extends HookConsumerWidget { final activity = data[index]; final canDelete = activity.user.id == user?.id || - album.ownerId == user?.uid; + album.ownerId == user?.id; return Padding( padding: const EdgeInsets.all(5), diff --git a/mobile/lib/providers/auth.provider.dart b/mobile/lib/providers/auth.provider.dart index 9187808984..3221b80526 100644 --- a/mobile/lib/providers/auth.provider.dart +++ b/mobile/lib/providers/auth.provider.dart @@ -153,7 +153,7 @@ class AuthNotifier extends StateNotifier { state = state.copyWith( deviceId: deviceId, - userId: user.uid, + userId: user.id, userEmail: user.email, isAuthenticated: true, name: user.name, diff --git a/mobile/lib/providers/timeline.provider.dart b/mobile/lib/providers/timeline.provider.dart index 97d5698c4c..f857d8aa6c 100644 --- a/mobile/lib/providers/timeline.provider.dart +++ b/mobile/lib/providers/timeline.provider.dart @@ -5,7 +5,7 @@ import 'package:immich_mobile/providers/locale_provider.dart'; import 'package:immich_mobile/services/timeline.service.dart'; import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart'; -final singleUserTimelineProvider = StreamProvider.family( +final singleUserTimelineProvider = StreamProvider.family( (ref, userId) { if (userId == null) { return const Stream.empty(); @@ -18,7 +18,8 @@ final singleUserTimelineProvider = StreamProvider.family( dependencies: [localeProvider], ); -final multiUsersTimelineProvider = StreamProvider.family>( +final multiUsersTimelineProvider = + StreamProvider.family>( (ref, userIds) { ref.watch(localeProvider); final timelineService = ref.watch(timelineServiceProvider); diff --git a/mobile/lib/providers/user.provider.dart b/mobile/lib/providers/user.provider.dart index c3623106e8..99dfba9010 100644 --- a/mobile/lib/providers/user.provider.dart +++ b/mobile/lib/providers/user.provider.dart @@ -34,7 +34,7 @@ final currentUserProvider = return CurrentUserProvider(ref.watch(userServiceProvider)); }); -class TimelineUserIdsProvider extends StateNotifier> { +class TimelineUserIdsProvider extends StateNotifier> { TimelineUserIdsProvider(this._timelineService) : super([]) { _timelineService.getTimelineUserIds().then((users) => state = users); streamSub = _timelineService @@ -42,7 +42,7 @@ class TimelineUserIdsProvider extends StateNotifier> { .listen((users) => state = users); } - late final StreamSubscription> streamSub; + late final StreamSubscription> streamSub; final TimelineService _timelineService; @override @@ -53,6 +53,6 @@ class TimelineUserIdsProvider extends StateNotifier> { } final timelineUsersIdsProvider = - StateNotifierProvider>((ref) { + StateNotifierProvider>((ref) { return TimelineUserIdsProvider(ref.watch(timelineServiceProvider)); }); diff --git a/mobile/lib/repositories/album.repository.dart b/mobile/lib/repositories/album.repository.dart index a6657f7637..8c50c54382 100644 --- a/mobile/lib/repositories/album.repository.dart +++ b/mobile/lib/repositories/album.repository.dart @@ -10,6 +10,7 @@ import 'package:immich_mobile/interfaces/album.interface.dart'; import 'package:immich_mobile/models/albums/album_search.model.dart'; import 'package:immich_mobile/providers/db.provider.dart'; import 'package:immich_mobile/repositories/database.repository.dart'; +import 'package:immich_mobile/utils/hash.dart'; import 'package:isar/isar.dart'; final albumRepositoryProvider = @@ -43,14 +44,11 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository { if (shared != null) { query = query.sharedEqualTo(shared); } + final isarUserId = fastHash(Store.get(StoreKey.currentUser).id); if (owner == true) { - query = query.owner( - (q) => q.isarIdEqualTo(Store.get(StoreKey.currentUser).id), - ); + query = query.owner((q) => q.isarIdEqualTo(isarUserId)); } else if (owner == false) { - query = query.owner( - (q) => q.not().isarIdEqualTo(Store.get(StoreKey.currentUser).id), - ); + query = query.owner((q) => q.not().isarIdEqualTo(isarUserId)); } if (remote == true) { query = query.localIdIsNull(); @@ -140,16 +138,13 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository { .filter() .nameContains(searchTerm, caseSensitive: false) .remoteIdIsNotNull(); + final isarUserId = fastHash(Store.get(StoreKey.currentUser).id); switch (filterMode) { case QuickFilterMode.sharedWithMe: - query = query.owner( - (q) => q.not().isarIdEqualTo(Store.get(StoreKey.currentUser).id), - ); + query = query.owner((q) => q.not().isarIdEqualTo(isarUserId)); case QuickFilterMode.myAlbums: - query = query.owner( - (q) => q.isarIdEqualTo(Store.get(StoreKey.currentUser).id), - ); + query = query.owner((q) => q.isarIdEqualTo(isarUserId)); case QuickFilterMode.all: break; } diff --git a/mobile/lib/repositories/asset.repository.dart b/mobile/lib/repositories/asset.repository.dart index c27660c352..ac1c768df0 100644 --- a/mobile/lib/repositories/asset.repository.dart +++ b/mobile/lib/repositories/asset.repository.dart @@ -11,6 +11,7 @@ import 'package:immich_mobile/infrastructure/entities/exif.entity.dart'; import 'package:immich_mobile/interfaces/asset.interface.dart'; import 'package:immich_mobile/providers/db.provider.dart'; import 'package:immich_mobile/repositories/database.repository.dart'; +import 'package:immich_mobile/utils/hash.dart'; import 'package:isar/isar.dart'; final assetRepositoryProvider = @@ -22,20 +23,21 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository { @override Future> getByAlbum( Album album, { - Iterable notOwnedBy = const [], - int? ownerId, + Iterable notOwnedBy = const [], + String? ownerId, AssetState? state, AssetSort? sortBy, }) { var query = album.assets.filter(); + final isarUserIds = notOwnedBy.map(fastHash).toList(); if (notOwnedBy.length == 1) { - query = query.not().ownerIdEqualTo(notOwnedBy.first); + query = query.not().ownerIdEqualTo(isarUserIds.first); } else if (notOwnedBy.isNotEmpty) { query = - query.not().anyOf(notOwnedBy, (q, int id) => q.ownerIdEqualTo(id)); + query.not().anyOf(isarUserIds, (q, int id) => q.ownerIdEqualTo(id)); } if (ownerId != null) { - query = query.ownerIdEqualTo(ownerId); + query = query.ownerIdEqualTo(fastHash(ownerId)); } if (state != null) { @@ -87,27 +89,28 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository { @override Future> getAll({ - required int ownerId, + required String ownerId, AssetState? state, AssetSort? sortBy, int? limit, }) { final baseQuery = db.assets.where(); + final isarUserIds = fastHash(ownerId); final QueryBuilder filteredQuery = switch (state) { - null => baseQuery.ownerIdEqualToAnyChecksum(ownerId).noOp(), + null => baseQuery.ownerIdEqualToAnyChecksum(isarUserIds).noOp(), AssetState.local => baseQuery .remoteIdIsNull() .filter() .localIdIsNotNull() - .ownerIdEqualTo(ownerId), + .ownerIdEqualTo(isarUserIds), AssetState.remote => baseQuery .localIdIsNull() .filter() .remoteIdIsNotNull() - .ownerIdEqualTo(ownerId), + .ownerIdEqualTo(isarUserIds), AssetState.merged => baseQuery - .ownerIdEqualToAnyChecksum(ownerId) + .ownerIdEqualToAnyChecksum(isarUserIds) .filter() .remoteIdIsNotNull() .localIdIsNotNull(), @@ -132,7 +135,7 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository { @override Future> getMatches({ required List assets, - required int ownerId, + required String ownerId, AssetState? state, int limit = 100, }) { @@ -147,7 +150,7 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository { AssetState.merged => baseQuery.localIdIsNotNull().filter().remoteIdIsNotNull(), }; - return _getMatchesImpl(query, ownerId, assets, limit); + return _getMatchesImpl(query, fastHash(ownerId), assets, limit); } @override @@ -185,10 +188,10 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository { @override Future> getAllByOwnerIdChecksum( - List ids, + List ownerIds, List checksums, ) => - db.assets.getAllByOwnerIdChecksum(ids, checksums); + db.assets.getAllByOwnerIdChecksum(ownerIds, checksums); @override Future> getAllLocal() => @@ -224,30 +227,30 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository { } @override - Future> getTrashAssets(int userId) { + Future> getTrashAssets(String userId) { return db.assets .where() .remoteIdIsNotNull() .filter() - .ownerIdEqualTo(userId) + .ownerIdEqualTo(fastHash(userId)) .isTrashedEqualTo(true) .findAll(); } @override - Future> getRecentlyAddedAssets(int userId) { + Future> getRecentlyAddedAssets(String userId) { return db.assets .where() - .ownerIdEqualToAnyChecksum(userId) + .ownerIdEqualToAnyChecksum(fastHash(userId)) .sortByFileCreatedAtDesc() .findAll(); } @override - Future> getMotionAssets(int userId) { + Future> getMotionAssets(String userId) { return db.assets .where() - .ownerIdEqualToAnyChecksum(userId) + .ownerIdEqualToAnyChecksum(fastHash(userId)) .filter() .livePhotoVideoIdIsNotNull() .findAll(); diff --git a/mobile/lib/repositories/asset_media.repository.dart b/mobile/lib/repositories/asset_media.repository.dart index 0149a8d6c6..7df26455cd 100644 --- a/mobile/lib/repositories/asset_media.repository.dart +++ b/mobile/lib/repositories/asset_media.repository.dart @@ -4,6 +4,7 @@ import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/interfaces/asset_media.interface.dart'; +import 'package:immich_mobile/utils/hash.dart'; import 'package:photo_manager/photo_manager.dart' hide AssetType; final assetMediaRepositoryProvider = Provider((ref) => AssetMediaRepository()); @@ -24,7 +25,7 @@ class AssetMediaRepository implements IAssetMediaRepository { final Asset asset = Asset( checksum: "", localId: local.id, - ownerId: Store.get(StoreKey.currentUser).id, + ownerId: fastHash(Store.get(StoreKey.currentUser).id), fileCreatedAt: local.createDateTime, fileModifiedAt: local.modifiedDateTime, updatedAt: local.modifiedDateTime, diff --git a/mobile/lib/repositories/etag.repository.dart b/mobile/lib/repositories/etag.repository.dart index 93d98de28c..e8e0624a89 100644 --- a/mobile/lib/repositories/etag.repository.dart +++ b/mobile/lib/repositories/etag.repository.dart @@ -15,7 +15,7 @@ class ETagRepository extends DatabaseRepository implements IETagRepository { Future> getAllIds() => db.eTags.where().idProperty().findAll(); @override - Future get(int id) => db.eTags.get(id); + Future get(String id) => db.eTags.getById(id); @override Future upsertAll(List etags) => txn(() => db.eTags.putAll(etags)); diff --git a/mobile/lib/repositories/timeline.repository.dart b/mobile/lib/repositories/timeline.repository.dart index 1b0471059f..319ce3e5b4 100644 --- a/mobile/lib/repositories/timeline.repository.dart +++ b/mobile/lib/repositories/timeline.repository.dart @@ -6,6 +6,7 @@ import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; import 'package:immich_mobile/interfaces/timeline.interface.dart'; import 'package:immich_mobile/providers/db.provider.dart'; import 'package:immich_mobile/repositories/database.repository.dart'; +import 'package:immich_mobile/utils/hash.dart'; import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart'; import 'package:isar/isar.dart'; @@ -17,32 +18,32 @@ class TimelineRepository extends DatabaseRepository TimelineRepository(super.db); @override - Future> getTimelineUserIds(int id) { + Future> getTimelineUserIds(String id) { return db.users .filter() .inTimelineEqualTo(true) .or() - .isarIdEqualTo(id) - .isarIdProperty() + .idEqualTo(id) + .idProperty() .findAll(); } @override - Stream> watchTimelineUsers(int id) { + Stream> watchTimelineUsers(String id) { return db.users .filter() .inTimelineEqualTo(true) .or() - .isarIdEqualTo(id) - .isarIdProperty() + .idEqualTo(id) + .idProperty() .watch(); } @override - Stream watchArchiveTimeline(int userId) { + Stream watchArchiveTimeline(String userId) { final query = db.assets .where() - .ownerIdEqualToAnyChecksum(userId) + .ownerIdEqualToAnyChecksum(fastHash(userId)) .filter() .isArchivedEqualTo(true) .isTrashedEqualTo(false) @@ -52,10 +53,10 @@ class TimelineRepository extends DatabaseRepository } @override - Stream watchFavoriteTimeline(int userId) { + Stream watchFavoriteTimeline(String userId) { final query = db.assets .where() - .ownerIdEqualToAnyChecksum(userId) + .ownerIdEqualToAnyChecksum(fastHash(userId)) .filter() .isFavoriteEqualTo(true) .isTrashedEqualTo(false) @@ -79,10 +80,10 @@ class TimelineRepository extends DatabaseRepository } @override - Stream watchTrashTimeline(int userId) { + Stream watchTrashTimeline(String userId) { final query = db.assets .filter() - .ownerIdEqualTo(userId) + .ownerIdEqualTo(fastHash(userId)) .isTrashedEqualTo(true) .sortByFileCreatedAtDesc(); @@ -103,12 +104,12 @@ class TimelineRepository extends DatabaseRepository @override Stream watchHomeTimeline( - int userId, + String userId, GroupAssetsBy groupAssetByOption, ) { final query = db.assets .where() - .ownerIdEqualToAnyChecksum(userId) + .ownerIdEqualToAnyChecksum(fastHash(userId)) .filter() .isArchivedEqualTo(false) .isTrashedEqualTo(false) @@ -120,12 +121,13 @@ class TimelineRepository extends DatabaseRepository @override Stream watchMultiUsersTimeline( - List userIds, + List userIds, GroupAssetsBy groupAssetByOption, ) { + final isarUserIds = userIds.map(fastHash).toList(); final query = db.assets .where() - .anyOf(userIds, (qb, userId) => qb.ownerIdEqualToAnyChecksum(userId)) + .anyOf(isarUserIds, (qb, id) => qb.ownerIdEqualToAnyChecksum(id)) .filter() .isArchivedEqualTo(false) .isTrashedEqualTo(false) @@ -143,12 +145,12 @@ class TimelineRepository extends DatabaseRepository } @override - Stream watchAssetSelectionTimeline(int userId) { + Stream watchAssetSelectionTimeline(String userId) { final query = db.assets .where() .remoteIdIsNotNull() .filter() - .ownerIdEqualTo(userId) + .ownerIdEqualTo(fastHash(userId)) .isTrashedEqualTo(false) .stackPrimaryAssetIdIsNull() .sortByFileCreatedAtDesc(); diff --git a/mobile/lib/services/album.service.dart b/mobile/lib/services/album.service.dart index 1251ef51fe..0922f506d5 100644 --- a/mobile/lib/services/album.service.dart +++ b/mobile/lib/services/album.service.dart @@ -28,6 +28,7 @@ import 'package:immich_mobile/repositories/asset.repository.dart'; import 'package:immich_mobile/repositories/backup.repository.dart'; import 'package:immich_mobile/services/entity.service.dart'; import 'package:immich_mobile/services/sync.service.dart'; +import 'package:immich_mobile/utils/hash.dart'; import 'package:logging/logging.dart'; final albumServiceProvider = Provider( @@ -208,7 +209,7 @@ class AlbumService { final Album album = await _albumApiRepository.create( albumName, assetIds: assets.map((asset) => asset.remoteId!), - sharedUserIds: sharedUsers.map((user) => user.uid), + sharedUserIds: sharedUsers.map((user) => user.id), ); await _entityService.fillAlbumWithDatabaseEntities(album); return _albumRepository.create(album); @@ -296,7 +297,7 @@ class AlbumService { Future deleteAlbum(Album album) async { try { final userId = _userService.getMyUser().id; - if (album.owner.value?.isarId == userId) { + if (album.owner.value?.isarId == fastHash(userId)) { await _albumApiRepository.delete(album.remoteId!); } if (album.shared) { @@ -362,7 +363,7 @@ class AlbumService { try { await _albumApiRepository.removeUser( album.remoteId!, - userId: user.uid, + userId: user.id, ); album.sharedUsers.remove(entity.User.fromDto(user)); diff --git a/mobile/lib/services/asset.service.dart b/mobile/lib/services/asset.service.dart index 6eff80ae02..2894f5a7de 100644 --- a/mobile/lib/services/asset.service.dart +++ b/mobile/lib/services/asset.service.dart @@ -101,7 +101,7 @@ class AssetService { _getRemoteAssetChanges(List users, DateTime since) async { final dto = AssetDeltaSyncDto( updatedAfter: since, - userIds: users.map((e) => e.uid).toList(), + userIds: users.map((e) => e.id).toList(), ); final changes = await _apiService.syncApi.getDeltaSync(dto); return changes == null || changes.needsFullSync @@ -142,7 +142,7 @@ class AssetService { limit: chunkSize, updatedUntil: until, lastId: lastId, - userId: user.uid, + userId: user.id, ); log.fine("Requesting $chunkSize assets from $lastId"); final List? assets = diff --git a/mobile/lib/services/partner.service.dart b/mobile/lib/services/partner.service.dart index cc3631a0b1..78d4d71e99 100644 --- a/mobile/lib/services/partner.service.dart +++ b/mobile/lib/services/partner.service.dart @@ -46,10 +46,10 @@ class PartnerService { Future removePartner(UserDto partner) async { try { - await _partnerApiRepository.delete(partner.uid); + await _partnerApiRepository.delete(partner.id); await _userRepository.update(partner.copyWith(isPartnerSharedBy: false)); } catch (e) { - _log.warning("Failed to remove partner ${partner.uid}", e); + _log.warning("Failed to remove partner ${partner.id}", e); return false; } return true; @@ -57,11 +57,11 @@ class PartnerService { Future addPartner(UserDto partner) async { try { - await _partnerApiRepository.create(partner.uid); + await _partnerApiRepository.create(partner.id); await _userRepository.update(partner.copyWith(isPartnerSharedBy: true)); return true; } catch (e) { - _log.warning("Failed to add partner ${partner.uid}", e); + _log.warning("Failed to add partner ${partner.id}", e); } return false; } @@ -72,14 +72,14 @@ class PartnerService { }) async { try { final dto = await _partnerApiRepository.update( - partner.uid, + partner.id, inTimeline: inTimeline, ); await _userRepository .update(partner.copyWith(inTimeline: dto.inTimeline)); return true; } catch (e) { - _log.warning("Failed to update partner ${partner.uid}", e); + _log.warning("Failed to update partner ${partner.id}", e); } return false; } diff --git a/mobile/lib/services/sync.service.dart b/mobile/lib/services/sync.service.dart index 24f2fd00d6..1386eebec7 100644 --- a/mobile/lib/services/sync.service.dart +++ b/mobile/lib/services/sync.service.dart @@ -32,6 +32,7 @@ import 'package:immich_mobile/services/hash.service.dart'; import 'package:immich_mobile/utils/async_mutex.dart'; import 'package:immich_mobile/utils/datetime_comparison.dart'; import 'package:immich_mobile/utils/diff.dart'; +import 'package:immich_mobile/utils/hash.dart'; import 'package:logging/logging.dart'; final syncServiceProvider = Provider( @@ -152,14 +153,14 @@ class SyncService { /// Syncs users from the server to the local database /// Returns `true`if there were any changes Future _syncUsersFromServer(List users) async { - users.sortBy((u) => u.uid); + users.sortBy((u) => u.id); final dbUsers = await _userRepository.getAll(sortBy: SortUserBy.id); - final List toDelete = []; + final List toDelete = []; final List toUpsert = []; final changes = diffSortedListsSync( users, dbUsers, - compare: (UserDto a, UserDto b) => a.uid.compareTo(b.uid), + compare: (UserDto a, UserDto b) => a.id.compareTo(b.id), both: (UserDto a, UserDto b) { if (!a.updatedAt.isAtSameMomentAs(b.updatedAt) || a.isPartnerSharedBy != b.isPartnerSharedBy || @@ -319,12 +320,12 @@ class SyncService { } Future _updateUserAssetsETag(List users, DateTime time) { - final etags = users.map((u) => ETag(id: u.uid, time: time)).toList(); + final etags = users.map((u) => ETag(id: u.id, time: time)).toList(); return _eTagRepository.upsertAll(etags); } Future _clearUserAssetsETag(List users) { - final ids = users.map((u) => u.uid).toList(); + final ids = users.map((u) => u.id).toList(); return _eTagRepository.deleteByIds(ids); } @@ -408,7 +409,7 @@ class SyncService { sharedUsers, compare: (UserDto a, UserDto b) => a.id.compareTo(b.id), both: (a, b) => false, - onlyFirst: (UserDto a) => userIdsToAdd.add(a.uid), + onlyFirst: (UserDto a) => userIdsToAdd.add(a.id), onlySecond: (UserDto a) => usersToUnlink.add(a), ); @@ -459,7 +460,8 @@ class SyncService { existing.addAll(foreign); // delete assets in DB unless they belong to this user or part of some other shared album - deleteCandidates.addAll(toUnlink.where((a) => a.ownerId != userId)); + final isarUserId = fastHash(userId); + deleteCandidates.addAll(toUnlink.where((a) => a.ownerId != isarUserId)); } return true; @@ -878,16 +880,16 @@ class SyncService { return null; } - users.sortBy((u) => u.uid); - sharedBy.sortBy((u) => u.uid); - sharedWith.sortBy((u) => u.uid); + users.sortBy((u) => u.id); + sharedBy.sortBy((u) => u.id); + sharedWith.sortBy((u) => u.id); final updatedSharedBy = []; diffSortedListsSync( users, sharedBy, - compare: (UserDto a, UserDto b) => a.uid.compareTo(b.uid), + compare: (UserDto a, UserDto b) => a.id.compareTo(b.id), both: (UserDto a, UserDto b) { updatedSharedBy.add(a.copyWith(isPartnerSharedBy: true)); return true; @@ -901,7 +903,7 @@ class SyncService { diffSortedListsSync( updatedSharedBy, sharedWith, - compare: (UserDto a, UserDto b) => a.uid.compareTo(b.uid), + compare: (UserDto a, UserDto b) => a.id.compareTo(b.id), both: (UserDto a, UserDto b) { updatedSharedWith.add( a.copyWith(inTimeline: b.inTimeline, isPartnerSharedWith: true), diff --git a/mobile/lib/services/timeline.service.dart b/mobile/lib/services/timeline.service.dart index dd2252602d..4e91d27a7c 100644 --- a/mobile/lib/services/timeline.service.dart +++ b/mobile/lib/services/timeline.service.dart @@ -28,21 +28,21 @@ class TimelineService { this._userService, ); - Future> getTimelineUserIds() async { + Future> getTimelineUserIds() async { final me = _userService.getMyUser(); return _timelineRepository.getTimelineUserIds(me.id); } - Stream> watchTimelineUserIds() async* { + Stream> watchTimelineUserIds() async* { final me = _userService.getMyUser(); yield* _timelineRepository.watchTimelineUsers(me.id); } - Stream watchHomeTimeline(int userId) { + Stream watchHomeTimeline(String userId) { return _timelineRepository.watchHomeTimeline(userId, _getGroupByOption()); } - Stream watchMultiUsersTimeline(List userIds) { + Stream watchMultiUsersTimeline(List userIds) { return _timelineRepository.watchMultiUsersTimeline( userIds, _getGroupByOption(), @@ -83,10 +83,10 @@ class TimelineService { GroupAssetsBy? groupBy, ) { GroupAssetsBy groupOption = GroupAssetsBy.none; - if (groupBy != null) { - groupOption = groupBy; - } else { + if (groupBy == null) { groupOption = _getGroupByOption(); + } else { + groupOption = groupBy; } return _timelineRepository.getTimelineFromAssets( diff --git a/mobile/lib/utils/migration.dart b/mobile/lib/utils/migration.dart index d2f0a2ac9d..3e73ab445b 100644 --- a/mobile/lib/utils/migration.dart +++ b/mobile/lib/utils/migration.dart @@ -6,13 +6,33 @@ import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/etag.entity.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/infrastructure/entities/exif.entity.dart'; +import 'package:immich_mobile/infrastructure/entities/store.entity.dart'; import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; import 'package:isar/isar.dart'; -const int targetVersion = 8; +const int targetVersion = 9; Future migrateDatabaseIfNeeded(Isar db) async { final int version = Store.get(StoreKey.version, 1); + + if (version < 9) { + await Store.put(StoreKey.version, version); + final value = await db.storeValues.get(StoreKey.currentUser.id); + if (value != null) { + final id = value.intValue; + if (id == null) { + return; + } + await db.writeTxn(() async { + final user = await db.users.get(id); + await db.storeValues + .put(StoreValue(StoreKey.currentUser.id, strValue: user?.id)); + }); + } + // Do not clear other entities + return; + } + if (version < targetVersion) { _migrateTo(db, targetVersion); } diff --git a/mobile/lib/widgets/album/album_thumbnail_card.dart b/mobile/lib/widgets/album/album_thumbnail_card.dart index 089544a9f1..30e2fc58b9 100644 --- a/mobile/lib/widgets/album/album_thumbnail_card.dart +++ b/mobile/lib/widgets/album/album_thumbnail_card.dart @@ -58,7 +58,7 @@ class AlbumThumbnailCard extends ConsumerWidget { // Add the owner name to the subtitle String? owner; if (showOwner) { - if (album.ownerId == ref.read(currentUserProvider)?.uid) { + if (album.ownerId == ref.read(currentUserProvider)?.id) { owner = 'album_thumbnail_owned'.tr(); } else if (album.ownerName != null) { owner = 'album_thumbnail_shared_by'.tr(args: [album.ownerName!]); diff --git a/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart b/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart index 1b225f106f..ea54c69e53 100644 --- a/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart +++ b/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart @@ -19,6 +19,7 @@ import 'package:immich_mobile/providers/server_info.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/services/stack.service.dart'; +import 'package:immich_mobile/utils/hash.dart'; import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart'; import 'package:immich_mobile/widgets/asset_grid/delete_dialog.dart'; import 'package:immich_mobile/widgets/asset_viewer/video_controls.dart'; @@ -49,7 +50,8 @@ class BottomGalleryBar extends ConsumerWidget { if (asset == null) { return const SizedBox(); } - final isOwner = asset.ownerId == ref.watch(currentUserProvider)?.id; + final isOwner = + asset.ownerId == fastHash(ref.watch(currentUserProvider)?.id ?? ''); final showControls = ref.watch(showControlsProvider); final stackId = asset.stackId; diff --git a/mobile/lib/widgets/asset_viewer/description_input.dart b/mobile/lib/widgets/asset_viewer/description_input.dart index 844e4744b3..778212eabe 100644 --- a/mobile/lib/widgets/asset_viewer/description_input.dart +++ b/mobile/lib/widgets/asset_viewer/description_input.dart @@ -9,6 +9,7 @@ import 'package:immich_mobile/extensions/theme_extensions.dart'; import 'package:immich_mobile/providers/asset.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/services/asset.service.dart'; +import 'package:immich_mobile/utils/hash.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; import 'package:logging/logging.dart'; @@ -81,7 +82,7 @@ class DescriptionInput extends HookConsumerWidget { } return TextField( - enabled: owner?.id == asset.ownerId, + enabled: fastHash(owner?.id ?? '') == asset.ownerId, focusNode: focusNode, onTap: () => isFocus.value = true, onChanged: (value) { diff --git a/mobile/lib/widgets/asset_viewer/gallery_app_bar.dart b/mobile/lib/widgets/asset_viewer/gallery_app_bar.dart index dcef6c79d4..4354dceb4f 100644 --- a/mobile/lib/widgets/asset_viewer/gallery_app_bar.dart +++ b/mobile/lib/widgets/asset_viewer/gallery_app_bar.dart @@ -16,6 +16,7 @@ import 'package:immich_mobile/providers/tab.provider.dart'; import 'package:immich_mobile/providers/trash.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/routing/router.dart'; +import 'package:immich_mobile/utils/hash.dart'; import 'package:immich_mobile/widgets/album/add_to_album_bottom_sheet.dart'; import 'package:immich_mobile/widgets/asset_grid/upload_dialog.dart'; import 'package:immich_mobile/widgets/asset_viewer/top_control_app_bar.dart'; @@ -33,12 +34,13 @@ class GalleryAppBar extends ConsumerWidget { return const SizedBox(); } final album = ref.watch(currentAlbumProvider); - final isOwner = asset.ownerId == ref.watch(currentUserProvider)?.id; + final isOwner = + asset.ownerId == fastHash(ref.watch(currentUserProvider)?.id ?? ''); final showControls = ref.watch(showControlsProvider); final isPartner = ref .watch(partnerSharedWithProvider) - .map((e) => e.id) + .map((e) => fastHash(e.id)) .contains(asset.ownerId); toggleFavorite(Asset asset) => diff --git a/mobile/lib/widgets/common/user_avatar.dart b/mobile/lib/widgets/common/user_avatar.dart index 753a1f5d37..a5a6fa2bdd 100644 --- a/mobile/lib/widgets/common/user_avatar.dart +++ b/mobile/lib/widgets/common/user_avatar.dart @@ -8,7 +8,7 @@ import 'package:immich_mobile/services/api.service.dart'; Widget userAvatar(BuildContext context, UserDto u, {double? radius}) { final url = - "${Store.get(StoreKey.serverEndpoint)}/users/${u.uid}/profile-image"; + "${Store.get(StoreKey.serverEndpoint)}/users/${u.id}/profile-image"; final nameFirstLetter = u.name.isNotEmpty ? u.name[0] : ""; return CircleAvatar( radius: radius, diff --git a/mobile/lib/widgets/common/user_circle_avatar.dart b/mobile/lib/widgets/common/user_circle_avatar.dart index 4bc7bfa0f4..b3727e8323 100644 --- a/mobile/lib/widgets/common/user_circle_avatar.dart +++ b/mobile/lib/widgets/common/user_circle_avatar.dart @@ -27,7 +27,7 @@ class UserCircleAvatar extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { bool isDarkTheme = context.themeData.brightness == Brightness.dark; final profileImageUrl = - '${Store.get(StoreKey.serverEndpoint)}/users/${user.uid}/profile-image?d=${Random().nextInt(1024)}'; + '${Store.get(StoreKey.serverEndpoint)}/users/${user.id}/profile-image?d=${Random().nextInt(1024)}'; final textIcon = DefaultTextStyle( style: TextStyle( diff --git a/mobile/test/fixtures/user.stub.dart b/mobile/test/fixtures/user.stub.dart index 88b14dc02e..1dfec9b4b1 100644 --- a/mobile/test/fixtures/user.stub.dart +++ b/mobile/test/fixtures/user.stub.dart @@ -4,7 +4,7 @@ abstract final class UserStub { const UserStub._(); static final admin = UserDto( - uid: "admin", + id: "admin", email: "admin@test.com", name: "admin", isAdmin: true, @@ -14,7 +14,7 @@ abstract final class UserStub { ); static final user1 = UserDto( - uid: "user1", + id: "user1", email: "user1@test.com", name: "user1", isAdmin: false, @@ -24,7 +24,7 @@ abstract final class UserStub { ); static final user2 = UserDto( - uid: "user2", + id: "user2", email: "user2@test.com", name: "user2", isAdmin: false, diff --git a/mobile/test/modules/shared/sync_service_test.dart b/mobile/test/modules/shared/sync_service_test.dart index 7594c35fff..0197008dd1 100644 --- a/mobile/test/modules/shared/sync_service_test.dart +++ b/mobile/test/modules/shared/sync_service_test.dart @@ -66,7 +66,7 @@ void main() { final MockUserService userService = MockUserService(); final owner = UserDto( - uid: "1", + id: "1", updatedAt: DateTime.now(), email: "a@b.c", name: "first last", @@ -110,7 +110,7 @@ void main() { ); when(() => userService.getMyUser()).thenReturn(owner); when(() => eTagRepository.get(owner.id)) - .thenAnswer((_) async => ETag(id: owner.uid, time: DateTime.now())); + .thenAnswer((_) async => ETag(id: owner.id, time: DateTime.now())); when(() => eTagRepository.deleteByIds(["1"])).thenAnswer((_) async {}); when(() => eTagRepository.upsertAll(any())).thenAnswer((_) async {}); when(() => partnerRepository.getSharedWith()).thenAnswer((_) async => []); diff --git a/mobile/test/services/album.service_test.dart b/mobile/test/services/album.service_test.dart index 0efd695560..443e37e75d 100644 --- a/mobile/test/services/album.service_test.dart +++ b/mobile/test/services/album.service_test.dart @@ -149,7 +149,7 @@ void main() { () => albumApiRepository.create( "name", assetIds: [AssetStub.image1.remoteId!], - sharedUserIds: [UserStub.user1.uid], + sharedUserIds: [UserStub.user1.id], ), ).called(1); verify( @@ -217,7 +217,7 @@ void main() { final result = await sut.addUsers( AlbumStub.emptyAlbum, - [UserStub.user2.uid], + [UserStub.user2.id], ); expect(result, true); diff --git a/mobile/test/services/entity.service_test.dart b/mobile/test/services/entity.service_test.dart index fd99a4faee..190b2bc2b5 100644 --- a/mobile/test/services/entity.service_test.dart +++ b/mobile/test/services/entity.service_test.dart @@ -41,7 +41,7 @@ void main() { [User.fromDto(UserStub.admin), User.fromDto(UserStub.admin)], ); - when(() => userRepository.get(any())) + when(() => userRepository.getByUserId(any())) .thenAnswer((_) async => UserStub.admin); when(() => userRepository.getByUserId(any())) .thenAnswer((_) async => UserStub.admin);