mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
refactor: user entity (#16655)
* refactor: user entity * fix: add users to album & user profile url * chore: rebase fixes * generate files * fix(mobile): timeline not reset on login * fix: test stub * refactor: rename user model (#16813) * refactor: rename user model * simplify import --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex <alex.tran1502@gmail.com> * chore: generate files * fix: use getAllAccessible instead of getAll --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
a75718ce99
commit
d1c8fe5303
82 changed files with 1039 additions and 947 deletions
|
|
@ -2,11 +2,11 @@ import 'dart:async';
|
|||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/constants/enums.dart';
|
||||
import 'package:immich_mobile/entities/user.entity.dart';
|
||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||
import 'package:immich_mobile/entities/album.entity.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
import 'package:immich_mobile/models/albums/album_search.model.dart';
|
||||
import 'package:immich_mobile/services/album.service.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
import 'package:immich_mobile/entities/album.entity.dart';
|
||||
|
||||
final isRefreshingRemoteAlbumProvider = StateProvider<bool>((ref) => false);
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ class AlbumNotifier extends StateNotifier<List<Album>> {
|
|||
await albumService.addUsers(album, userIds);
|
||||
}
|
||||
|
||||
Future<bool> removeUser(Album album, User user) async {
|
||||
Future<bool> removeUser(Album album, UserDto user) async {
|
||||
final isRemoved = await albumService.removeUser(album, user);
|
||||
|
||||
if (isRemoved && album.sharedUsers.isEmpty) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/entities/user.entity.dart';
|
||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
import 'package:immich_mobile/services/user.service.dart';
|
||||
|
||||
final otherUsersProvider = FutureProvider.autoDispose<List<User>>((ref) {
|
||||
final otherUsersProvider =
|
||||
FutureProvider.autoDispose<List<UserDto>>((ref) async {
|
||||
UserService userService = ref.watch(userServiceProvider);
|
||||
final currentUser = ref.watch(currentUserProvider);
|
||||
|
||||
return userService.getUsers();
|
||||
final allUsers = await userService.getAll();
|
||||
allUsers.removeWhere((u) => currentUser?.id == u.id);
|
||||
return allUsers;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter_udid/flutter_udid.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||
import 'package:immich_mobile/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/entities/user.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/utils/user.converter.dart';
|
||||
import 'package:immich_mobile/models/auth/auth_state.model.dart';
|
||||
import 'package:immich_mobile/models/auth/login_response.model.dart';
|
||||
import 'package:immich_mobile/providers/api.provider.dart';
|
||||
|
|
@ -105,7 +106,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||
String deviceId =
|
||||
Store.tryGet(StoreKey.deviceId) ?? await FlutterUdid.consistentUdid;
|
||||
|
||||
User? user = Store.tryGet(StoreKey.currentUser);
|
||||
UserDto? user = Store.tryGet(StoreKey.currentUser);
|
||||
|
||||
UserAdminResponseDto? userResponse;
|
||||
UserPreferencesResponseDto? userPreferences;
|
||||
|
|
@ -141,18 +142,18 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||
|
||||
// If the user information is successfully retrieved, update the store
|
||||
// Due to the flow of the code, this will always happen on first login
|
||||
if (userResponse != null) {
|
||||
if (userResponse == null) {
|
||||
_log.severe("Unable to get user information from the server.");
|
||||
} else {
|
||||
await Store.put(StoreKey.deviceId, deviceId);
|
||||
await Store.put(StoreKey.deviceIdHash, fastHash(deviceId));
|
||||
await Store.put(
|
||||
StoreKey.currentUser,
|
||||
User.fromUserDto(userResponse, userPreferences),
|
||||
UserConverter.fromAdminDto(userResponse, userPreferences),
|
||||
);
|
||||
await Store.put(StoreKey.accessToken, accessToken);
|
||||
|
||||
user = User.fromUserDto(userResponse, userPreferences);
|
||||
} else {
|
||||
_log.severe("Unable to get user information from the server.");
|
||||
user = UserConverter.fromAdminDto(userResponse, userPreferences);
|
||||
}
|
||||
|
||||
// If the user is null, the login was not successful
|
||||
|
|
@ -163,7 +164,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||
|
||||
state = state.copyWith(
|
||||
isAuthenticated: true,
|
||||
userId: user.id,
|
||||
userId: user.uid,
|
||||
userEmail: user.email,
|
||||
name: user.name,
|
||||
profileImagePath: user.profileImagePath,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
|
||||
import 'package:immich_mobile/domain/services/store.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'store.provider.g.dart';
|
||||
|
||||
@riverpod
|
||||
@Riverpod(keepAlive: true)
|
||||
IStoreRepository storeRepository(Ref ref) =>
|
||||
IsarStoreRepository(ref.watch(isarProvider));
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
StoreService storeService(Ref _) => StoreService.I;
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ part of 'store.provider.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$storeRepositoryHash() => r'9f378b96e552151fa14a8c8ce2c30a5f38f436ed';
|
||||
String _$storeRepositoryHash() => r'99d24875d30c5e86b1c6caa352a0026167114e62';
|
||||
|
||||
/// See also [storeRepository].
|
||||
@ProviderFor(storeRepository)
|
||||
final storeRepositoryProvider = AutoDisposeProvider<IStoreRepository>.internal(
|
||||
final storeRepositoryProvider = Provider<IStoreRepository>.internal(
|
||||
storeRepository,
|
||||
name: r'storeRepositoryProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
|
|
@ -22,6 +22,22 @@ final storeRepositoryProvider = AutoDisposeProvider<IStoreRepository>.internal(
|
|||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
typedef StoreRepositoryRef = AutoDisposeProviderRef<IStoreRepository>;
|
||||
typedef StoreRepositoryRef = ProviderRef<IStoreRepository>;
|
||||
String _$storeServiceHash() => r'250e10497c42df360e9e1f9a618d0b19c1b5b0a0';
|
||||
|
||||
/// See also [storeService].
|
||||
@ProviderFor(storeService)
|
||||
final storeServiceProvider = Provider<StoreService>.internal(
|
||||
storeService,
|
||||
name: r'storeServiceProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$storeServiceHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
typedef StoreServiceRef = ProviderRef<StoreService>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
|
|
|||
11
mobile/lib/providers/infrastructure/user.provider.dart
Normal file
11
mobile/lib/providers/infrastructure/user.provider.dart
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/interfaces/user.interface.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'user.provider.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
IUserRepository userRepository(Ref ref) =>
|
||||
IsarUserRepository(ref.watch(isarProvider));
|
||||
27
mobile/lib/providers/infrastructure/user.provider.g.dart
generated
Normal file
27
mobile/lib/providers/infrastructure/user.provider.g.dart
generated
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'user.provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$userRepositoryHash() => r'1a2ac726bcc44397dcaecf449084fefd336696d4';
|
||||
|
||||
/// See also [userRepository].
|
||||
@ProviderFor(userRepository)
|
||||
final userRepositoryProvider = Provider<IUserRepository>.internal(
|
||||
userRepository,
|
||||
name: r'userRepositoryProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$userRepositoryHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
typedef UserRepositoryRef = ProviderRef<IUserRepository>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
|
@ -2,16 +2,16 @@ import 'dart:async';
|
|||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||
import 'package:immich_mobile/providers/album/suggested_shared_users.provider.dart';
|
||||
import 'package:immich_mobile/services/partner.service.dart';
|
||||
import 'package:immich_mobile/entities/user.entity.dart';
|
||||
|
||||
class PartnerSharedWithNotifier extends StateNotifier<List<User>> {
|
||||
class PartnerSharedWithNotifier extends StateNotifier<List<UserDto>> {
|
||||
final PartnerService _partnerService;
|
||||
late final StreamSubscription<List<User>> streamSub;
|
||||
late final StreamSubscription<List<UserDto>> streamSub;
|
||||
|
||||
PartnerSharedWithNotifier(this._partnerService) : super([]) {
|
||||
Function eq = const ListEquality<User>().equals;
|
||||
Function eq = const ListEquality<UserDto>().equals;
|
||||
_partnerService.getSharedWith().then((partners) {
|
||||
if (!eq(state, partners)) {
|
||||
state = partners;
|
||||
|
|
@ -25,7 +25,7 @@ class PartnerSharedWithNotifier extends StateNotifier<List<User>> {
|
|||
});
|
||||
}
|
||||
|
||||
Future<bool> updatePartner(User partner, {required bool inTimeline}) {
|
||||
Future<bool> updatePartner(UserDto partner, {required bool inTimeline}) {
|
||||
return _partnerService.updatePartner(partner, inTimeline: inTimeline);
|
||||
}
|
||||
|
||||
|
|
@ -39,18 +39,18 @@ class PartnerSharedWithNotifier extends StateNotifier<List<User>> {
|
|||
}
|
||||
|
||||
final partnerSharedWithProvider =
|
||||
StateNotifierProvider<PartnerSharedWithNotifier, List<User>>((ref) {
|
||||
StateNotifierProvider<PartnerSharedWithNotifier, List<UserDto>>((ref) {
|
||||
return PartnerSharedWithNotifier(
|
||||
ref.watch(partnerServiceProvider),
|
||||
);
|
||||
});
|
||||
|
||||
class PartnerSharedByNotifier extends StateNotifier<List<User>> {
|
||||
class PartnerSharedByNotifier extends StateNotifier<List<UserDto>> {
|
||||
final PartnerService _partnerService;
|
||||
late final StreamSubscription<List<User>> streamSub;
|
||||
late final StreamSubscription<List<UserDto>> streamSub;
|
||||
|
||||
PartnerSharedByNotifier(this._partnerService) : super([]) {
|
||||
Function eq = const ListEquality<User>().equals;
|
||||
Function eq = const ListEquality<UserDto>().equals;
|
||||
_partnerService.getSharedBy().then((partners) {
|
||||
if (!eq(state, partners)) {
|
||||
state = partners;
|
||||
|
|
@ -74,15 +74,15 @@ class PartnerSharedByNotifier extends StateNotifier<List<User>> {
|
|||
}
|
||||
|
||||
final partnerSharedByProvider =
|
||||
StateNotifierProvider<PartnerSharedByNotifier, List<User>>((ref) {
|
||||
StateNotifierProvider<PartnerSharedByNotifier, List<UserDto>>((ref) {
|
||||
return PartnerSharedByNotifier(ref.watch(partnerServiceProvider));
|
||||
});
|
||||
|
||||
final partnerAvailableProvider =
|
||||
FutureProvider.autoDispose<List<User>>((ref) async {
|
||||
FutureProvider.autoDispose<List<UserDto>>((ref) async {
|
||||
final otherUsers = await ref.watch(otherUsersProvider.future);
|
||||
final currentPartners = ref.watch(partnerSharedByProvider);
|
||||
final available = Set<User>.of(otherUsers);
|
||||
final available = Set<UserDto>.of(otherUsers);
|
||||
available.removeAll(currentPartners);
|
||||
return available.toList();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ import 'dart:async';
|
|||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||
import 'package:immich_mobile/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/entities/user.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/utils/user.converter.dart';
|
||||
import 'package:immich_mobile/providers/api.provider.dart';
|
||||
import 'package:immich_mobile/services/api.service.dart';
|
||||
import 'package:immich_mobile/services/timeline.service.dart';
|
||||
|
||||
class CurrentUserProvider extends StateNotifier<User?> {
|
||||
class CurrentUserProvider extends StateNotifier<UserDto?> {
|
||||
CurrentUserProvider(this._apiService) : super(null) {
|
||||
state = Store.tryGet(StoreKey.currentUser);
|
||||
streamSub =
|
||||
|
|
@ -16,7 +17,7 @@ class CurrentUserProvider extends StateNotifier<User?> {
|
|||
}
|
||||
|
||||
final ApiService _apiService;
|
||||
late final StreamSubscription<User?> streamSub;
|
||||
late final StreamSubscription<UserDto?> streamSub;
|
||||
|
||||
refresh() async {
|
||||
try {
|
||||
|
|
@ -25,7 +26,7 @@ class CurrentUserProvider extends StateNotifier<User?> {
|
|||
if (user != null) {
|
||||
await Store.put(
|
||||
StoreKey.currentUser,
|
||||
User.fromUserDto(user, userPreferences),
|
||||
UserConverter.fromAdminDto(user, userPreferences),
|
||||
);
|
||||
}
|
||||
} catch (_) {}
|
||||
|
|
@ -39,7 +40,7 @@ class CurrentUserProvider extends StateNotifier<User?> {
|
|||
}
|
||||
|
||||
final currentUserProvider =
|
||||
StateNotifierProvider<CurrentUserProvider, User?>((ref) {
|
||||
StateNotifierProvider<CurrentUserProvider, UserDto?>((ref) {
|
||||
return CurrentUserProvider(
|
||||
ref.watch(apiServiceProvider),
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue