Skip to content

feat: display user's real name with time-based greeting in header. #7421

Open
chetanr25 wants to merge 11 commits intoopenfoodfacts:developfrom
chetanr25:7372_greet_username
Open

feat: display user's real name with time-based greeting in header. #7421
chetanr25 wants to merge 11 commits intoopenfoodfacts:developfrom
chetanr25:7372_greet_username

Conversation

@chetanr25
Copy link
Contributor

What

This PR updates the Community page header to display the user's real name (when available) along with a greeting instead of just showing the userid (while userid serves as fallback when name isn't available)

  • Extracted userDetails from LoginStatus during login flow and added to LoginResult class.
  • Added globalUserDetails static variable in UserManagementProvider for global access
  • name is stored using DaoSecuredString

Screenshot or video

Fixes bug(s)

…a way to extract userDetails and store in provider. Closes openfoodfacts#7372
serDetails after app is restarted. UserDetails is stored in DaoSecuredString by se
rialization
@codecov-commenter
Copy link

codecov-commenter commented Feb 18, 2026

Codecov Report

❌ Patch coverage is 3.33333% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 9.10%. Comparing base (4d9c7fc) to head (af7688a).
⚠️ Report is 1348 commits behind head on develop.

Files with missing lines Patch % Lines
..._app/lib/data_models/user_management_provider.dart 0.00% 16 Missing ⚠️
...s/app_bars/logged_in/logged_in_app_bar_header.dart 0.00% 12 Missing ⚠️
...kages/smooth_app/lib/data_models/login_result.dart 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           develop   #7421      +/-   ##
==========================================
- Coverage     9.54%   9.10%   -0.45%     
==========================================
  Files          325     625     +300     
  Lines        16411   36664   +20253     
==========================================
+ Hits          1567    3337    +1770     
- Misses       14844   33327   +18483     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@chetanr25
Copy link
Contributor Author

UserDetails is serialized to JSON for storage since we need multiple fields from it (name, preferredLanguage, country, isModerator). This approach is easier to maintain than storing each field separately, and automatically supports any new fields added to UserDetails in the future.

Does this seem like the right approach or would you prefer something different?

@chetanr25 chetanr25 marked this pull request as ready for review February 19, 2026 10:49
Copy link
Member

@teolemon teolemon left a comment

Choose a reason for hiding this comment

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

  • I'm not sure we can assume a name 100% of the time. We should have a fallback, and a path to fixing it if it is not corrrect
  • I'm not completely sure about the time of the day thing, since the string might overflow, and it might be a bit overkill

Copy link
Contributor

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

Updates the Preferences/Community header to greet the logged-in user by their real name (when available) instead of only showing the userId, by persisting UserDetails from the login flow and adding new localized greeting strings.

Changes:

  • Extend the login flow (LoginResult) to carry UserDetails and persist them in secure storage.
  • Add time-of-day greeting strings to l10n and display a greeting + name in the logged-in header.
  • Introduce UserManagementProvider.globalUserDetails for retrieving the stored name globally.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/smooth_app/lib/l10n/app_localizations.dart Generated localization interface updated with new greeting getters.
packages/smooth_app/lib/l10n/app_en.arb Adds English strings for the new greeting keys.
packages/smooth_app/lib/generic_lib/widgets/app_bars/logged_in/logged_in_app_bar_header.dart Displays a time-based greeting and the user’s real name (fallback to userId).
packages/smooth_app/lib/data_models/user_management_provider.dart Saves/restores UserDetails to secure storage and clears them on logout.
packages/smooth_app/lib/data_models/login_result.dart Adds userDetails to LoginResult and populates it from LoginStatus.

Comment on lines 84 to 88
DaoSecuredString.remove(key: _USER_ID);
DaoSecuredString.remove(key: _PASSWORD);
DaoSecuredString.remove(key: _COOKIE);
DaoSecuredString.remove(key: _USER_DETAILS);
Logs.e('Credentials query failed, you have been logged out');
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

In the PlatformException handler, DaoSecuredString.remove is async but not awaited. That can leave stale credentials/user_details in secure storage after a decryption failure. Await these removals (e.g. Future.wait) so the cleanup is guaranteed before continuing.

Copilot uses AI. Check for mistakes.
Comment on lines +108 to +110
Logs.e('Failed to parse UserDetails: $e');
DaoSecuredString.remove(key: _USER_DETAILS);
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

When JSON parsing fails, DaoSecuredString.remove(_USER_DETAILS) is async but not awaited. Awaiting the removal ensures corrupted data is actually cleared before the next startup/login attempt.

Copilot uses AI. Check for mistakes.
Comment on lines +54 to 56
AutoSizeText(
'${_getGreeting(appLocalizations)} $name',
style: TextStyle(
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The greeting is built by concatenating two localized fragments (greeting + name). This is not fully localizable (word order / punctuation / spacing differ by language). Prefer a single localized message with a {name} placeholder (e.g. per time-of-day greeting keys that include the name), and format it through l10n instead of string concatenation.

Copilot uses AI. Check for mistakes.
Comment on lines +45 to +47
} else {
DaoSecuredString.remove(key: _USER_DETAILS);
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

DaoSecuredString.remove returns a Future, but this call isn’t awaited. That can leave user_details undeleted when subsequent logic runs (and also hides storage errors). Await the remove call (and consider propagating/handling the returned bool) before notifying listeners.

Copilot uses AI. Check for mistakes.
Comment on lines 55 to 61
DaoSecuredString.remove(key: _USER_ID);
DaoSecuredString.remove(key: _PASSWORD);
DaoSecuredString.remove(key: _COOKIE);
DaoSecuredString.remove(key: _USER_DETAILS);
notifyListeners();
final bool contains = await credentialsInStorage();
return !contains;
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

logout() calls DaoSecuredString.remove (async) without awaiting any of them, then immediately calls credentialsInStorage(). Because deletes may not have completed, logout can incorrectly report that credentials still exist. Await the removals (e.g. Future.wait) before checking credentialsInStorage / returning.

Copilot uses AI. Check for mistakes.
@chetanr25
Copy link
Contributor Author

  • I'm not sure we can assume a name 100% of the time. We should have a fallback, and a path to fixing it if it is not corrrect
  • I'm not completely sure about the time of the day thing, since the string might overflow, and it might be a bit overkill

We will display userid as a fallback if username is null.
https://github.com/openfoodfacts/smooth-app/pull/7421/changes#diff-bb0a766b884d5375b57a48ec47e314cc1de446513b459a3894eb12bbcc2f9680R40-R41

We can use AutoSizeText which decreases Text size based on its length.
https://github.com/openfoodfacts/smooth-app/pull/7421/changes#diff-bb0a766b884d5375b57a48ec47e314cc1de446513b459a3894eb12bbcc2f9680R54

UI sample for a long text when used with AutoSizeText:

Hmm

@chetanr25
Copy link
Contributor Author

Copilot just suggested to add await, but is it necessary when we are removing stored data from DaoSecuredString?

#7421 (comment)
I didn’t think this could also be an issue, but Makes sense. I will commit a fix for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🌐 l10n 👥 User management Account login, signup, signout

Projects

Status: 💬 To discuss and validate

Development

Successfully merging this pull request may close these issues.

Use the username (if available) on the Community page

4 participants