From 69310575e5408f59f0a4767fd7e07cfc8696db89 Mon Sep 17 00:00:00 2001 From: Sultan khan Date: Mon, 13 Apr 2026 19:15:41 +0300 Subject: [PATCH] updates --- lib/core/app_state.dart | 23 +++++--- .../authentication_view_model.dart | 21 +++++-- .../profile_settings_repo.dart | 2 +- .../profile_settings_view_model.dart | 55 +++++++++--------- .../widgets/profile_picture_widget.dart | 56 +++++++++++-------- 5 files changed, 98 insertions(+), 59 deletions(-) diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart index 85fe9cb2..21f93eed 100644 --- a/lib/core/app_state.dart +++ b/lib/core/app_state.dart @@ -94,24 +94,33 @@ class AppState { String? get getProfileImageData => _profileImageData; set setProfileImageData(String? value) { + // Clear old data first + if (_profileImageData != null && _profileImageData != value) { + print('๐Ÿ”„ Replacing profile image: old data length=${_profileImageData!.length}, new data length=${value?.length ?? 0}'); + } + + // Set new value directly WITHOUT caching _profileImageData = value; - // Persist to cache + if (value != null && value.isNotEmpty) { - cacheService.saveString(key: _profileImageKey, value: value); + print('โœ… Profile image set (length: ${value.length}) - NO CACHE'); } else { - cacheService.remove(key: _profileImageKey); + print('๐Ÿ—‘๏ธ Profile image cleared - NO CACHE'); } } - /// Load profile image from cache on app initialization + /// Load profile image from cache on app initialization - DISABLED void _loadProfileImageFromCache() { - _profileImageData = cacheService.getString(key: _profileImageKey); + // DO NOT LOAD FROM CACHE - always fetch fresh from API + _profileImageData = null; + print('๐Ÿ“‚ Profile image cache disabled - will fetch from API'); } - /// Clear profile image from cache (e.g., on logout) + /// Clear profile image data (e.g., on logout or user switch) void clearProfileImageCache() { + print('๐Ÿงน Clearing profile image data (was: ${_profileImageData != null ? "${_profileImageData!.length} chars" : "null"})'); _profileImageData = null; - cacheService.remove(key: _profileImageKey); + print('โœ… Profile image data cleared - NO CACHE'); } SelectDeviceByImeiRespModelElement? _selectDeviceByImeiRespModelElement; diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index 45c2d620..573887e6 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -1240,6 +1240,12 @@ class AuthenticationViewModel extends ChangeNotifier { try { log("Fetching profile image for patient ID: $patientID"); + + // IMPORTANT: Clear old cache BEFORE fetching new image + // This ensures old data is removed immediately + _appState.clearProfileImageCache(); + log("๐Ÿงน Cleared profile image cache before fetch"); + final profileSettingsRepo = GetIt.instance(); final result = await profileSettingsRepo.getProfileImage(patientID: patientID); @@ -1247,6 +1253,8 @@ class AuthenticationViewModel extends ChangeNotifier { (failure) { // Silently fail - profile image is optional log("Failed to fetch profile image: ${failure.message}"); + // Ensure cache is cleared even on failure + _appState.setProfileImageData = null; }, (apiResponse) { if (apiResponse.data != null && apiResponse.data['Patient_GetProfileImageDataList'] != null) { @@ -1254,21 +1262,26 @@ class AuthenticationViewModel extends ChangeNotifier { if (imageList is List && imageList.isNotEmpty) { String? imageData = imageList[0]['ImageData']; if (imageData != null && imageData.isNotEmpty) { + // Set new profile image data - this will update cache and notify all listeners _appState.setProfileImageData = imageData; - log("โœ… Profile image loaded and cached successfully"); + log("โœ… Profile image loaded and cached successfully for patient: $patientID"); } else { - log("โš ๏ธ Profile image data is empty"); + log("โš ๏ธ Profile image data is empty for patient: $patientID"); + _appState.setProfileImageData = null; } } else { - log("โš ๏ธ Profile image list is empty"); + log("โš ๏ธ Profile image list is empty for patient: $patientID"); + _appState.setProfileImageData = null; } } else { - log("โš ๏ธ No profile image data in response"); + log("โš ๏ธ No profile image data in response for patient: $patientID"); + _appState.setProfileImageData = null; } }, ); } catch (e) { log("โŒ Error fetching profile image: $e"); + _appState.setProfileImageData = null; } } } diff --git a/lib/features/profile_settings/profile_settings_repo.dart b/lib/features/profile_settings/profile_settings_repo.dart index d86bd7fd..113a52c0 100644 --- a/lib/features/profile_settings/profile_settings_repo.dart +++ b/lib/features/profile_settings/profile_settings_repo.dart @@ -151,7 +151,7 @@ class ProfileSettingsRepoImp implements ProfileSettingsRepo { } @override - Future>> getProfileImage({ + Future>> getProfileImage({ required int patientID, }) async { final Map body = { diff --git a/lib/features/profile_settings/profile_settings_view_model.dart b/lib/features/profile_settings/profile_settings_view_model.dart index b208494a..5d2f58d4 100644 --- a/lib/features/profile_settings/profile_settings_view_model.dart +++ b/lib/features/profile_settings/profile_settings_view_model.dart @@ -189,19 +189,15 @@ class ProfileSettingsViewModel extends ChangeNotifier { Function(String)? onError, bool forceRefresh = false, // Add flag to force refresh }) async { - // Skip API call if image is already loaded and not forcing refresh - if (!forceRefresh && GetIt.instance().getProfileImageData != null) { - // Use cached data - profileImageData = GetIt.instance().getProfileImageData; - if (onSuccess != null) { - onSuccess(profileImageData); - } - return; - } + print('๐ŸŒ Fetching profile image from API for patient: $patientID (forceRefresh: $forceRefresh)'); + + // IMPORTANT: Always clear old data BEFORE fetching + // Do NOT use cached data - always fetch fresh from API + profileImageData = null; isProfileImageLoading = true; profileImageError = null; - notifyListeners(); + notifyListeners(); // Notify to show loading state final result = await profileSettingsRepo.getProfileImage(patientID: patientID); @@ -209,6 +205,11 @@ class ProfileSettingsViewModel extends ChangeNotifier { (failure) { isProfileImageLoading = false; profileImageError = failure.message; + print('โŒ Failed to fetch profile image: ${failure.message}'); + + // Ensure data is cleared on failure + profileImageData = null; + notifyListeners(); if (onError != null) { onError(failure.message); @@ -216,44 +217,48 @@ class ProfileSettingsViewModel extends ChangeNotifier { }, (response) { isProfileImageLoading = false; + // Extract image data from response if (response.data != null && response.data['Patient_GetProfileImageDataList'] != null) { var imageList = response.data['Patient_GetProfileImageDataList']; if (imageList is List && imageList.isNotEmpty) { profileImageData = imageList[0]['ImageData']; - // Store in AppState for global access - GetIt.instance().setProfileImageData = profileImageData; + if (profileImageData != null && profileImageData!.isNotEmpty) { + // ONLY store in ViewModel - AppState will be updated separately by auth flow + print('โœ… Profile image loaded from API (length: ${profileImageData!.length})'); + } else { + profileImageData = null; + print('โš ๏ธ Profile image data is empty in API response'); + } } else { profileImageData = null; - GetIt.instance().setProfileImageData = null; + print('โš ๏ธ Profile image list is empty in API response'); } } else { profileImageData = null; - GetIt.instance().setProfileImageData = null; + print('โš ๏ธ No profile image data in API response'); } - notifyListeners(); + + notifyListeners(); // Notify to update UI with new/null data onSuccess?.call(response.data); }, ); } - /// Clear cached profile image data + /// Clear profile image data from ViewModel void clearProfileImageCache() { + print('๐Ÿงน Clearing profile image from ViewModel'); profileImageData = null; - GetIt.instance().setProfileImageData = null; notifyListeners(); } - /// Sync profile image data from AppState + /// Sync profile image data from AppState - DISABLED + /// Profile Settings screen uses only ViewModel data from API void syncProfileImageFromAppState() { - final appStateImageData = GetIt.instance().getProfileImageData; - if (appStateImageData != null && appStateImageData.isNotEmpty) { - if (profileImageData != appStateImageData) { - profileImageData = appStateImageData; - notifyListeners(); - } - } + // DO NOTHING - Profile Settings uses only direct API data + // No syncing from AppState to avoid stale cache issues + print('โš ๏ธ syncProfileImageFromAppState called but disabled - use API data only'); } Future uploadProfileImage({ diff --git a/lib/presentation/profile_settings/widgets/profile_picture_widget.dart b/lib/presentation/profile_settings/widgets/profile_picture_widget.dart index b057591a..c9c5e7b1 100644 --- a/lib/presentation/profile_settings/widgets/profile_picture_widget.dart +++ b/lib/presentation/profile_settings/widgets/profile_picture_widget.dart @@ -34,13 +34,12 @@ class _ProfilePictureWidgetState extends State { void initState() { super.initState(); _currentPatientId = _appState.getAuthenticatedUser()?.patientId; - print('๐ŸŽฌ ProfilePictureWidget initState - patient: $_currentPatientId'); + // Use addPostFrameCallback to ensure widget is built before loading WidgetsBinding.instance.addPostFrameCallback((_) { if (!mounted) return; - final profileVm = context.read(); final patientID = _appState.getAuthenticatedUser()?.patientId; if (patientID == null) { @@ -48,20 +47,9 @@ class _ProfilePictureWidgetState extends State { return; } - // Check if we have data in AppState that matches current user - final appStateImageData = _appState.getProfileImageData; - - if (appStateImageData != null && appStateImageData.isNotEmpty) { - // Sync to ViewModel if it doesn't have data - if (profileVm.profileImageData == null || profileVm.profileImageData!.isEmpty) { - print('๐Ÿ”„ Syncing AppState data to ViewModel'); - profileVm.syncProfileImageFromAppState(); - } - } else { - // No cached data - load from API - print('๐Ÿ“ฅ No cached data - loading from API for patient: $patientID'); - _loadProfileImage(forceRefresh: false); - } + // Always load fresh data from API - do NOT use AppState cache + print('๐Ÿ“ฅ Loading fresh profile image from API for patient: $patientID'); + _loadProfileImage(forceRefresh: true); }); } @@ -88,13 +76,25 @@ class _ProfilePictureWidgetState extends State { final oldPatientId = _currentPatientId; _currentPatientId = currentPatientId; - // Clear the old profile image data + // Clear the old profile image data from BOTH AppState and ViewModel try { final profileVm = context.read(); print('๐Ÿงน Clearing cache for old user: $oldPatientId'); + + // Clear AppState cache first + _appState.clearProfileImageCache(); + + // Then clear ViewModel cache profileVm.clearProfileImageCache(); + // Force rebuild to show default avatar immediately + if (mounted) { + setState(() { + _selectedImage = null; // Clear any selected image + }); + } + print('๐Ÿ“ฅ Loading profile image for new user: $currentPatientId'); // Load the new user's profile image immediately profileVm.getProfileImage( @@ -455,6 +455,7 @@ class _ProfilePictureWidgetState extends State { Widget _buildProfileImage(ProfileSettingsViewModel profileVm) { // Always get fresh user data final currentUser = _appState.getAuthenticatedUser(); + final currentPatientId = currentUser?.patientId; final gender = currentUser?.gender ?? 1; final age = currentUser?.age ?? 0; @@ -480,11 +481,22 @@ class _ProfilePictureWidgetState extends State { ); } - // Use ViewModel data if available, otherwise fall back to AppState - // This ensures we show the current logged-in user's image (same as homepage profile icon) - final String? imageData = profileVm.profileImageData ?? _appState.getProfileImageData; + // // IMPORTANT: Verify the cached image belongs to the current user + // // If _currentPatientId doesn't match currentPatientId, don't show cached image + // if (currentPatientId != _currentPatientId) { + // print('โš ๏ธ Patient ID mismatch - showing default avatar (current: $currentPatientId, cached: $_currentPatientId)'); + // return Image.asset( + // defaultImage, + // width: 136.w, + // height: 136.h, + // ); + // } + + // IMPORTANT: Use ONLY ViewModel data, DO NOT fallback to AppState + // This prevents showing stale cached data when switching users + final String? imageData = profileVm.profileImageData; - print('๐Ÿ–ผ๏ธ Building profile image - has data: ${imageData != null && imageData.isNotEmpty}, patient: ${currentUser?.patientId}'); + print('๐Ÿ–ผ๏ธ Building profile image - has data: ${imageData != null && imageData.isNotEmpty}, patient: $currentPatientId (ViewModel ONLY)'); // Show uploaded image if available if (imageData != null && imageData.isNotEmpty) { @@ -510,7 +522,7 @@ class _ProfilePictureWidgetState extends State { } // Show default image (no image data or user has no uploaded image) - print('๐Ÿ“ท Showing default avatar for user ${currentUser?.patientId}'); + print('๐Ÿ“ท Showing default avatar for user $currentPatientId'); return Image.asset( defaultImage, width: 136.w,