Allow Links to be Selectable / Fix Performance of Message Row to prevent Spurious Renders

This commit is contained in:
Sarah Jamie Lewis 2022-12-29 12:48:12 -08:00 committed by Gitea
parent 7bcde5a1fa
commit 23ae1ac0bb
3 changed files with 36 additions and 26 deletions

View File

@ -123,6 +123,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
key: Key('app'), key: Key('app'),
navigatorKey: navKey, navigatorKey: navKey,
locale: settings.locale, locale: settings.locale,
showPerformanceOverlay: false,
localizationsDelegates: <LocalizationsDelegate<dynamic>>[ localizationsDelegates: <LocalizationsDelegate<dynamic>>[
AppLocalizations.delegate, AppLocalizations.delegate,
MaterialLocalizationDelegate(), MaterialLocalizationDelegate(),

View File

@ -122,12 +122,15 @@ class Linkify extends StatelessWidget {
linkifiers: linkifiers, linkifiers: linkifiers,
); );
return Text.rich( return SelectionArea(
buildTextSpan( child: RichText(
selectionRegistrar: SelectionContainer.maybeOf(context),
text: buildTextSpan(
elements, elements,
style: Theme.of(context).textTheme.bodyText2?.merge(style), style: Theme.of(context).textTheme.bodyText2?.merge(style),
onOpen: onOpen, onOpen: onOpen,
useMouseRegion: true, useMouseRegion: true,
context: context,
linkStyle: Theme.of(context) linkStyle: Theme.of(context)
.textTheme .textTheme
.bodyText2 .bodyText2
@ -148,7 +151,7 @@ class Linkify extends StatelessWidget {
locale: locale, locale: locale,
textWidthBasis: textWidthBasis, textWidthBasis: textWidthBasis,
textHeightBehavior: textHeightBehavior, textHeightBehavior: textHeightBehavior,
); ));
} }
} }
@ -297,6 +300,7 @@ class SelectableLinkify extends StatelessWidget {
style: Theme.of(context).textTheme.bodyText2?.merge(style), style: Theme.of(context).textTheme.bodyText2?.merge(style),
codeStyle: Theme.of(context).textTheme.bodyText2?.merge(codeStyle), codeStyle: Theme.of(context).textTheme.bodyText2?.merge(codeStyle),
onOpen: onOpen, onOpen: onOpen,
context: context,
linkStyle: Theme.of(context) linkStyle: Theme.of(context)
.textTheme .textTheme
.bodyText2 .bodyText2
@ -337,11 +341,13 @@ class LinkableSpan extends WidgetSpan {
LinkableSpan({ LinkableSpan({
required MouseCursor mouseCursor, required MouseCursor mouseCursor,
required InlineSpan inlineSpan, required InlineSpan inlineSpan,
required BuildContext context,
}) : super( }) : super(
child: MouseRegion( child: MouseRegion(
cursor: mouseCursor, cursor: mouseCursor,
child: Text.rich( child: RichText(
inlineSpan, text: inlineSpan,
selectionRegistrar: SelectionContainer.maybeOf(context),
), ),
), ),
); );
@ -354,6 +360,7 @@ TextSpan buildTextSpan(
TextStyle? linkStyle, TextStyle? linkStyle,
TextStyle? codeStyle, TextStyle? codeStyle,
LinkCallback? onOpen, LinkCallback? onOpen,
required BuildContext context,
bool useMouseRegion = false, bool useMouseRegion = false,
}) { }) {
return TextSpan( return TextSpan(
@ -361,20 +368,18 @@ TextSpan buildTextSpan(
(element) { (element) {
if (element is LinkableElement) { if (element is LinkableElement) {
if (useMouseRegion) { if (useMouseRegion) {
return TooltipSpan( return TextSpan(
message: element.url, text: element.text,
inlineSpan: LinkableSpan( style: linkStyle,
mouseCursor: SystemMouseCursors.click, mouseCursor: SystemMouseCursors.click,
inlineSpan: TextSpan(text: element.text, style: linkStyle, recognizer: onOpen != null ? (TapGestureRecognizer()..onTap = () => onOpen(element)) : null, semanticsLabel: element.text), recognizer: onOpen != null ? (TapGestureRecognizer()..onTap = () => onOpen(element)) : null,
)); semanticsLabel: element.text);
} else { } else {
return TooltipSpan( return TextSpan(
message: element.url, text: element.text,
inlineSpan: TextSpan( style: linkStyle,
text: element.text, recognizer: onOpen != null ? (TapGestureRecognizer()..onTap = () => onOpen(element)) : null,
style: linkStyle, );
recognizer: onOpen != null ? (TapGestureRecognizer()..onTap = () => onOpen(element)) : null,
));
} }
} else if (element is BoldElement) { } else if (element is BoldElement) {
return TextSpan(text: element.text.replaceAll("*", ""), style: style?.copyWith(fontWeight: FontWeight.bold), semanticsLabel: element.text); return TextSpan(text: element.text.replaceAll("*", ""), style: style?.copyWith(fontWeight: FontWeight.bold), semanticsLabel: element.text);
@ -428,11 +433,13 @@ class TooltipSpan extends WidgetSpan {
TooltipSpan({ TooltipSpan({
required String message, required String message,
required InlineSpan inlineSpan, required InlineSpan inlineSpan,
required BuildContext context,
}) : super( }) : super(
child: Tooltip( child: Tooltip(
message: message, message: message,
child: Text.rich( child: RichText(
inlineSpan, text: inlineSpan,
selectionRegistrar: SelectionContainer.maybeOf(context),
), ),
), ),
); );

View File

@ -215,14 +215,16 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
var mr = MouseRegion( var mr = MouseRegion(
// For desktop... // For desktop...
onHover: (event) { onHover: (event) {
setState(() { if (Provider.of<AppState>(context, listen: false).hoveredIndex != Provider.of<MessageMetadata>(context, listen: false).messageID) {
Provider.of<AppState>(context, listen: false).hoveredIndex = Provider.of<MessageMetadata>(context, listen: false).messageID; setState(() {
}); Provider.of<AppState>(context, listen: false).hoveredIndex = Provider.of<MessageMetadata>(context, listen: false).messageID;
});
}
}, },
onExit: (event) { onExit: (event) {
setState(() { // setState(() {
Provider.of<AppState>(context, listen: false).hoveredIndex = -1; // Provider.of<AppState>(context, listen: false).hoveredIndex = -1;
}); //});
}, },
child: GestureDetector( child: GestureDetector(
onPanUpdate: (details) { onPanUpdate: (details) {