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

Fix lagging when scrolling #2

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 28 additions & 143 deletions lib/src/matrix_linkify.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,160 +6,43 @@ import 'package:linkfy_text/src/utils/matrix_regex.dart';

/// Matrix Linkify [text] containing urls, emails or hashtag
class MatrixLinkifyText extends StatelessWidget {
const MatrixLinkifyText(
this.text, {
this.textStyle,
this.linkStyle,
this.linkTypes,
this.onTap,
this.customLinkStyles,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaler,
this.maxLines,
this.semanticsLabel,
this.textWidthBasis,
Key? key,
this.onTapDownLink,
this.themeData,
}) : super(key: key);

/// text to be linkified
final String text;

/// [textStyle] applied the text
final TextStyle? textStyle;

/// [textStyle] added to the formatted links in the text
final TextStyle? linkStyle;

/// called when a formatted link is pressed, it returns the link as a parameter
/// ```dart
/// LinkifyText("#helloWorld", onTap: (link) {
/// // do stuff with link
/// print("${link.value} hashtag was tapped");
/// });
/// ```
final void Function(Link)? onTap;

/// option to override the links to be formatted in the text, defaults to `[LinkType.url]`
/// so only urls are being linkified in the text
final List<LinkType>? linkTypes;

/// {@macro flutter.painting.textPainter.strutStyle}
final StrutStyle? strutStyle;

/// How the text should be aligned horizontally.
final TextAlign? textAlign;

/// The directionality of the text.
///
/// This decides how [textAlign] values like [TextAlign.start] and
/// [TextAlign.end] are interpreted.
///
/// This is also used to disambiguate how to render bidirectional text. For
/// example, if the [data] is an English phrase followed by a Hebrew phrase,
/// in a [TextDirection.ltr] context the English phrase will be on the left
/// and the Hebrew phrase to its right, while in a [TextDirection.rtl]
/// context, the English phrase will be on the right and the Hebrew phrase on
/// its left.
///
/// Defaults to the ambient [Directionality], if any.
final TextDirection? textDirection;

/// Used to select a font when the same Unicode character can
/// be rendered differently, depending on the locale.
///
/// It's rarely necessary to set this property. By default its value
/// is inherited from the enclosing app with `Localizations.localeOf(context)`.
///
/// See [RenderParagraph.locale] for more information.
final Locale? locale;

/// Whether the text should break at soft line breaks.
///
/// If false, the glyphs in the text will be positioned as if there was unlimited horizontal space.
final bool? softWrap;

/// How visual overflow should be handled.
///
/// Defaults to retrieving the value from the nearest [DefaultTextStyle] ancestor.
final TextOverflow? overflow;

/// The number of font pixels for each logical pixel.
///
/// For example, if the text scale factor is 1.5, text will be 50% larger than
/// the specified font size.
///
/// The value given to the constructor as textScaleFactor. If null, will
/// use the [MediaQueryData.textScaler] obtained from the ambient
/// [MediaQuery], or 1.0 if there is no [MediaQuery] in scope.
final TextScaler? textScaler;

/// An optional maximum number of lines for the text to span, wrapping if necessary.
/// If the text exceeds the given number of lines, it will be truncated according
/// to [overflow].
///
/// If this is 1, text will not wrap. Otherwise, text will be wrapped at the
/// edge of the box.
///
/// If this is null, but there is an ambient [DefaultTextStyle] that specifies
/// an explicit number for its [DefaultTextStyle.maxLines], then the
/// [DefaultTextStyle] value will take precedence. You can use a [RichText]
/// widget directly to entirely override the [DefaultTextStyle].
final List<LinkType>? linkTypes;
final ThemeData? themeData;
final Function(Link)? onTapLink;
final Function(TapDownDetails, Link)? onTapDownLink;
final int? maxLines;

/// An alternative semantics label for this text.
///
/// If present, the semantics of this widget will contain this value instead
/// of the actual text. This will overwrite any of the semantics labels applied
/// directly to the [TextSpan]s.
///
/// This is useful for replacing abbreviations or shorthands with the full
/// text value:
///
/// ```dart
/// Text(r'$$', semanticsLabel: 'Double dollars')
/// ```
final String? semanticsLabel;

/// {@macro flutter.painting.textPainter.textWidthBasis}
final TextWidthBasis? textWidthBasis;

final Map<LinkType, TextStyle>? customLinkStyles;

final void Function(TapDownDetails, Link)? onTapDownLink;

final ThemeData? themeData;
const MatrixLinkifyText({
Key? key,
required this.text,
this.textStyle,
this.linkStyle,
this.textAlign = TextAlign.start,
this.maxLines,
this.linkTypes,
this.themeData,
this.onTapLink,
this.onTapDownLink,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return Text.rich(
return CleanRichText(
LinkifyTextSpans(
text: text,
textStyle: textStyle,
linkStyle: linkStyle,
onTapLink: onTap,
onTapDownLink: onTapDownLink,
themeData: themeData,
linkTypes: linkTypes,
customLinkStyles: customLinkStyles,
themeData: themeData,
onTapLink: onTapLink,
onTapDownLink: onTapDownLink,
),
key: key,
style: textStyle,
strutStyle: strutStyle,
textAlign: textAlign,
textDirection: textDirection,
textScaler: textScaler,
textWidthBasis: textWidthBasis,
semanticsLabel: semanticsLabel,
softWrap: softWrap,
overflow: overflow,
maxLines: maxLines,
locale: locale,
);
}
}
Expand Down Expand Up @@ -291,25 +174,26 @@ TextSpan LinkifyTextSpans({
decoration: TextDecoration.underline,
);

final _regExp =
constructMatrixRegExpFromLinkType(linkTypes ?? [LinkType.url]);
final regExp = constructMatrixRegExpFromLinkType(linkTypes ?? [LinkType.url]);

// return the full text if there's no match or if empty
if (!_regExp.hasMatch(text) || text.isEmpty) {
if (!regExp.hasMatch(text) || text.isEmpty) {
return TextSpan(
text: text,
style: textStyle,
children: const [],
);
}

final texts = text.split(_regExp);
final texts = text.split(regExp);
final List<InlineSpan> spans = [];
final highlights = _regExp.allMatches(text).toList();
final highlights = regExp.allMatches(text).toList();

for (final text in texts) {
spans.add(TextSpan(
text: text,
style: textStyle,
children: const [],
));

if (highlights.isNotEmpty) {
Expand All @@ -319,6 +203,7 @@ TextSpan LinkifyTextSpans({
spans.add(TextSpan(
text: link.value,
style: textStyle,
children: const [],
));
continue;
}
Expand Down