react-native-autolink icon indicating copy to clipboard operation
react-native-autolink copied to clipboard

Matching `@username` formatted usernames encounters collisions with generated token strings

Open mhuggins opened this issue 7 months ago • 3 comments

Hello, thank you for sharing this package!

I am trying to match several patterns of strings within a body of text, namely:

  1. Hash tags (e.g.: #programming),
  2. User names (e.g.: @mhuggins), and
  3. URLs.

I've defined three custom matchers as part of a wrapper component:

import { router } from 'expo-router';
import { Linking, StyleProp, TextStyle } from 'react-native';
import Autolink, { CustomMatcher } from 'react-native-autolink';

const linkStyle: StyleProp<TextStyle> = {
  color: '#0a7ea4',
};

const HashTagMatcher: CustomMatcher = {
  pattern: /#([a-z0-9_\-]+)/g,
  style: linkStyle,
  getLinkText: (replacerArgs) => `#${replacerArgs[1]}`,
  onPress: (match) => {
    const tag = match.getReplacerArgs()[1];
    router.navigate(`/tags/${encodeURIComponent(tag)}`);
  },
};

const UserMatcher: CustomMatcher = {
  pattern: /@([a-z0-9_\.]+)/g,
  style: linkStyle,
  getLinkText: (replacerArgs) => `@${replacerArgs[1]}`,
  onPress: (match) => {
    const userId = match.getReplacerArgs()[1];
    router.navigate(`/users/${encodeURIComponent(userId)}`);
  },
};

const UrlMatcher: CustomMatcher = {
  pattern: /https?:\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])/g,
  style: linkStyle,
  getLinkText: (replacerArgs) => replacerArgs[0],
  onPress: (match) => {
    const url = match.getMatchedText();
    Linking.openURL(url);
  },
};

const matchers: CustomMatcher[] = [HashTagMatcher, UserMatcher, UrlMatcher];

export const PostBody = ({ text }: { text: string }) => (
  <Autolink text={text} matchers={matchers} />
);

I then try to use this on a code of text, e.g.:

I am linking to https://google.com because I'm a #corporateshill. All hail @google!

This ends up replacing some matched elements with tokens in the format @__ELEMENT-${uid}-\\d+__@, at which point my HashTagMatcher matches against combinations of string created from these tokens such as @__ and @..

Screenshot 2024-07-10 at 8 52 32 AM

Is there an existing way to avoid this, or is this a bug that needs to be reconciled?

mhuggins avatar Jul 10 '24 13:07 mhuggins