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>
This commit is contained in:
shenlong
2025-03-18 21:35:37 +05:30
committed by GitHub
parent e96ffd43e7
commit 9cf3b88f80
38 changed files with 182 additions and 157 deletions

View File

@@ -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<bool> 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));

View File

@@ -101,7 +101,7 @@ class AssetService {
_getRemoteAssetChanges(List<UserDto> 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<AssetResponseDto>? assets =

View File

@@ -46,10 +46,10 @@ class PartnerService {
Future<bool> 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<bool> 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;
}

View File

@@ -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<bool> _syncUsersFromServer(List<UserDto> users) async {
users.sortBy((u) => u.uid);
users.sortBy((u) => u.id);
final dbUsers = await _userRepository.getAll(sortBy: SortUserBy.id);
final List<int> toDelete = [];
final List<String> toDelete = [];
final List<UserDto> 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<void> _updateUserAssetsETag(List<UserDto> 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<void> _clearUserAssetsETag(List<UserDto> 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 = <UserDto>[];
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),

View File

@@ -28,21 +28,21 @@ class TimelineService {
this._userService,
);
Future<List<int>> getTimelineUserIds() async {
Future<List<String>> getTimelineUserIds() async {
final me = _userService.getMyUser();
return _timelineRepository.getTimelineUserIds(me.id);
}
Stream<List<int>> watchTimelineUserIds() async* {
Stream<List<String>> watchTimelineUserIds() async* {
final me = _userService.getMyUser();
yield* _timelineRepository.watchTimelineUsers(me.id);
}
Stream<RenderList> watchHomeTimeline(int userId) {
Stream<RenderList> watchHomeTimeline(String userId) {
return _timelineRepository.watchHomeTimeline(userId, _getGroupByOption());
}
Stream<RenderList> watchMultiUsersTimeline(List<int> userIds) {
Stream<RenderList> watchMultiUsersTimeline(List<String> 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(