Skip to content

Conversation

@codeswot
Copy link
Contributor

@codeswot codeswot commented Nov 4, 2025

Refactored group image path loading to handle direct messages and groups differently, improving performance and error handling and streamline member data retrieval.

Description

Fix profile images not displaying in direct messages (#772)

Problem

User profile images were not showing in:

  • Chat list (DM items)
  • Chat screen header (DirectMessageHeader)
  • Chat group appbar

Root Cause

Two-path image loading system mismatch:

  • UI watched groupImagePaths cache (from Rust API)
  • For DMs, the Rust API returns empty/null
  • Member images (otherMember.imagePath) existed but were never used

Solution

Unified image caching in the provider layer based on group type:

  • For DMs: Cache otherMember.imagePath directly
  • For Groups: Cache Rust API result as before

UI remains unchanged - still watches the unified groupImagePaths map, now populated for both DMs and groups.

Implementation

Modified image loading in GroupsNotifier:

  • _loadGroupImagePathForGroup() - Type-aware single group loading
  • _loadGroupImagePaths() - Type-aware batch loading

Both methods check group type and source image accordingly before caching.

Key Benefit

  • Centralized logic (no more dual image sources)
  • Polling automatically updates DM images when members change
  • UI components need no changes

Type of Change

  • ✨ 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
  • 🧪 Tests

Checklist

  • Run just precommit to ensure that formatting and linting are correct
  • Run just check-flutter-coverage to ensure that flutter coverage rules are passing
  • Updated the CHANGELOG.md file with your changes (if they affect the user experience)

Summary by CodeRabbit

  • Refactor

    • Image loading for groups and direct messages now processes in parallel, improving speed and responsiveness.
    • Enhanced error handling and intelligent caching reduce redundant operations and API calls.
    • Metadata loading is now batched for improved efficiency and resilience during partial failures.
  • Chores

    • Removed unnecessary comments from chat header widget.

Refactored group image path loading to handle direct messages and groups differently, improving performance and error handling and streamline member data retrieval.
@codeswot codeswot self-assigned this Nov 4, 2025
@codeswot codeswot linked an issue Nov 4, 2025 that may be closed by this pull request
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 4, 2025

Walkthrough

The group provider refactors metadata and image path loading to use parallelized operations instead of sequential calls. New helper methods handle DMs and groups distinctly, introduce caching for group image paths and types, and add batch processing scaffolding. The chat header widget removes non-functional comments.

Changes

Cohort / File(s) Summary
Group metadata and image path parallelization
lib/config/providers/group_provider.dart
Replaces sequential image path loading with parallelized loading via new _loadImagePathForGroup helper. Introduces caching for group image paths and types. Adds batch/metadata processing scaffolding (_processBatchedGroups, _loadGroupsMetadataLazy, _retryFailedGroupsMetadata). Centralizes error handling into _logErrorSync. Implements group-type-aware image path loading with group/DM distinction.
UI comment cleanup
lib/ui/chat/widgets/chat_header_widget.dart
Removes non-functional comments from DirectMessageHeader.build method. No behavioral or control-flow changes.

Sequence Diagram

sequenceDiagram
    participant Provider as Group Provider
    participant Cache as Image Path Cache
    participant API as Rust API
    participant Other as Other Member Data

    Note over Provider,Other: Old: Sequential Loading
    Provider->>API: Load group 1 image path
    API-->>Provider: Return path
    Provider->>API: Load group 2 image path
    API-->>Provider: Return path

    Note over Provider,Other: New: Parallel Loading with Caching
    par Load Group 1
        Provider->>Cache: Check cache
        alt Cache miss
            Provider->>API: Load image path
            API-->>Provider: Return path
            Provider->>Cache: Store path
        else Cache hit
            Cache-->>Provider: Return cached path
        end
    and Load Group 2
        Provider->>Other: Get DM member image
        Other-->>Provider: Return image path
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • The group_provider.dart changes introduce multiple new methods (_loadImagePathForGroup, _processBatchedGroups, _loadGroupsMetadataLazy, _retryFailedGroupsMetadata, _loadGroupMetadata, _loadGroupType) with distinct logic paths for DMs vs. groups, caching strategies, batch processing, and retry mechanisms—requiring careful verification of concurrency safety and error handling consistency.
  • The parallelization pattern and caching layer need validation to ensure thread-safety and absence of race conditions.
  • The _logErrorSync error-handling centralization requires review to confirm it preserves all necessary error context.

Possibly related PRs

Suggested reviewers

  • erskingardner
  • josefinalliende

Poem

🐰 Sequential paths once dragged along,
Now parallel whispers sing a song!
Cache-blessed dreams and batches tight,
Group images load at lightning flight! ⚡

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main changes: optimizing group image path loading (primary refactoring in group_provider.dart) and fixing DM header display (changes in chat_header_widget.dart).
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 772-user-profile-image-in-chat-list-and-chat-screen-doesnt-show

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b87eab8 and b9002d4.

📒 Files selected for processing (2)
  • lib/config/providers/group_provider.dart (3 hunks)
  • lib/ui/chat/widgets/chat_header_widget.dart (0 hunks)
💤 Files with no reviewable changes (1)
  • lib/ui/chat/widgets/chat_header_widget.dart
🧰 Additional context used
📓 Path-based instructions (2)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)

