2000calories / flutter_easy_rich_text

The EasyRichText widget provides an easy way to use RichText.
https://pub.dev/packages/easy_rich_text
MIT License
79 stars 34 forks source link

tap gesture not getting fired #55

Open nergal79 opened 6 months ago

nergal79 commented 6 months ago
 `Widget build(BuildContext context) {
  final linkStyle = TextStyle(
  color: linkColor,
  decorationColor: linkColor,
   decoration: TextDecoration.underline,
   );

return EasyRichText(
  text,
  defaultStyle: style,
  maxLines: maxLines,
  overflow: maxLines == null ? TextOverflow.clip : TextOverflow.ellipsis,
  patternList: [
    EasyRichTextPattern(
        targetString: EasyRegexPattern.emailPattern,
        urlType: 'email',
        style: linkStyle),
    EasyRichTextPattern(
      targetString: EasyRegexPattern.webPattern,
      urlType: 'web',
      style: linkStyle,
    ),
    EasyRichTextPattern(
      targetString: Constants.patternPhone,
      urlType: 'tel',
      style: linkStyle,
    ),
    EasyRichTextPattern(
      targetString: '(\\*)(.*?)(\\*)',
      matchBuilder: (BuildContext context, RegExpMatch? match) {
        return TextSpan(
          text: match?[0]?.replaceAll('*', ''),
          style: const TextStyle(
            fontWeight: FontWeight.bold,
          ),
        );
      },
    ),

    ///italic font
    EasyRichTextPattern(
      targetString: '(_)(.*?)(_)',
      matchBuilder: (BuildContext context, RegExpMatch? match) {
        return TextSpan(
          text: match?[0]?.replaceAll('_', ''),
          style: const TextStyle(fontStyle: FontStyle.italic),
        );
      },
    ),

    ///strikethrough
    EasyRichTextPattern(
      targetString: '(~)(.*?)(~)',
      matchBuilder: (BuildContext context, RegExpMatch? match) {
        return TextSpan(
          text: match?[0]?.replaceAll('~', ''),
          style: TextStyle(
            color: style.color,
            decorationColor: style.color,
            decoration: TextDecoration.lineThrough,
          ),
        );
      },
    )
  ],
);

} }`

flutter doctor

Doctor summary (to see all details, run flutter doctor -v): [√] Flutter (Channel stable, 3.16.9, on Microsoft Windows [Version 10.0.22631.3296], locale en-IN) [√] Windows Version (Installed version of Windows is version 10 or higher) [!] Android toolchain - develop for Android devices (Android SDK version 34.0.0) X cmdline-tools component is missing Runpath/to/sdkmanager --install "cmdline-tools;latest" See https://developer.android.com/studio/command-line for more details. X Android license status unknown. Runflutter doctor --android-licenses` to accept the SDK licenses. See https://flutter.dev/docs/get-started/install/windows#android-setup for more details. [√] Chrome - develop for the web [X] Visual Studio - develop Windows apps X Visual Studio not installed; this is necessary to develop Windows apps. Download at https://visualstudio.microsoft.com/downloads/. Please install the "Desktop development with C++" workload, including all of its default components [√] Android Studio (version 2023.2) [√] IntelliJ IDEA Community Edition (version 2023.2) [√] VS Code (version 1.87.2) [√] Connected device (4 available) [√] Network resources

! Doctor found issues in 2 categories. `

I m using this text widget in Chat list just like whats app .. I can see all text(email, phone, links ) underlined but nothing happens when i click them .. Weird things is when i comment out last 3 patterns some how phone number , email and link starts working. Is this a library bug ? Can u pls advise what might be wrong here .

nergal79 commented 5 months ago

@2000calories Checking in again . Is this a library limitation ? Can't we use these bold/italic regEx with email, link and phone regEx ? Or somehow its getting overridden . In any case Pls share your thoughts, I'll be grateful . Thanks .

2000calories commented 5 months ago

Sorry for late reply. There is a conflict if two EasyRichTextPattern target the same text. Here is a workaround. You can implement the link inside the matchBuilder. Since _ (for italic effect) is common in link, I replace it with !.

EasyRichTextPattern(
  targetString: '(\!)(.*?)(\!)',
  matchBuilder: (BuildContext context, RegExpMatch? match) {
    var boldWebText = match?[0]?.replaceAll("\!", '');
    return TextSpan(
      text: boldWebText,
      recognizer: TapGestureRecognizer()
        ..onTap = () async {
          Uri url = Uri.parse(boldWebText!);
          if (await canLaunchUrl(url)) {
            await launchUrl(url);
          }
        },
      style: const TextStyle(
        // fontWeight: FontWeight.bold,
        fontStyle: FontStyle.italic,
        decoration: TextDecoration.underline,
      ),
    );
  },
),
JessMnk commented 5 months ago

Hi, I also have an issue with the pattern detector and the TapGetureRecognizer not being executed. I think my problem comes from the custom pattern I added for username detection because without this block of code the other two work fine.

EasyRichTextPattern(
  targetString: '@' + '[A-Za-z0-9]*',
  matchBuilder: (BuildContext context, RegExpMatch? match) {
    String tagUserName = match[0]!;
    return TextSpan(
        text: tagUserName,
        style: Theme.of(context).textTheme.headline3,
        recognizer: TapGestureRecognizer()
          ..onTap = () {
            print("Tag user");
          });
  },
  style: Theme.of(context).textTheme.headline3,
),

EasyRichTextPattern(
  targetString: EasyRegexPattern.webPattern,
  matchBuilder: (BuildContext context, RegExpMatch? match) {
    String link = match[0]!;

    return TextSpan(
      text: link,
      style: TextStyle(
        color: Colors.green,
        decoration: TextDecoration.underline,
      ),
      recognizer: TapGestureRecognizer()
        ..onTap = () async {
          print("Open link");
        },
    );
  },
),

EasyRichTextPattern(
  targetString: EasyRegexPattern.emailPattern,
  matchBuilder: (context, match) {
    String link = match![0]!;

    return TextSpan(
      text: link,
      style: TextStyle(
        color: Colors.red,
        decoration: TextDecoration.underline,
      ),
      recognizer: TapGestureRecognizer()
        ..onTap = () {
          print("Open Email");
        },
    );
  },
),

I tried reorganising the EasyRichTextPattern classes but it didn't help. Is there anything I can do ? Is my regex the problem ? Thanks !

nergal79 commented 5 months ago

Sorry for late reply. There is a conflict if two EasyRichTextPattern target the same text. Here is a workaround. You can implement the link inside the matchBuilder. Since _ (for italic effect) is common in link, I replace it with !.

EasyRichTextPattern(
  targetString: '(\!)(.*?)(\!)',
  matchBuilder: (BuildContext context, RegExpMatch? match) {
    var boldWebText = match?[0]?.replaceAll("\!", '');
    return TextSpan(
      text: boldWebText,
      recognizer: TapGestureRecognizer()
        ..onTap = () async {
          Uri url = Uri.parse(boldWebText!);
          if (await canLaunchUrl(url)) {
            await launchUrl(url);
          }
        },
      style: const TextStyle(
        // fontWeight: FontWeight.bold,
        fontStyle: FontStyle.italic,
        decoration: TextDecoration.underline,
      ),
    );
  },
),

Thx for reply @2000calories .. I tried your solution but unfortunately it does not work .. have u tried it with provided code above with question ?