Skip to content

Conversation

@4555jan
Copy link
Contributor

@4555jan 4555jan commented Oct 27, 2025

Description

This PR adds the username unavailability indicator feature to the Edit Profile Screen, matching the functionality already present in the Onboarding Screen. Previously, the Edit Profile Screen only showed when a username was available but provided no feedback when a username was unavailable or invalid.

Changes made:

  • Added "Checking..." indicator while validating username
  • Added red snackbar notification when username is unavailable
  • Added client-side validation for username format (letters, numbers, dots, hyphens, underscores only)
  • Added 36 character limit to match Appwrite document ID constraints
  • Added usernameAvailableChecking observable to track validation state

Fixes #440

screen-recording-2025-11-23-100747_7v5xHbCz.mp4

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Manual Testing:

  1. Navigate to Edit Profile Screen
  2. Attempt to change username with various inputs:
    • Valid username (6+ chars, valid format) - Shows green checkmark
    • Invalid characters (spaces, special chars) - Shows error message
    • Too long (>36 chars) - Shows error message
    • Too short (<6 chars) - Shows error message
    • Existing username - Shows "Username unavailable" snackbar

Test Configuration:

  • Device: android emulator

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • I have checked my code and corrected any misspellings

Maintainer Checklist

Summary by CodeRabbit

Release Notes

  • New Features
    • Added real-time username availability checking during profile editing
    • Display visual feedback (loading indicator and green verification icon) while checking username availability
    • Enhanced username validation with character restrictions and 36-character limit
    • Added error messages for invalid or unavailable usernames

@github-actions
Copy link
Contributor

🎉 Welcome @4555jan!
Thank you for your pull request! Our team will review it soon. 🔍

  • Please ensure your PR follows the contribution guidelines. ✅
  • All automated tests should pass before merging. 🔄
  • If this PR fixes an issue, link it in the description. 🔗

We appreciate your contribution! 🚀

@coderabbitai
Copy link

coderabbitai bot commented Oct 27, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR implements a username availability checking feature in the EditProfileScreen by adding reactive state tracking in the controller and integrating debounced validation logic with real-time UI feedback in the screen, including availability indicators and error messaging.

Changes

Cohort / File(s) Summary
Controller State Addition
lib/controllers/edit_profile_controller.dart
Adds observable usernameAvailableChecking boolean field to track username validation state.
Screen Username Validation
lib/views/screens/edit_profile_screen.dart
Introduces debounced username availability checks with format and length validation (36-character limit, allowed characters). Displays contextual snackbars for invalid or unavailable usernames. Adds real-time UI feedback via "checking" suffix and green verification icon when username is available. Updates input decorations and error messaging.

Sequence Diagram

sequenceDiagram
    actor User
    participant Screen as EditProfileScreen
    participant Debouncer
    participant Validator
    participant API as Availability<br/>Check
    participant Controller

    User->>Screen: Types username
    Screen->>Debouncer: Queue availability check
    Debouncer-->>Debouncer: Wait for input pause
    Debouncer->>Validator: Validate format & length
    alt Invalid Format/Length
        Validator-->>Screen: Show error snackbar
        Screen->>Screen: Hide verification icon
    else Valid Format
        Validator-->>Screen: Format OK
        Screen->>Controller: Set usernameAvailableChecking = true
        Controller-->>Screen: Update UI (show "checking")
        Screen->>API: Check username availability
        API-->>Screen: Available/Unavailable
        alt Username Available
            Screen->>Screen: Show green icon
            Screen->>Controller: Set usernameAvailableChecking = false
        else Username Taken
            Screen->>Screen: Show error snackbar
            Screen->>Controller: Set usernameAvailableChecking = false
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Debouncer implementation: Verify timing and cleanup to prevent memory leaks or duplicate checks
  • Validation logic: Confirm format rules, character whitelist, and 36-character limit are correctly enforced
  • State synchronization: Ensure usernameAvailableChecking field correctly reflects checking status across async operations
  • Error handling: Review both validation error snackbars and API error responses for consistency

Poem

🐰 A username checker hops with glee,
Debouncing keystrokes, one, two, three!
Green checkmarks bloom when names are free,
Red warnings when they disagree—
Guiding users, swift and true! 🎯✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "Add username unavailability indicator and validation to Edit Profile …" directly and clearly summarizes the main changes in the changeset. It accurately captures the primary objective of adding username validation features and unavailability feedback to the Edit Profile screen, which aligns with both the controller changes (adding the usernameAvailableChecking observable) and the screen changes (implementing debounced availability checks with UI feedback). The title is concise, specific, and would allow a teammate scanning the history to immediately understand the purpose of this changeset.
Linked Issues Check ✅ Passed The pull request successfully addresses the core requirements from linked issue #440. The implementation adds username validation with unavailability indication to the Edit Profile screen, matching the Onboarding screen behavior. The changes include client-side format validation, a 36-character limit enforcement, debounced availability checks with a "Checking..." indicator, and snackbar notifications for unavailable usernames. The new usernameAvailableChecking observable properly tracks validation state, and the overall implementation aligns Edit Profile behavior with Onboarding as required by the issue. All primary coding objectives from the linked issue are met by this changeset.
Out of Scope Changes Check ✅ Passed The code changes are appropriately scoped to the username validation feature described in issue #440. The additions to edit_profile_controller.dart (the usernameAvailableChecking field) and edit_profile_screen.dart (debounced username checks with UI feedback) are directly related to the stated objectives. The summary mentions minor formatting adjustments to tooltips and loading dialog calls around image picking actions; while these adjustments appear incidental to the primary feature, they are sufficiently minor and do not constitute significant out-of-scope work. The changeset remains focused on implementing the username validation feature as specified.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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.