**/*.dart: Always declare the type of each variable and function (parameters and return value)
Avoid using dynamic and Object without justification
Create necessary types instead of overusing primitives or dynamic
One export per file
Use PascalCase for classes
Use camelCase for variables, functions, and methods
Avoid magic numbers and define constants
Start each function name with a verb
Use verbs for boolean variables (e.g., isLoading, hasError, canDelete)
Write short functions with a single purpose (under ~20 instructions)
Name functions with a verb plus context; for booleans use isX/hasX/canX; for void use executeX/saveX
Avoid deep nesting via early returns and extraction to utility functions
Use higher-order functions (map, where/filter, reduce) to avoid nesting
Use arrow functions for simple functions (under ~3 statements); use named functions otherwise
Use default parameter values instead of null checks
Reduce function parameters using RO-RO: pass/return parameter objects with declared types
Maintain a single level of abstraction within functions
Encapsulate data in composite types; avoid overusing primitives
Prefer validating data within classes rather than in functions
Prefer immutability; use final for runtime constants and const for compile-time constants
Use const constructors and const literals where possible
Follow SOLID principles
Prefer composition over inheritance
Declare interfaces (abstract classes) to define contracts
Write small classes with a single purpose (under ~200 instructions, <10 public methods, <10 properties)
Use exceptions for unexpected errors
Only catch exceptions to fix expected problems or add context; otherwise use a global handler

Files:

  • lib/config/providers/group_provider.dart
lib/**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)

lib/**/*.dart: Use flutter_rust_bridge to access core app functionality
Use Riverpod for state management; prefer StreamProviders for Rust API streams; use keepAlive if needed
Use freezed to model/manage UI states
Controllers should expose methods as inputs and update UI state that drives the UI
Use AutoRoute for navigation and use extras to pass data between pages
Use Dart extensions to manage reusable code
Use ThemeData to manage themes
Use AppLocalizations for translations
Use constants to manage constant values
Avoid deeply nested widget trees; aim for a flatter widget structure for performance and readability
Break down large widgets into smaller, focused, reusable components
Keep the widget tree shallow to simplify state management and data flow
Utilize const constructors and const widgets wherever possible to reduce rebuilds

Files:

  • lib/config/providers/group_provider.dart
🧠 Learnings (3)
📓 Common learnings
Learnt from: josefinalliende
Repo: parres-hq/whitenoise_flutter PR: 594
File: lib/src/rust/api/utils.dart:12-16
Timestamp: 2025-09-07T02:15:31.931Z
Learning: The lingering PublicKey references in lib/config/providers/auth_provider.dart, lib/config/providers/group_provider.dart, and rust_builder/cargokit/build_tool/lib/src/options.dart identified during the utils.dart API cleanup were fixed in PR #597 in the whitenoise_flutter codebase.
Learnt from: Quwaysim
Repo: parres-hq/whitenoise_flutter PR: 634
File: lib/config/providers/group_provider.dart:1130-1132
Timestamp: 2025-09-14T21:22:00.962Z
Learning: In the whitenoise_flutter codebase, the _updateGroupInfo method in GroupsNotifier performs optimistic updates that directly modify Group objects in the provider state (groups list and groupsMap). For non-DM groups, the display name comes from group.name, so updating the Group object directly is sufficient to reflect name changes in the UI without needing to refresh the separate display name cache.
Learnt from: Quwaysim
Repo: parres-hq/whitenoise_flutter PR: 642
File: lib/ui/contact_list/new_chat_bottom_sheet.dart:324-336
Timestamp: 2025-09-16T07:24:07.489Z
Learning: In the whitenoise_flutter project, the user Quwaysim prefers to handle security improvements incrementally across different PRs rather than bundling them all together. Input trimming for search functionality was handled in PR #613, and private key security measures are planned for PR #505.
📚 Learning: 2025-09-14T21:22:00.962Z
Learnt from: Quwaysim
Repo: parres-hq/whitenoise_flutter PR: 634
File: lib/config/providers/group_provider.dart:1130-1132
Timestamp: 2025-09-14T21:22:00.962Z
Learning: In the whitenoise_flutter codebase, the _updateGroupInfo method in GroupsNotifier performs optimistic updates that directly modify Group objects in the provider state (groups list and groupsMap). For non-DM groups, the display name comes from group.name, so updating the Group object directly is sufficient to reflect name changes in the UI without needing to refresh the separate display name cache.

Applied to files:

  • lib/config/providers/group_provider.dart
📚 Learning: 2025-09-07T02:15:31.931Z
Learnt from: josefinalliende
Repo: parres-hq/whitenoise_flutter PR: 594
File: lib/src/rust/api/utils.dart:12-16
Timestamp: 2025-09-07T02:15:31.931Z
Learning: The lingering PublicKey references in lib/config/providers/auth_provider.dart, lib/config/providers/group_provider.dart, and rust_builder/cargokit/build_tool/lib/src/options.dart identified during the utils.dart API cleanup were fixed in PR #597 in the whitenoise_flutter codebase.

Applied to files:

  • lib/config/providers/group_provider.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Flutter CI

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codeswot codeswot requested review from Quwaysim and untreu2 November 4, 2025 06:11
Copy link
Contributor

@Quwaysim Quwaysim left a comment

Choose a reason for hiding this comment

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

LGTM

@codeswot codeswot merged commit c69ad61 into master Nov 4, 2025
2 checks passed
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.

User profile image in chat list and chat screen doesn't show

3 participants