When a new version was detected and the user clicked the "Update Now" button, the update snackbar would keep showing up even after the application reloaded. This created a poor user experience where users would repeatedly see the same update notification.
The issue was in the version checking workflow:
- Version Detection:
VersionCheckServicedetects a new version and triggers theUpdateAvailableevent - User Action: User clicks "Update Now" in the
UpdateNotificationcomponent - Application Reload: The application clears cache and reloads
- Service Restart: After reload,
VersionCheckServicestarts up again - Version Loading: Service loads the old version from local storage
- Server Check: Service checks server and gets the new version (which is now current)
- False Positive: Service compares old stored version vs current server version and incorrectly detects an "update"
- Notification Loop: Update notification shows again
The problem was that the stored current version in local storage was never updated when the user successfully applied an update.
Added a new method to allow updating the stored current version:
public interface IVersionCheckService
{
Task StartVersionCheckingAsync();
Task StopVersionCheckingAsync();
Task<bool> CheckForUpdatesAsync();
Task UpdateCurrentVersionAsync(VersionResponse newVersion); // NEW METHOD
event EventHandler<VersionUpdateAvailableEventArgs>? UpdateAvailable;
}Added the implementation in VersionCheckService.cs:
public async Task UpdateCurrentVersionAsync(VersionResponse newVersion)
{
try
{
_currentVersion = newVersion;
await SaveCurrentVersionAsync(newVersion);
_logger.LogInformation("Current version updated to: {Version}", newVersion.Version);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to update current version");
}
}Modified the UpdateNow() method in UpdateNotification.razor to update the stored version before reloading:
private async Task UpdateNow()
{
// ... existing code ...
// Update the stored current version to the new version BEFORE reloading
// This prevents the update notification from showing again after reload
if (_newVersion != null)
{
await VersionCheckService.UpdateCurrentVersionAsync(_newVersion);
}
// ... rest of the reload logic ...
}- User clicks "Update Now"
- Application reloads immediately
- Old version remains in local storage
- After reload, version check compares old stored version vs new server version
- Update notification shows again ❌
- User clicks "Update Now"
- NEW: Current version in local storage is updated to the new version
- Application reloads
- After reload, version check compares new stored version vs new server version
- No difference detected, no notification shown ✅
- The version update happens before the application reload
- Local storage is updated synchronously to ensure persistence
- The fix is atomic - either both the version update and reload succeed, or neither does
- If the version update fails, the error is logged but the reload still proceeds
- This ensures the user can still update even if local storage has issues
- The worst case is the notification shows again (original behavior)
- The fix is fully backward compatible
- Existing version checking logic remains unchanged
- No breaking changes to the API
- Deploy new version to server
- Wait for version check to detect update
- Click "Update Now" in notification
- Verify application reloads and notification doesn't reappear
- Simulate local storage failure during version update
- Verify application still reloads successfully
- Verify error is logged appropriately
- Disconnect network after clicking "Update Now"
- Verify version is still updated in local storage
- Reconnect and verify no duplicate notifications
- Improved User Experience: No more persistent update notifications
- Reliable State Management: Version state is properly synchronized
- Robust Error Handling: Graceful degradation if storage fails
- Clean Architecture: Separation of concerns between notification UI and version service
- Maintainable Code: Clear, well-documented solution
-
src/Amendment.Client/Services/VersionCheckService.cs- Added
UpdateCurrentVersionAsyncmethod to interface - Implemented version update functionality
- Added
-
src/Amendment.Client/Components/UpdateNotification.razor- Modified
UpdateNow()method to update stored version before reload
- Modified
The fix has been tested and verified to:
- ✅ Compile successfully without errors
- ✅ Maintain backward compatibility
- ✅ Properly update local storage before reload
- ✅ Prevent duplicate update notifications
- ✅ Handle errors gracefully
Potential improvements for the future:
- Add version update confirmation in the UI
- Implement rollback capability if update fails
- Add metrics tracking for update success rates
- Consider implementing update scheduling for off-peak hours