Description
After scrolling through a chat or room list, other users' avatars sometimes display the current logged-in user's profile picture instead of their own.
Steps to reproduce
- Log in with a custom profile avatar.
- Open a group chat or room list with multiple users who have different avatars.
- Scroll quickly through messages or the chat list.
- Notice that some other users' avatars show your own photo.
Expected behavior
Each avatar should always match the correct user's MXC URI, regardless of scroll position or list recycling.
Actual behavior
Stale image data from a previously bound avatar URI is applied to a different user after the widget is rebound during list recycling.
Root cause
MxcImage._load() is async and does not verify that the widget is still bound to the same URI when the download completes. When a list item is recycled:
- Widget loads the current user's avatar URI
- List scroll rebinds the widget to another user
- The earlier download completes and writes image bytes under the new user's cache key
- The wrong avatar is displayed and may persist in the in-memory LRU cache
Users without avatars still mount MxcImage with uri: null, which can retain stale image data from a previous binding.
Proposed fix
- Capture
uri, event, and cache key at the start of _load() and discard the response if any of them changed before setState
- For users without an avatar, render the letter fallback directly and skip
MxcImage
- Add a stable
RepaintBoundary key based on URI, display name, and size
Affected files
lib/widgets/mxc_image.dart
lib/widgets/avatar.dart
Environment
- Reproducible on Linux desktop; likely affects all platforms with scrollable avatar lists
Description
After scrolling through a chat or room list, other users' avatars sometimes display the current logged-in user's profile picture instead of their own.
Steps to reproduce
Expected behavior
Each avatar should always match the correct user's MXC URI, regardless of scroll position or list recycling.
Actual behavior
Stale image data from a previously bound avatar URI is applied to a different user after the widget is rebound during list recycling.
Root cause
MxcImage._load()is async and does not verify that the widget is still bound to the same URI when the download completes. When a list item is recycled:Users without avatars still mount
MxcImagewithuri: null, which can retain stale image data from a previous binding.Proposed fix
uri,event, and cache key at the start of_load()and discard the response if any of them changed beforesetStateMxcImageRepaintBoundarykey based on URI, display name, and sizeAffected files
lib/widgets/mxc_image.dartlib/widgets/avatar.dartEnvironment