@4555jan
Copy link
Contributor Author

4555jan commented Oct 27, 2025

@M4dhav i added a debouncer of 800ms delay because During testing, I noticed that the username validation was triggering api calls with every letter ig and i saw a debouncer being used in basically in the onboarding too please review/check if i made any major mistakes i will fix it asap

@4555jan
Copy link
Contributor Author

4555jan commented Nov 1, 2025

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Nov 1, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0666a86 and 06db5ac.

📒 Files selected for processing (2)
  • lib/controllers/edit_profile_controller.dart (1 hunks)
  • lib/views/screens/edit_profile_screen.dart (6 hunks)

@M4dhav
Copy link
Contributor

M4dhav commented Nov 3, 2025

Hey @4555jan , for future reference, user with username CodeRabbit is someone else, and not the CodeRabbit ai Bot. Please tag coderabbitai to request future reviews. Although CodeRabbitAI still detects the command, it is probably annoying for the actual user with the CodeRabbit username.

@4555jan
Copy link
Contributor Author

4555jan commented Nov 3, 2025

sorry i will make sure of that @M4dhav in the future i think i made a minor/major mistake with my commit in the files i will fix it soon are these changes that i made is mergeable or did made major mistakes ?

@M4dhav
Copy link
Contributor

M4dhav commented Nov 3, 2025

Currently reviewing, will let you know

@M4dhav M4dhav self-requested a review November 3, 2025 18:03
@M4dhav M4dhav added the enhancement New feature or request label Nov 3, 2025
@M4dhav M4dhav linked an issue Nov 3, 2025 that may be closed by this pull request
Copy link
Contributor

@M4dhav M4dhav left a comment

Choose a reason for hiding this comment

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

Please share a video of the functionality

@4555jan
Copy link
Contributor Author

4555jan commented Nov 3, 2025

@M4dhav sure I will upload it tmrw

@M4dhav
Copy link
Contributor

M4dhav commented Nov 9, 2025

Could you please include the part in the video where the username is valid? Also, I think the representation of valid/invalid usernames as done in the sign up flow is better than this

@4555jan
Copy link
Contributor Author

4555jan commented Nov 10, 2025

@M4dhav ok i uploaded another video and by representation do you mean the way it shows the invalid message is the problem ?like the design is the problem ? Or my entire change is wrong ?

@M4dhav
Copy link
Contributor

M4dhav commented Nov 10, 2025

Okay, design looks fine. One small change though, we have a minimum length of username, it is 6 or 7, you need to check for the exact value. Below that length the check should not trigger. Also, how does the UI react when a username is taken?

@4555jan
Copy link
Contributor Author

4555jan commented Nov 10, 2025

@M4dhav i uploaded another video regarding how the ui will change if the username is taken

@M4dhav
Copy link
Contributor

M4dhav commented Nov 11, 2025

UI Looks fine, can you make the change for minimum length please?

@4555jan
Copy link
Contributor Author

4555jan commented Nov 11, 2025

@M4dhav i changed the minimum length to 7 as you mentioned

Copy link
Contributor

@M4dhav M4dhav left a comment

Choose a reason for hiding this comment

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

Please run flutter gen-l10n with each PR to check untranslated.txt into source

AppLocalizations.of(
context,
)!.usernameUnavailable,
"Username can only contain letters, numbers, dots, hyphens, and underscores (max 36 characters)",
Copy link
Contributor

Choose a reason for hiding this comment

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

Add localizations

}

// Temporarily show checking state
controller.usernameAvailable.value = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not a checking state, this will show the user a green tick even while checking

@4555jan 4555jan requested a review from M4dhav November 19, 2025 13:53
@4555jan
Copy link
Contributor Author

4555jan commented Nov 19, 2025

actually i removed the the hardcoded error message snakebar entirely from the onChanged handler cause the validator will show the error inline with autovalidateMode. is that ok ?

@M4dhav
Copy link
Contributor

M4dhav commented Nov 22, 2025

