Skip to content
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

Bug: Tapping a name suggestion when tagging causes Cast Modal to close #476

Open
willyogo opened this issue Oct 14, 2024 · 1 comment
Open
Assignees
Labels
bug Something isn't working
Milestone

Comments

@willyogo
Copy link
Collaborator

Reported by a user on 11/14/24 (https://discord.com/channels/1224471875023802521/1251186884726493225/1295470564785393717)

Steps to reproduce:

  1. When casting, start tagging someone (ie. @nounspaceTom) and tap one of the name suggestions that appears

Expected result:

  1. When a name suggestion is tapped, the tag is autocompleted with the username and highlighted blue

Actual result:

  1. When a name suggestion is tapped, the cast modal closes

AC:

  1. When a name suggestion is tapped, the tag is autocompleted with the username and highlighted blue; the modal does not close
@willyogo willyogo added the bug Something isn't working label Oct 14, 2024
@willyogo willyogo added this to the Extermination milestone Oct 14, 2024
@sktbrd
Copy link
Collaborator

sktbrd commented Oct 25, 2024

There was initially 3 problems,

  1. FocusMode prop in Modal component was causing it to fix when the focus shifted to mentionList that was imported from deprecated modProtocol

  2. we had no control over mentionList so I brought it over, its still only responsive by keyboard command

  3. we were passing mentions as simple text, when we needed to mount the cast using the text, the mentions and its positions as a separated object like this :

image

I am now stuck between the regex to grab the mention text position and placing it in the right position with all possible line breaks

This is the crucial code to solve the mention positions problem:

    const fetchMentionsAndSetDraft = async () => {
      const newEmbeds = initialEmbeds ? [...embeds, ...initialEmbeds] : embeds;

      // Regex to match pure @username mentions, ensuring it's not part of a URL
      const usernamePattern = /(?:^|\s|^)@([a-zA-Z0-9_.]+)(?=\s|$)/g;

      // The working copy of the text for position calculation
      const workingText = text;

      // Extract mentions and their positions from the original text
      const usernamesWithPositions = [
        ...workingText.matchAll(usernamePattern),
      ].map((match) => ({
        username: match[1],
        position: match.index! + match[0].indexOf("@"), // Adjust position to '@'
      }));

      const uniqueUsernames = Array.from(
        new Set(usernamesWithPositions.map((u) => u.username)),
      );

      if (uniqueUsernames.length > 0) {
        try {
          // Fetch the FIDs for the mentioned users
          const fetchedMentions =
            await getMentionFidsByUsernames(API_URL)(uniqueUsernames);

          const mentionsToFids = fetchedMentions.reduce(
            (acc, mention) => {
              if (mention && mention.username && mention.fid) {
                acc[mention.username] = mention.fid.toString(); // Convert fid to string
              }
              return acc;
            },
            {} as { [key: string]: string },
          );

          const mentionsPositions: number[] = [];

          // Traverse mentions and track positions while replacing them in the working text
          let currentTextIndex = 0;
          let finalText = text; // Keep the original text to display but update mention positions

          // for (const mention of usernamesWithPositions) {
          //   const { username, position } = mention;

          //   // As we find each mention, update the positions list
          //   const mentionIndex = finalText.indexOf(username, currentTextIndex);
          //   if (mentionIndex !== -1) {
          //     mentionsPositions.push(mentionIndex); // Log the position for each mention
          //     currentTextIndex = mentionIndex + username.length; // Move forward in the text

          //     // Optionally, remove the duplicate `@username` from the final text (visible text)
          //     finalText = finalText.replace(`@${username}`, ``); // Keep one `@`
          //   }
          // }

          for (const mention of usernamesWithPositions) {
            const { username, position } = mention;

            // As we find each mention, update the positions list
            const mentionIndex = finalText.indexOf(username, currentTextIndex);
            if (mentionIndex !== -1) {
              mentionsPositions.push(mentionIndex - 1); // Log the position for each mention
              currentTextIndex = mentionIndex + username.length; // Move forward in the text
            }
          }

          for (const mention of usernamesWithPositions) {
            const { username, position } = mention;
            // Optionally, remove the duplicate `@username` from the final text (visible text)
            finalText = finalText.replace(`@${username}`, ``); // Keep one `@`
          }

          if (Object.keys(mentionsToFids).length !== mentionsPositions.length) {
            console.error(
              "Mismatch between mentions and their positions:",
              mentionsToFids,
              mentionsPositions,
            );
          }

          // Update the draft with recalculated text and positions
          setDraft((prevDraft) => {
            const updatedDraft = {
              ...prevDraft,
              text: finalText, // Use the modified text for submission
              embeds: newEmbeds,
              parentUrl: channel?.parent_url || undefined,
              mentionsToFids, // Correct FIDs
              mentionsPositions, // Final recalculated positions
            };
            console.log("Updated Draft before posting:", updatedDraft);
            return updatedDraft;
          });
        } catch (error) {
          console.error("Error fetching FIDs:", error);
        }
      }
    };
    
    ``` 
    
    and then we still need to refactor the original mentionList now in our code so it can handle Mouse commands.
 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: In Progress
Development

No branches or pull requests

2 participants