Skip to content

[$250] ComposeBox - When you click on the mention again, extra characters appear #60804

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
6 of 8 tasks
jponikarchuk opened this issue Apr 24, 2025 · 16 comments
Open
6 of 8 tasks
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2

Comments

@jponikarchuk
Copy link

jponikarchuk commented Apr 24, 2025

If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!


Version Number: 9.1.32-0
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught on HybridApp, is this reproducible on New Expensify Standalone?: No, reproducible on hybrid only
If this was caught during regression testing, add the test name, ID and link from TestRail: https://expensify.testrail.io/index.php?/tests/view/5995329
Email or phone of affected tester (no customers): [email protected]
Issue reported by: Applause Internal Team
Device used: Macbook/13.7.5/Chrome, OnePlus 9 PRO/Android 14/Chrome, iPhone 12 PRO/iOS 18.4.1
App Component: Chat Report View

Action Performed:

  1. Open https://staging.new.expensify.com
  2. Log in with any HT account
  3. Go to any conversation or create one
  4. In the Compose box, type “ @ ”
  5. Select any user to mention or enter any username
  6. Click on the login of the user in the mention
  7. In the window that appears, click on the same user again
  8. Repeat steps 6-7 several times

Expected Result:

When you click on the mention again, nothing should change

Actual Result:

When you click on a mention again, extra characters appear at the end of the mention.

Workaround:

Unknown

Platforms:

  • Android: Standalone
  • Android: HybridApp
  • Android: mWeb Chrome
  • iOS: Standalone
  • iOS: HybridApp
  • iOS: mWeb Safari
  • MacOS: Chrome / Safari
  • MacOS: Desktop

Screenshots/Videos

1.mp4

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~021915530953266836404
  • Upwork Job ID: 1915530953266836404
  • Last Price Increase: 2025-04-24
  • Automatic offers:
    • Krishna2323 | Contributor | 107127961
Issue OwnerCurrent Issue Owner: @
Issue OwnerCurrent Issue Owner: @Krishna2323
@jponikarchuk jponikarchuk added Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 labels Apr 24, 2025
Copy link

melvin-bot bot commented Apr 24, 2025

