Skip to content

Conversation

@kodjima33
Copy link
Collaborator

Persist task indent levels across app restarts to ensure indentation state is restored.


Open in Cursor Open in Web

- Add taskIndentLevels getter/setter to SharedPreferencesUtil for persistence
- Load saved indent levels on ActionItemsPage init
- Save indent levels when user swipes to indent/unindent tasks
- Follows existing pattern for taskCategoryOrder and taskGoalLinks

Fixes task indentation state not persisting after app restart

Co-authored-by: Nik Shevchenko <kodjima33@users.noreply.github.com>
@cursor
Copy link

cursor bot commented Feb 9, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds persistence for task indentation levels, which is a great enhancement for user experience. The implementation correctly uses SharedPreferences to store and retrieve the indent levels. However, I've identified a high-severity issue where the indent level for a deleted task is not removed from storage, leading to an accumulation of stale data over time. My review includes a detailed comment on how to address this data leak.

Comment on lines +153 to +155
void _saveTaskIndentLevels() {
SharedPreferencesUtil().taskIndentLevels = Map<String, int>.from(_indentLevels);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current implementation persists indent levels but doesn't handle cleaning up this data when a task is deleted. This will lead to stale data for deleted tasks accumulating in SharedPreferences over time.

To fix this, you should ensure that when a task is deleted, its corresponding entry in _indentLevels is also removed and the map is re-saved.

Since task deletion can be initiated from different places (e.g., swipe-to-delete on this page or from the ActionItemFormSheet), you'll need to handle cleanup in each case. For swipe-to-delete, you could modify the _deleteTask method:

  Future<void> _deleteTask(ActionItemWithMetadata item) async {
    HapticFeedback.mediumImpact();
    final provider = Provider.of<ActionItemsProvider>(context, listen: false);
    final success = await provider.deleteActionItem(item);
    if (success && mounted) {
      if (_indentLevels.remove(item.id) != null) {
        _saveTaskIndentLevels();
      }
    }
  }

A similar approach would be needed for deletions from the edit sheet, likely by passing a callback.

Suggested change
void _saveTaskIndentLevels() {
SharedPreferencesUtil().taskIndentLevels = Map<String, int>.from(_indentLevels);
}
Future<void> _deleteTask(ActionItemWithMetadata item) async {
HapticFeedback.mediumImpact();
final provider = Provider.of<ActionItemsProvider>(context, listen: false);
final success = await provider.deleteActionItem(item);
if (success && mounted) {
if (_indentLevels.remove(item.id) != null) {
_saveTaskIndentLevels();
}
}
}

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.

2 participants