Yes that is fine. Could you share an updated video of the functionalituy as well

},
controller: controller.usernameController,
onChanged: (value) async {
Get.closeCurrentSnackbar();
Copy link
Contributor

Choose a reason for hiding this comment

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

If you are no longer opening snackbars for validation then this is unnecessary

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We are still showing snackbars for validation errors (invalid format and username taken), so Get.closeCurrentSnackbar() is needed isnt

Copy link
Contributor

@M4dhav M4dhav Nov 23, 2025

Choose a reason for hiding this comment

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

but you said AutoValidator will handle those inline so the only snackbar is shown when the submit button is pressed it looks like

Comment on lines 181 to 182
controller.usernameAvailable.value = false;
controller.usernameChecking.value = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

These are unnecessary as you are already settings the values above

if (!validUsername) {
return AppLocalizations.of(
context,
)!.usernameInvalidOrTaken;
Copy link
Contributor

Choose a reason for hiding this comment

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

Please make a separate string for invalid username and taken username so user can have proper feedback

@4555jan
Copy link
Contributor Author

4555jan commented Nov 23, 2025

i have updated the video please check it

@4555jan 4555jan requested a review from M4dhav November 23, 2025 07:37
Copy link
Contributor

@M4dhav M4dhav left a comment

Choose a reason for hiding this comment

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

I think we should disable the save changes button when the username is not valid, as the autovalidator is already showing the necessary feedback inline

Comment on lines 1769 to 1772
"thisMessageWasDeleted": "This message was deleted",
"failedToDeleteMessage": "Failed to delete message"
"failedToDeleteMessage": "Failed to delete message",
"usernameInvalidFormat": "Please enter a valid username. Only letters, numbers, dots, underscores, and hyphens are allowed.",
"usernameAlreadyTaken": "This username is already taken. Try a different one."
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add descriptions for all 4 localization strings

@4555jan
Copy link
Contributor Author

4555jan commented Nov 23, 2025

sorry i didnt got it what u said elaborate it please

@M4dhav
Copy link
Contributor

M4dhav commented Nov 23, 2025

sorry i didnt got it what u said elaborate it please

  • All localization strings have descriptions for developer convenience ( see other strings for example). Please add descriptions for the strings added by you.
  • When username is invalid, save changes button should be disabled (Not clickable). This will not trigger any snackbars, but it is fine, because the Autovalidator shows errors inline. When the username is valid, then button clicks are detected and used to change the username

@4555jan 4555jan requested a review from M4dhav November 23, 2025 14:07
@4555jan
Copy link
Contributor Author

4555jan commented Nov 23, 2025

should i add another video with the changes that we made till now

Comment on lines 261 to 278
if (isUsernameChanged()) {
var usernameAvail = await isUsernameAvailable(
usernameController.text.trim(),
);
if (!usernameAvail) {
usernameAvailable.value = false;
customSnackbar(
AppLocalizations.of(Get.context!)!.usernameUnavailable,
AppLocalizations.of(Get.context!)!.usernameInvalidOrTaken,
AppLocalizations.of(Get.context!)!.usernameAlreadyTaken,
LogType.error,
);

SemanticsService.announce(
AppLocalizations.of(Get.context!)!.usernameInvalidOrTaken,
AppLocalizations.of(Get.context!)!.usernameAlreadyTaken,
TextDirection.ltr,
);
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is now unnecessary as button is disabled when username is invalid

Comment on lines 281 to 286
await databases.createDocument(
databaseId: userDatabaseID,
collectionId: usernameCollectionID,
documentId: usernameController.text.trim(),
data: {'email': authStateController.email},
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Wrap this in the try catch below as well

@4555jan 4555jan requested a review from M4dhav November 23, 2025 14:40
data: {'email': authStateController.email},
);

try {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why 2 try catch blocks? same block can handle all conditions. Also, as you are rethrowing errors,ensure that errors are captured in the view and appropriately displayed, for example, via snackbar

Copy link
Contributor Author

Choose a reason for hiding this comment

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

but we are displaying the errors in snakebar already isnt i am sorry ig rethrowing the errors is the problem is it? @M4dhav

Copy link
Contributor

Choose a reason for hiding this comment

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

There's no problem with rethrowing as long as they are handled on the view

Copy link
Contributor Author

@4555jan 4555jan Nov 24, 2025

Choose a reason for hiding this comment

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

do you think i should remove the rethrow because i think right now we are displaying the errors in the app cleanly right and so may be we should just log the error as the string what you think? actually when i wrote rethrow i wasnt sure if it really needs it

@M4dhav
Copy link
Contributor

M4dhav commented Nov 23, 2025

Also please add translation for Marathi and Gujarati for all added strings

@4555jan
Copy link
Contributor Author

4555jan commented Nov 23, 2025

for the recent new strings as well right ?

@M4dhav
Copy link
Contributor

M4dhav commented Nov 23, 2025

Just the ones you added in this PR

@4555jan 4555jan force-pushed the feat-username-validation branch 2 times, most recently from ad0aae3 to a8926cd Compare November 25, 2025 00:54
@4555jan 4555jan requested a review from M4dhav November 25, 2025 14:27
@4555jan
Copy link
Contributor Author

4555jan commented Nov 25, 2025

i had to force push earlier cause i was haveing branch issues and i removed rethrow and just logging the errors as we are already showing it snakebar

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Username Guiding feature is Not there in Edit ProfileScreen

2 participants