Triggered auto assignment to @lydiabarclay (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

@Krishna2323
Copy link
Contributor

Krishna2323 commented Apr 24, 2025

🚨 Edited by proposal-police: This proposal was edited at 2025-04-29 20:36:16 UTC.

Proposal

Please re-state the problem that we are trying to solve in this issue.

  • When a user clicks on a mention suggestion (e.g., @[email protected]) after partially typing it (e.g., @abcd), the mention is inserted correctly, but extra characters from the original input (like gmail.com) remain after the inserted mention. This results in duplicated or malformed mentions like @[email protected] gmail.com.

What is the root cause of that problem?

  • The issue stems from how the commentAfterMention is computed when inserting the selected mention.
  • Currently, the logic slices the comment based on a fixed offset after the @ symbol — it doesn't account for the full original mention text (like @[email protected]). As a result, the remaining part of the original input (e.g., gmail.com) gets preserved and appended after the newly inserted mention.

const insertSelectedMention = useCallback(
(highlightedMentionIndexInner: number) => {
const commentBeforeAtSign = value.slice(0, suggestionValues.atSignIndex);
const mentionObject = suggestionValues.suggestedMentions.at(highlightedMentionIndexInner);
if (!mentionObject || highlightedMentionIndexInner === -1) {
return;
}
const mentionCode = getMentionCode(mentionObject, suggestionValues.prefixType);
const commentAfterMention = value.slice(suggestionValues.atSignIndex + suggestionValues.mentionPrefix.length + 1);
updateComment(`${commentBeforeAtSign}${mentionCode} ${trimLeadingSpace(commentAfterMention)}`, true);
const selectionPosition = suggestionValues.atSignIndex + mentionCode.length + CONST.SPACE_LENGTH;
setSelection({
start: selectionPosition,
end: selectionPosition,
});
suggestionInsertionIndexRef.current = selectionPosition;
setSuggestionValues((prevState) => ({
...prevState,
suggestedMentions: [],
shouldShowSuggestionMenu: false,
}));
},

What changes do you think we should make in order to solve the problem?

  • Instead of slicing a fixed number of characters after the @, dynamically determine the length of the original mention string (e.g., @[email protected]) by matching the text from atSignIndex.

  • Then, slice the value only after that full match to get the accurate commentAfterMention.

  • We will use MENTION_BREAKER to get the remaining part of the metion.

    App/src/CONST.ts

    Lines 3494 to 3498 in 3885a40

    // Define the regular expression pattern to find a potential end of a mention suggestion:
    // It might be a space, a newline character, an emoji, or a special character (excluding underscores & tildes, which might be used in usernames)
    get MENTION_BREAKER() {
    return new RegExp(`[\\n\\s]|${this.SPECIAL_CHAR.source}|${this.EMOJI.source}`, 'gu');
    },

  • This ensures we don’t re-append any part of the original partial mention.

Code diff
+  function getOriginalMentionText(valuee: string, atSignIndex: number) {
+     const rest = valuee.slice(atSignIndex);
+     const mentionMatch = rest.match(/^[@\w.\-+]+/); // capture till space or special characters not in emails
+     return mentionMatch?.[0] ?? '';
+  }

  const insertSelectedMention = useCallback(
      (highlightedMentionIndexInner: number) => {
          const commentBeforeAtSign = value.slice(0, suggestionValues.atSignIndex);
          const mentionObject = suggestionValues.suggestedMentions.at(highlightedMentionIndexInner);
          if (!mentionObject || highlightedMentionIndexInner === -1) {
              return;
          }
          const mentionCode = getMentionCode(mentionObject, suggestionValues.prefixType);
-         const commentAfterMention = value.slice(suggestionValues.atSignIndex + suggestionValues.mentionPrefix.length + 1);
+         const originalMention = getOriginalMentionText(value, suggestionValues.atSignIndex);
+         const commentAfterMention = value.slice(suggestionValues.atSignIndex + originalMention.length);

          updateComment(`${commentBeforeAtSign}${mentionCode} ${trimLeadingSpace(commentAfterMention)}`, true);
          const selectionPosition = suggestionValues.atSignIndex + mentionCode.length + CONST.SPACE_LENGTH;
          setSelection({
              start: selectionPosition,
              end: selectionPosition,
          });
          suggestionInsertionIndexRef.current = selectionPosition;
          setSuggestionValues((prevState) => ({
              ...prevState,
              suggestedMentions: [],
              shouldShowSuggestionMenu: false,
          }));
      },
-     [
-         value,
-         suggestionValues.atSignIndex,
-         suggestionValues.suggestedMentions,
-         suggestionValues.prefixType,
-         suggestionValues.mentionPrefix.length,
-         getMentionCode,
-         updateComment,
-         setSelection,
-     ],
+     [
+         value,
+         suggestionValues.atSignIndex,
+         suggestionValues.suggestedMentions,
+         suggestionValues.prefixType,
+         getMentionCode,
+         updateComment,
+         setSelection,
+     ],
  );

What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

  • We can create test for insertSelectedMention to test different scenarios.

What alternative solutions did you explore? (Optional)

N/A

Result

@lydiabarclay lydiabarclay added the External Added to denote the issue can be worked on by a contributor label Apr 24, 2025
@melvin-bot melvin-bot bot changed the title ComposeBox - When you click on the mention again, extra characters appear [$250] ComposeBox - When you click on the mention again, extra characters appear Apr 24, 2025
Copy link

melvin-bot bot commented Apr 24, 2025

Job added to Upwork: https://www.upwork.com/jobs/~021915530953266836404

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Apr 24, 2025
Copy link

melvin-bot bot commented Apr 24, 2025

Triggered auto assignment to Contributor-plus team member for initial proposal review - @hoangzinh (External)

@hoangzinh
Copy link
Contributor

@Krishna2323 can you check if we have any existing regrex for this const mentionMatch = rest.match(/^[@\w.\-+]+/);?

@Krishna2323
Copy link
Contributor

Krishna2323 commented Apr 28, 2025

@hoangzinh, I think we can use MENTION_BREAKER. It works well.

App/src/CONST.ts

Lines 3494 to 3498 in 3885a40

// Define the regular expression pattern to find a potential end of a mention suggestion:
// It might be a space, a newline character, an emoji, or a special character (excluding underscores & tildes, which might be used in usernames)
get MENTION_BREAKER() {
return new RegExp(`[\\n\\s]|${this.SPECIAL_CHAR.source}|${this.EMOJI.source}`, 'gu');
},

Monosnap.screencast.2025-04-28.15-15-20.mp4

@hoangzinh
Copy link
Contributor

Cool. Can you add it to your proposal? Also, you can put code diff into details expand block to help your proposal look cleaner/

@dangrous dangrous self-assigned this Apr 28, 2025
@dangrous
Copy link
Contributor

Can help with internal review on this when it's ready for it!

@Krishna2323
Copy link
Contributor

Cool. Can you add it to your proposal? Also, you can put code diff into details expand block to help your proposal look cleaner.

@hoangzinh, proposal updated.

@hoangzinh
Copy link
Contributor

Thank you. @Krishna2323's proposal looks good to me.

Link to proposal #60804 (comment)

🎀👀🎀 C+ reviewed

Copy link

melvin-bot bot commented Apr 30, 2025

Current assignee @dangrous is eligible for the choreEngineerContributorManagement assigner, not assigning anyone new.

@melvin-bot melvin-bot bot removed the Help Wanted Apply this label when an issue is open to proposals by contributors label Apr 30, 2025
Copy link

melvin-bot bot commented Apr 30, 2025

📣 @Krishna2323 🎉 An offer has been automatically sent to your Upwork account for the Contributor role 🎉 Thanks for contributing to the Expensify app!

Offer link
Upwork job
Please accept the offer and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review 🧑‍💻
Keep in mind: Code of Conduct | Contributing 📖

@Krishna2323
Copy link
Contributor

@hoangzinh, PR is ready for review ^

Copy link

melvin-bot bot commented May 13, 2025

⚠️ Looks like this issue was linked to a Deploy Blocker here

If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

If a regression has occurred and you are the assigned CM follow the instructions here.

If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

@lydiabarclay
Copy link

@hoangzinh looks like a different issue was the cause of the above deploy blocker, could you confirm?

@hoangzinh
Copy link
Contributor

yes, the PR was reverted. @Krishna2323 can you create another PR to fix this issue again?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is broken. Auto assigns a BugZero manager. External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2
Projects
Status: No status
Development

No branches or pull requests

5 participants