new linkify handling
Should fix mentions in non-HTML messages
This commit is contained in:
parent
bcb0c57015
commit
40f5d0f459
3 changed files with 123 additions and 42 deletions
|
|
@ -1,26 +1,46 @@
|
|||
import "package:flutter/gestures.dart";
|
||||
import "package:material_ui/material_ui.dart";
|
||||
import "package:flutter_linkify/flutter_linkify.dart";
|
||||
import "package:linkify/linkify.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/helpers/extensions/get_link_info.dart";
|
||||
import "package:nexus/helpers/launch_helper.dart";
|
||||
import "package:nexus/helpers/matrix_linkifier.dart";
|
||||
import "package:nexus/widgets/html/mention_chip.dart";
|
||||
|
||||
final class const LinkifiedText(
|
||||
final String text, {
|
||||
final String? roomId,
|
||||
final int? maxLines,
|
||||
final TextStyle? style,
|
||||
super.key,
|
||||
}) extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) =>
|
||||
MaterialUiCompatibilityBridge(
|
||||
child: Linkify(
|
||||
text: text,
|
||||
maxLines: maxLines,
|
||||
style: style,
|
||||
options: .new(humanize: false),
|
||||
onOpen: (link) =>
|
||||
ref.read(LaunchHelper.provider).launchUrl(.parse(link.url)),
|
||||
linkStyle: .new(color: Theme.of(context).colorScheme.primary),
|
||||
overflow: maxLines == null ? null : .ellipsis,
|
||||
),
|
||||
);
|
||||
Widget build(BuildContext context, WidgetRef ref) => Text.rich(
|
||||
TextSpan(
|
||||
style: style,
|
||||
children: linkifyText(text)
|
||||
.map<InlineSpan>(
|
||||
(element) => switch (element) {
|
||||
LinkableElement(:final url) when url.linkInfo != null =>
|
||||
WidgetSpan(
|
||||
alignment: .baseline,
|
||||
baseline: .alphabetic,
|
||||
child: MentionChip(url, roomId),
|
||||
),
|
||||
LinkableElement(:final text, :final url) => TextSpan(
|
||||
text: text,
|
||||
style: .new(color: Theme.of(context).colorScheme.primary),
|
||||
mouseCursor: SystemMouseCursors.click,
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () =>
|
||||
ref.read(LaunchHelper.provider).launchUrl(.parse(url)),
|
||||
),
|
||||
_ => TextSpan(text: element.text),
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
maxLines: maxLines,
|
||||
overflow: maxLines == null ? null : .ellipsis,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import "package:linkify/linkify.dart";
|
|||
import "package:nexus/controllers/client_state.dart";
|
||||
import "package:nexus/controllers/event.dart";
|
||||
import "package:nexus/helpers/extensions/get_filename.dart";
|
||||
import "package:nexus/helpers/extensions/linkify_html.dart";
|
||||
import "package:nexus/models/content/encrypted.dart";
|
||||
import "package:nexus/models/content/message.dart";
|
||||
import "package:nexus/models/content/sticker.dart";
|
||||
|
|
@ -77,26 +78,11 @@ class const MessageRenderer(
|
|||
? Html(
|
||||
roomId: event.roomId,
|
||||
textStyle: textStyle,
|
||||
formattedBody.replaceAllMapped(
|
||||
RegExp(
|
||||
r"(<a\b[^>]*>.*?<\/a>)|(\bhttps?:\/\/[^\s<]+)",
|
||||
caseSensitive: false,
|
||||
dotAll: true,
|
||||
),
|
||||
(m) {
|
||||
// If it's already an <a> tag, leave it unchanged
|
||||
if (m.group(1) != null) {
|
||||
return m.group(1)!;
|
||||
}
|
||||
|
||||
// Otherwise, wrap the bare URL
|
||||
final url = m.group(2)!;
|
||||
return "<a href=\"$url\">$url</a>";
|
||||
},
|
||||
),
|
||||
formattedBody.linkifiedHtml,
|
||||
)
|
||||
: LinkifiedText(
|
||||
body.isEmpty ? content.filename ?? "" : body,
|
||||
roomId: event.roomId,
|
||||
style: textStyle,
|
||||
maxLines: maxLines,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ class const RoomSummarySheet(
|
|||
if (summary.topic != null)
|
||||
ListTile(
|
||||
title: Text("Topic"),
|
||||
subtitle: LinkifiedText(summary.topic!),
|
||||
subtitle: LinkifiedText(summary.topic!, roomId: summary.roomId),
|
||||
leading: Icon(Icons.info),
|
||||
),
|
||||
if (isKnocking)
|
||||
|
|
|
|||
Loading…
Reference in a new issue