Skip to content

fix(chat): prevent display-name flicker and admin-badge duplication on hover#313

Open
novavale wants to merge 1 commit intoberkmancenter:mainfrom
novavale:fix/chat-hover-username-visibility
Open

fix(chat): prevent display-name flicker and admin-badge duplication on hover#313
novavale wants to merge 1 commit intoberkmancenter:mainfrom
novavale:fix/chat-hover-username-visibility

Conversation

@novavale
Copy link

Problem

Fixes #248

When hovering over a chat message, two visual bugs appeared:

  1. Display name disappeared — temporarily replaced by ...
  2. Admin/mod badge duplicated momentarily in the header row

Root Cause

MessageDisplayState stored hover state as a bool field and called setState() on enter/exit. This triggered a full rebuild of the widget, including UserInfoBuilder. During that rebuild UserInfoBuilder briefly re-entered its loading state, making snapshot.data == null and causing the display name to fall back to '...'. The same rebuild caused Wrap to re-lay out its children, producing a momentary duplicate paint of the admin badge.

Fix

Replace the bool _isHovered field with a ValueNotifier<bool> and wrap only the background Container in a ValueListenableBuilder. The message content Row is passed as the static child argument of ValueListenableBuilder — Flutter reuses it unchanged when the notifier fires, so UserInfoBuilder is never re-triggered by a hover event.

// Before — setState triggers full rebuild
onEnter: (hover) => setState(() => _isHovered = true),

// After — only Container color re-evaluates
final _isHovered = ValueNotifier<bool>(false);
onEnter: (_) => _isHovered.value = true,

Testing

  • Hovered over chat messages with admin/mod senders — name stays stable, no badge duplication
  • Verified hover highlight still appears/disappears correctly
  • Verified delete button still renders for permitted users

…n hover

Hover state was stored as a bool field and updated via setState(), which
triggered a full rebuild of MessageDisplayState — including UserInfoBuilder.
During the rebuild UserInfoBuilder briefly re-entered the loading state,
making snapshot.data null so the display name showed '...' instead of the
actual name. The same rebuild caused Wrap to re-lay out its children,
producing a momentary duplicate of the admin/mod badge.

Fix: replace the bool field with a ValueNotifier<bool> and wrap only the
Container in a ValueListenableBuilder. The message content Row is passed as
the static  argument and is reused unchanged when hover changes, so
UserInfoBuilder is never re-triggered by hover events.

Fixes berkmancenter#248
@katherineqian katherineqian self-requested a review February 26, 2026 04:04
@katherineqian
Copy link
Collaborator

Hi @novavale, thank you so much for your contribution! I will test out these updates and provide a review early next week. Have a great weekend!

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a Flutter chat UI hover regression where message header content (display name and admin/mod badge) visually flickered/duplicated due to hover-triggered full widget rebuilds.

Changes:

  • Replaced hover tracking from setState-backed bool to a ValueNotifier<bool> to avoid rebuilding the full widget subtree on hover.
  • Wrapped only the background Container in a ValueListenableBuilder, passing the message content as the static child to prevent UserInfoBuilder from being retriggered.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

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.

[Bug] Meeting chat temporarily hides user name, duplicates admin label in previously sent message

3 participants