Skip to content

fix: view listener never updates the cover widget's view field#8872

Open
matanrotman wants to merge 1 commit into
AppFlowy-IO:mainfrom
matanrotman:fix/document-cover-view-listener-self-assignment
Open

fix: view listener never updates the cover widget's view field#8872
matanrotman wants to merge 1 commit into
AppFlowy-IO:mainfrom
matanrotman:fix/document-cover-view-listener-self-assignment

Conversation

@matanrotman

@matanrotman matanrotman commented Jul 19, 2026

Copy link
Copy Markdown

Bug

In _DocumentCoverWidgetState.initState, the onViewUpdated callback parameter is named view, which shadows the state field of the same name:

viewListener = ViewListener(viewId: widget.view.id)
  ..start(
    onViewUpdated: (view) {
      setState(() {
        viewIcon = EmojiIconData.fromViewIconPB(view.icon);
        cover = view.cover;
        view = view;          // <-- assigns the parameter to itself
      });
    },
  );

view = view resolves to the parameter on both sides, so the state field is never updated. It keeps the ViewPB captured when the widget was first built, for the widget's lifetime.

The field is not unused — it is read in build(), most notably by DocumentCover(view: view), which therefore receives a stale view even though the listener exists specifically to keep it current. The two view.id reads are unaffected in practice, since a view's id does not change.

Fix

Rename the parameter to updatedView so the assignment does what it reads as. The icon and cover assignments on the surrounding lines are unchanged in behaviour — they already read from the parameter.

Four lines, rename only. No new behaviour, no new imports or identifiers.

Note on verification

I found this while working in a fork and am reporting it as a latent correctness bug rather than a fix for a specific reproduction: I have not reproduced a user-visible symptom on unmodified main, so I have deliberately not claimed one. The defect itself is unambiguous from the code.

I am not able to compile upstream locally (this needs Flutter >= 3.32; I'm pinned to 3.27.4 by another dependency), so CI here will be its first real compile. Happy to adjust the naming or approach if you'd prefer it done differently.

Summary by Sourcery

Bug Fixes:

  • Fix the onViewUpdated callback so the cover widget's view field is correctly updated instead of being shadowed by the parameter.

In `_DocumentCoverWidgetState.initState`, the `onViewUpdated` callback
parameter is named `view`, which shadows the state field of the same
name. `view = view` therefore assigns the parameter to itself and the
field is never updated.

The field keeps the `ViewPB` captured when the widget was first built,
for the lifetime of the widget. It is read in `build`, most notably by
`DocumentCover(view: view)`, so that widget receives a stale view even
though the listener exists specifically to keep it current.

Renaming the parameter makes the assignment do what it reads as. The
icon and cover assignments on the surrounding lines are unaffected --
they already read from the parameter.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Jul 19, 2026

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

Reviewer's Guide

Fixes a shadowing bug in the document cover widget’s view listener so that the widget’s internal view state is correctly updated when the listener fires.

Sequence diagram for updated view handling in DocumentCoverWidget

sequenceDiagram
  actor User
  participant DocumentCoverWidget
  participant _DocumentCoverWidgetState
  participant ViewListener
  participant DocumentCover

  User->>DocumentCoverWidget: open document view
  DocumentCoverWidget->>_DocumentCoverWidgetState: initState()
  _DocumentCoverWidgetState->>ViewListener: start(onViewUpdated)

  ViewListener-->>_DocumentCoverWidgetState: onViewUpdated(updatedView)
  _DocumentCoverWidgetState->>_DocumentCoverWidgetState: setState(update viewIcon, cover, view = updatedView)
  _DocumentCoverWidgetState->>DocumentCover: build(DocumentCover(view))
  DocumentCover->>DocumentCover: render with current view
Loading

File-Level Changes

Change Details Files
Fix view listener callback so state.view, icon, and cover are correctly updated from the latest view.
  • Rename the onViewUpdated callback parameter to avoid shadowing the State.view field.
  • Update usages inside setState to read from the renamed parameter.
  • Assign the latest view from the listener to the State.view field so DocumentCover receives up-to-date data.
frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_cover_widget.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

@CLAassistant

CLAassistant commented Jul 19, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@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:

  • Consider renaming the state field view to something like currentView to avoid shadowing with callback parameters and make the intent clearer throughout the widget.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider renaming the state field `view` to something like `currentView` to avoid shadowing with callback parameters and make the intent clearer throughout the widget.

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.

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