Files
iiEsaywebUIapp/lib/features/auth/providers/unified_auth_providers.dart
cogwheel0 37ebe46e15 refactor: optimize providers with keepAlive for improved state management
- Updated multiple providers to use `@Riverpod(keepAlive: true)` for better state retention throughout the app lifecycle.
- Enhanced `SocketConnectionStream` and `ConversationDeltaStream` with comments clarifying the purpose of public getters.
- Improved error handling in the `_ChatPageState` by ensuring proper checks for mounted state before using context.
- Added comments to clarify the rationale behind keepAlive usage in various providers, ensuring better maintainability and understanding of the codebase.
2025-09-30 23:18:06 +05:30

142 lines
4.3 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/auth/auth_state_manager.dart';
import '../../../core/models/user.dart';
import '../../../core/providers/app_providers.dart';
/// Unified auth providers using the new auth state manager
/// These replace the old auth providers for better efficiency
/// Imperative auth actions wrapper to avoid side-effects during provider build
class AuthActions {
final Ref _ref;
AuthActions(this._ref);
AuthStateManager get _auth => _ref.read(authStateManagerProvider.notifier);
Future<bool> login(
String username,
String password, {
bool rememberCredentials = false,
}) {
return _auth.login(
username,
password,
rememberCredentials: rememberCredentials,
);
}
Future<bool> loginWithApiKey(
String apiKey, {
bool rememberCredentials = false,
}) {
return _auth.loginWithApiKey(
apiKey,
rememberCredentials: rememberCredentials,
);
}
Future<bool> silentLogin() {
return _auth.silentLogin();
}
Future<void> logout() {
return _auth.logout();
}
Future<void> refresh() {
return _auth.refresh();
}
}
final authActionsProvider = Provider<AuthActions>((ref) => AuthActions(ref));
// Legacy action providers have been replaced by `authActionsProvider`
/// Check if saved credentials exist
final hasSavedCredentialsProvider2 = FutureProvider<bool>((ref) async {
final authManager = ref.read(authStateManagerProvider.notifier);
return await authManager.hasSavedCredentials();
});
/// Computed providers for UI consumption
/// These automatically update when auth state changes
/// These are keepAlive since they derive from keepAlive authStateManagerProvider
/// and are used throughout the app lifecycle
final isAuthenticatedProvider2 = Provider<bool>((ref) {
final authState = ref.watch(authStateManagerProvider);
return authState.maybeWhen(
data: (state) => state.isAuthenticated,
orElse: () => false,
);
});
final authTokenProvider3 = Provider<String?>((ref) {
final authState = ref.watch(authStateManagerProvider);
return authState.maybeWhen(data: (state) => state.token, orElse: () => null);
});
final currentUserProvider2 = Provider<User?>((ref) {
final authState = ref.watch(authStateManagerProvider);
return authState.maybeWhen(data: (state) => state.user, orElse: () => null);
});
final authErrorProvider3 = Provider<String?>((ref) {
final authState = ref.watch(authStateManagerProvider);
return authState.maybeWhen(data: (state) => state.error, orElse: () => null);
});
final isAuthLoadingProvider2 = Provider<bool>((ref) {
final authState = ref.watch(authStateManagerProvider);
if (authState.isLoading) return true;
return authState.maybeWhen(
data: (state) => state.isLoading,
orElse: () => false,
);
});
final authStatusProvider = Provider<AuthStatus>((ref) {
final authState = ref.watch(authStateManagerProvider);
return authState.maybeWhen(
data: (state) => state.status,
orElse: () => AuthStatus.loading,
);
});
// Use `ref.read(authActionsProvider).refresh()` instead of refresh providers
/// Provider to watch for auth state changes and update API service
final authApiIntegrationProvider = Provider<void>((ref) {
ref.listen(authTokenProvider3, (previous, next) {
final api = ref.read(apiServiceProvider);
if (api != null && next != null && next.isNotEmpty) {
api.updateAuthToken(next);
}
});
});
/// Navigation helper provider - determines where user should go
final authNavigationStateProvider = Provider<AuthNavigationState>((ref) {
final authState = ref.watch(authStateManagerProvider);
return authState.when(
data: (state) {
switch (state.status) {
case AuthStatus.initial:
case AuthStatus.loading:
return AuthNavigationState.loading;
case AuthStatus.authenticated:
return AuthNavigationState.authenticated;
case AuthStatus.unauthenticated:
case AuthStatus.tokenExpired:
return AuthNavigationState.needsLogin;
case AuthStatus.error:
return AuthNavigationState.error;
}
},
loading: () => AuthNavigationState.loading,
error: (_, stack) => AuthNavigationState.error,
);
});
enum AuthNavigationState { loading, authenticated, needsLogin, error }