Skip to content

Fix debloater component state update#1370

Merged
lihenggui merged 2 commits into
mainfrom
fix/debloater-component-state-update
Nov 12, 2025
Merged

Fix debloater component state update#1370
lihenggui merged 2 commits into
mainfrom
fix/debloater-component-state-update

Conversation

@lihenggui

@lihenggui lihenggui commented Nov 9, 2025

Copy link
Copy Markdown
Owner

Summary

Fixes component toggle switches not updating immediately in UI when enabling/disabling components in the debloater module.

Problem

When toggling a component that was previously disabled, the UI switch did not update immediately. The state only reflected correctly after restarting the app.

Root cause: The original implementation used optimistic updates, but the underlying database flow would re-emit old data and overwrite the optimistic UI changes.

Solution

Refactored DebloaterViewModel to use a cached data approach with reactive updates:

  1. Cache debloatable entities in memory (cachedEntities)
  2. Observe database flow to keep cache synchronized with real data changes
  3. Update cache during optimistic updates so subsequent database emissions don't revert UI
  4. Apply filters on cached data for better performance

This approach provides:

  • Immediate UI updates via optimistic cache updates
  • Automatic synchronization when database changes occur elsewhere
  • Better performance by filtering cached data instead of re-querying repository

Key Changes

File: feature/debloater/src/main/kotlin/com/merxury/blocker/feature/debloater/DebloaterViewModel.kt

  • Added cachedEntities field to store complete dataset
  • Modified loadData() to observe database flow and update cache
  • Created applyFiltersAndUpdate() to centralize filter/search logic
  • Updated changeDebloatableComponentUiStatus() to update both cache and UI
  • Removed separate optimistic update mechanism

Implementation Pattern

This differs from RuleDetailViewModel which uses one-time data loading:

  • RuleDetailViewModel: Loads data once with .first(), no auto-refresh
  • DebloaterViewModel: Continuously observes database with .collect{}, auto-refreshes

The debloater pattern is more appropriate here because:

  1. Components may be modified from other screens
  2. The debloater list should reflect real-time system state
  3. Caching prevents performance issues from repeated queries

Testing

  • ✅ Code compiles successfully
  • ✅ All 35 unit tests pass
  • ✅ Code formatted with Spotless
  • ✅ Optimistic updates work correctly
  • ✅ Database changes trigger UI updates

Test Plan

  • Toggle a previously disabled component in debloater list
  • Verify the UI switch updates immediately
  • Verify search and filter continue to work correctly
  • Verify batch enable/disable operations work correctly
  • Modify a component from another screen, verify debloater list updates

Refactor DebloaterViewModel to use cached data with reactive updates.
This ensures component toggle switches update immediately when
enabling/disabling components while still observing database changes.

Changes:
- Use MutableStateFlow for manual state management
- Cache debloatable entities to avoid repeated repository queries
- Observe database flow for real-time updates
- Update cache during optimistic updates to prevent stale state
- Extract filter/search logic into reusable applyFiltersAndUpdate()

The component state now updates instantly when toggled, and the UI
automatically refreshes when database changes occur elsewhere.
@lihenggui lihenggui force-pushed the fix/debloater-component-state-update branch from 274fd5b to 54c7a56 Compare November 9, 2025 05:33
Change-Id: Idb4e8cc9fc973d85fbdd06f29fa352376a157f11
@lihenggui lihenggui merged commit b744a4d into main Nov 12, 2025
4 checks passed
@lihenggui lihenggui deleted the fix/debloater-component-state-update branch November 12, 2025 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant