Skip to content

chore: add reset to normal state method for interactive layer#480

Merged
behnam-deriv merged 1 commit into
masterfrom
add-reset-method-for-interactive-layer
Jun 18, 2026
Merged

chore: add reset to normal state method for interactive layer#480
behnam-deriv merged 1 commit into
masterfrom
add-reset-method-for-interactive-layer

Conversation

@behnam-deriv

@behnam-deriv behnam-deriv commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Clickup link:
Fixes issue: #

This PR contains the following changes:

  • Added a resetToNormalState method to the interactive layer. This allows consumer apps to programmatically reset drawing tools from a selected state back to normal. For example, if a user reloads the chart while a drawing tool is active, the consumer app can call this method to ensure all tools are unselected upon reload.

  • ✨ New feature (non-breaking change which adds functionality)

  • 🛠️ Bug fix (non-breaking change which fixes an issue)

  • ❌ Breaking change (fix or feature that would cause existing functionality to change)

  • 🧹 Code refactor

  • ✅ Build configuration change

  • 📝 Documentation

  • 🗑️ Chore

Developers Note (Optional)

Pre-launch Checklist (For PR creator)

As a creator of this PR:

  • ✍️ I have included clickup id and package/app_name in the PR title.
  • 👁️ I have gone through the code and removed any temporary changes (commented lines, prints, debug statements etc.).
  • ⚒️ I have fixed any errors/warnings shown by the analyzer/linter.
  • 📝 I have added documentation, comments and logging wherever required.
  • 🧪 I have added necessary tests for these changes.
  • 🔎 I have ensured all existing tests are passing.

Reviewers

Pre-launch Checklist (For Reviewers)

As a reviewer I ensure that:

  • ✴️ This PR follows the standard PR template.
  • 🪩 The information in this PR properly reflects the code changes.
  • 🧪 All the necessary tests for this PR's are passing.

Pre-launch Checklist (For QA)

  • 👌 It passes the acceptance criteria.

Pre-launch Checklist (For Maintainer)

  • [MAINTAINER_NAME] I make sure this PR fulfills its purpose.

Summary by Sourcery

New Features:

  • Expose a resetToNormalState method on the interactive layer behaviour so consumers can programmatically return it to the normal interaction state.

@sourcery-ai

sourcery-ai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds a programmatic API on the interactive layer behaviour to reset the interactive state back to the normal (unselected) state without requiring the widget to be mounted, by directly updating the controller’s currentState when needed.

File-Level Changes

Change Details Files
Expose a safe reset method on interactive layer behaviour to return to InteractiveNormalState, bypassing updateStateTo when the layer is not yet mounted.
  • Introduce resetToNormalState() on InteractiveLayerBehaviour that checks if the current state is not InteractiveNormalState and, if so, assigns a new InteractiveNormalState to the controller
  • Implement the reset in terms of directly setting _controller.currentState instead of using updateStateTo to avoid requiring interactiveLayer initialisation
  • Document the method’s semantics: drops current selection/in-progress adding state, is safe pre-mount, and is a no-op when already in normal state
lib/src/deriv_chart/interactive_layer/interactive_layer_behaviours/interactive_layer_behaviour.dart

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails

Scanned Manifest Files

@claude

claude Bot commented Jun 18, 2026

Copy link
Copy Markdown

Claude finished @behnam-deriv's task —— View job


Code Review: Add reset to normal state method for interactive layer

I've reviewed the PR and analyzed the implementation. Here's my feedback:


Summary

This PR adds a resetToNormalState() method to InteractiveLayerBehaviour that allows consumer apps to programmatically reset drawing tools to their normal state. The implementation is clean and serves its stated purpose well.


Findings

High Priority

1. Missing notification to listeners after state change

Location: lib/src/deriv_chart/interactive_layer/interactive_layer_behaviours/interactive_layer_behaviour.dart:57-62

Issue: The resetToNormalState() method directly sets _controller.currentState but doesn't call notifyListeners() on the controller. Looking at InteractiveLayerController (line 47-50), the setter for currentState calls notifyListeners(), but the new method bypasses this setter and directly assigns to the private field.

void resetToNormalState() {
  if (currentState is! InteractiveNormalState) {
    _controller.currentState =
        InteractiveNormalState(interactiveLayerBehaviour: this);
  }
}

Why this matters: Widgets listening to the controller won't be notified of the state change, potentially causing UI inconsistencies.

Recommendation: Use the public setter instead of directly accessing the private field:

void resetToNormalState() {
  if (currentState is! InteractiveNormalState) {
    _controller.currentState =
        InteractiveNormalState(interactiveLayerBehaviour: this);
  }
}

Wait - looking at the code again, you're already using _controller.currentState = which should trigger the setter. Let me verify... Yes, the code is correct. The setter will be invoked and notifyListeners() will be called. This is actually fine as-is.


Medium Priority

2. Missing test coverage

Issue: No unit tests were added for the new resetToNormalState() method.

Why this matters: This is a public API that will be used by consumer applications. Tests would help ensure:

  • The method correctly transitions from InteractiveSelectedToolState to InteractiveNormalState
  • The method correctly transitions from InteractiveAddingToolState to InteractiveNormalState
  • The method is a no-op when already in InteractiveNormalState
  • The method works correctly before initialization (as documented)

Recommendation: Add unit tests covering these scenarios. Example test cases:

test('resetToNormalState transitions from selected state to normal state', () { ... });
test('resetToNormalState transitions from adding state to normal state', () { ... });
test('resetToNormalState is no-op when already in normal state', () { ... });
test('resetToNormalState works before initialization', () { ... });

3. Potential cleanup needed for AddingToolState

Location: lib/src/deriv_chart/interactive_layer/interactive_layer_behaviours/interactive_layer_behaviour.dart:57-62

Issue: When transitioning from InteractiveAddingToolState to InteractiveNormalState, there's a _drawingPreview that might be in progress. Looking at interactive_adding_tool_state.dart (lines 113-116), this preview is managed internally. The direct state change might leave this preview in an inconsistent state.

Why this matters: If a user is mid-way through adding a drawing tool and the app calls resetToNormalState() (e.g., on chart reload), the preview drawing might not be properly cleaned up.

Recommendation: Consider calling interactiveLayer.clearAddingDrawing() before resetting to normal state, or document that consumers should handle cleanup before calling this method. Looking at the existing cancelAdding() flow (controller:56-64), it calls onCancelAdding which eventually calls updateStateTo with InteractiveNormalState. You might want similar cleanup logic here.


Low Priority

4. Documentation could be more specific about the use case

Issue: The doc comment mentions "Safe to call before the layer has mounted" but doesn't explain why this is important or when you'd actually want to do this.

Why this matters: Better documentation helps consumers understand when and how to use this method.

Recommendation: Enhance the documentation to include a concrete example:

/// Resets the interactive layer to [InteractiveNormalState], dropping any
/// current selection or in-progress adding state.
/// 
/// This is useful when reloading the chart or switching symbols while a 
/// drawing tool is active. For example:
/// 
/// ```dart
/// // Before reloading chart data
/// interactiveLayerBehaviour.resetToNormalState();
/// reloadChartData();
/// ```
/// 
/// Safe to call before the layer has mounted — bypasses [updateStateTo] 
/// which requires [interactiveLayer] to be initialised. 
/// No-op if already in normal state.

5. Consider adding a callback for state changes

Issue: The method silently changes state without any callback mechanism. Consumer apps might want to know when this reset occurs to update their UI accordingly (e.g., deselecting a tool button in the toolbar).

Why this matters: While the InteractiveLayerController extends ChangeNotifier, consumer apps might want a more explicit callback for this specific reset action.

Recommendation: Consider adding an optional callback parameter or ensuring the existing notifyListeners() pattern is well-documented for this use case. This is a nice-to-have rather than a requirement.


Code Quality

Follows Dart conventions: PascalCase for class names, camelCase for methods
Immutability consideration: Doesn't mutate state unnecessarily
Documentation: Has dartdoc comments
Performance: Guard clause prevents unnecessary state creation
⚠️ Testing: Missing test coverage (see Medium Priority #2)


Recommendation

Approve with suggestions:

The implementation itself is clean and functional. The main concern is the lack of test coverage and potential edge case with InteractiveAddingToolState cleanup.


@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • Bypassing updateStateTo and assigning _controller.currentState directly may skip any cleanup or side effects normally performed during state transitions; consider reusing updateStateTo when the layer is mounted and only falling back to direct assignment when it is not.
  • The doc comment says this is safe to call before the layer has mounted, but _controller is late final; ensure _controller is always initialized before resetToNormalState can be called, or guard the method so it no-ops if the controller/state is not yet ready.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Bypassing `updateStateTo` and assigning `_controller.currentState` directly may skip any cleanup or side effects normally performed during state transitions; consider reusing `updateStateTo` when the layer is mounted and only falling back to direct assignment when it is not.
- The doc comment says this is safe to call before the layer has mounted, but `_controller` is `late final`; ensure `_controller` is always initialized before `resetToNormalState` can be called, or guard the method so it no-ops if the controller/state is not yet ready.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@behnam-deriv behnam-deriv merged commit 7954d06 into master Jun 18, 2026
8 checks passed
@behnam-deriv behnam-deriv deleted the add-reset-method-for-interactive-layer branch June 18, 2026 08:36
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