diff --git a/lib/pages/chat/events/html_message.dart b/lib/pages/chat/events/html_message.dart
index 61f9e1065..5bd4ef9bc 100644
--- a/lib/pages/chat/events/html_message.dart
+++ b/lib/pages/chat/events/html_message.dart
@@ -1,8 +1,11 @@
import 'package:collection/collection.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/pages/chat/chat.dart';
+import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/rendering.dart';
import 'package:flutter_highlighter/flutter_highlighter.dart';
import 'package:flutter_highlighter/themes/shades-of-purple.dart';
import 'package:flutter_html/flutter_html.dart';
@@ -18,12 +21,22 @@ class HtmlMessage extends StatelessWidget {
final String html;
final Room room;
final Color textColor;
+ // #Pangea
+ final bool isOverlay;
+ final PangeaMessageEvent? pangeaMessageEvent;
+ final ChatController controller;
+ // Pangea#
const HtmlMessage({
super.key,
required this.html,
required this.room,
this.textColor = Colors.black,
+ // #Pangea
+ required this.isOverlay,
+ this.pangeaMessageEvent,
+ required this.controller,
+ // Pangea#
});
dom.Node _linkifyHtml(dom.Node element) {
@@ -76,21 +89,16 @@ class HtmlMessage extends StatelessWidget {
// there is no need to pre-validate the html, as we validate it while rendering
// #Pangea
- return MouseRegion(
- // onHover: messageToolbar?.onMouseRegionUpdate,
- child: SelectionArea(
- // onSelectionChanged: (SelectedContent? selection) =>
- // messageToolbar?.onTextSelection(
- // selectedContent: selection,
- // context: context,
- // ),
- // focusNode: messageToolbar?.focusNode,
- // contextMenuBuilder: (context, state) =>
- // messageToolbar?.contextMenuOverride(
- // context: context,
- // contentSelection: state,
- // ) ??
- // const SizedBox(),
+ return SelectionArea(
+ onSelectionChanged: (SelectedContent? selection) {
+ controller.textSelection.onSelection(selection?.plainText);
+ },
+ child: GestureDetector(
+ onTap: () {
+ if (pangeaMessageEvent != null && !isOverlay) {
+ controller.showToolbar(pangeaMessageEvent!);
+ }
+ },
// Pangea#
child: Html.fromElement(
documentElement: element as dom.Element,
@@ -173,11 +181,6 @@ class HtmlMessage extends StatelessWidget {
),
),
);
- // ),
- // ],
- // ),
- // ),
- // );
}
static const Set fallbackTextTags = {'tg-forward'};
@@ -303,7 +306,6 @@ class ImageExtension extends HtmlExtension {
uri: mxcUrl,
width: width ?? height ?? defaultDimension,
height: height ?? width ?? defaultDimension,
- cacheKey: mxcUrl.toString(),
),
),
);
diff --git a/lib/pages/chat/events/message_content.dart b/lib/pages/chat/events/message_content.dart
index ae20d7a20..92bde721b 100644
--- a/lib/pages/chat/events/message_content.dart
+++ b/lib/pages/chat/events/message_content.dart
@@ -3,13 +3,13 @@ import 'dart:math';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/pages/chat/events/video_player.dart';
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
+import 'package:fluffychat/pangea/widgets/chat/message_toolbar.dart';
import 'package:fluffychat/pangea/widgets/igc/pangea_rich_text.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
@@ -205,6 +205,11 @@ class MessageContent extends StatelessWidget {
html: html,
textColor: textColor,
room: event.room,
+ // #Pangea
+ isOverlay: isOverlay,
+ controller: controller,
+ pangeaMessageEvent: pangeaMessageEvent,
+ // Pangea#
);
}
// else we fall through to the normal message rendering
@@ -285,8 +290,8 @@ class MessageContent extends StatelessWidget {
final bigEmotes = event.onlyEmotes &&
event.numberEmotes > 0 &&
event.numberEmotes <= 10;
+
// #Pangea
- // return Linkify(
final messageTextStyle = TextStyle(
overflow: TextOverflow.ellipsis,
color: textColor,
@@ -314,38 +319,36 @@ class MessageContent extends StatelessWidget {
),
);
}
+ // Pangea#
- return SelectableLinkify(
- onSelectionChanged: (selection, cause) {
- if (isOverlay) {
- controller.textSelection.onTextSelection(selection);
- }
- },
- onTap: () {
- if (pangeaMessageEvent != null && !isOverlay) {
- HapticFeedback.mediumImpact();
- controller.showToolbar(pangeaMessageEvent!);
- }
- },
- enableInteractiveSelection: isOverlay,
- // Pangea#
- text: event.calcLocalizedBodyFallback(
- MatrixLocals(L10n.of(context)!),
- hideReply: true,
+ return
+ // #Pangea
+ ToolbarSelectionArea(
+ controller: controller,
+ pangeaMessageEvent: pangeaMessageEvent,
+ isOverlay: isOverlay,
+ child:
+ // Pangea#
+ Linkify(
+ text: event.calcLocalizedBodyFallback(
+ MatrixLocals(L10n.of(context)!),
+ hideReply: true,
+ ),
+ style: TextStyle(
+ color: textColor,
+ fontSize: bigEmotes ? fontSize * 3 : fontSize,
+ decoration:
+ event.redacted ? TextDecoration.lineThrough : null,
+ ),
+ options: const LinkifyOptions(humanize: false),
+ linkStyle: TextStyle(
+ color: textColor.withAlpha(150),
+ fontSize: bigEmotes ? fontSize * 3 : fontSize,
+ decoration: TextDecoration.underline,
+ decorationColor: textColor.withAlpha(150),
+ ),
+ onOpen: (url) => UrlLauncher(context, url.url).launchUrl(),
),
- style: TextStyle(
- color: textColor,
- fontSize: bigEmotes ? fontSize * 3 : fontSize,
- decoration: event.redacted ? TextDecoration.lineThrough : null,
- ),
- options: const LinkifyOptions(humanize: false),
- linkStyle: TextStyle(
- color: textColor.withAlpha(150),
- fontSize: bigEmotes ? fontSize * 3 : fontSize,
- decoration: TextDecoration.underline,
- decorationColor: textColor.withAlpha(150),
- ),
- onOpen: (url) => UrlLauncher(context, url.url).launchUrl(),
);
}
case EventTypes.CallInvite:
diff --git a/lib/pangea/widgets/chat/message_text_selection.dart b/lib/pangea/widgets/chat/message_text_selection.dart
index 6263738f4..0a332a545 100644
--- a/lib/pangea/widgets/chat/message_text_selection.dart
+++ b/lib/pangea/widgets/chat/message_text_selection.dart
@@ -1,8 +1,5 @@
import 'dart:async';
-import 'package:flutter/foundation.dart';
-import 'package:flutter/services.dart';
-
class MessageTextSelection {
String? selectedText;
String messageText = "";
@@ -13,23 +10,17 @@ class MessageTextSelection {
messageText = text;
}
- void onTextSelection(TextSelection selection) => selection.isCollapsed == true
+ void onSelection(String? text) => text == null || text.isEmpty
? clearTextSelection()
- : setTextSelection(selection);
+ : setTextSelection(text);
- void setTextSelection(TextSelection selection) {
- selectedText = selection.textInside(messageText);
- if (BrowserContextMenu.enabled && kIsWeb) {
- BrowserContextMenu.disableContextMenu();
- }
+ void setTextSelection(String selection) {
+ selectedText = selection;
selectionStream.add(selectedText);
}
void clearTextSelection() {
selectedText = null;
- if (kIsWeb && !BrowserContextMenu.enabled) {
- BrowserContextMenu.enableContextMenu();
- }
selectionStream.add(selectedText);
}
diff --git a/lib/pangea/widgets/chat/message_toolbar.dart b/lib/pangea/widgets/chat/message_toolbar.dart
index 943269bdb..2bdfe6b7a 100644
--- a/lib/pangea/widgets/chat/message_toolbar.dart
+++ b/lib/pangea/widgets/chat/message_toolbar.dart
@@ -14,6 +14,7 @@ import 'package:fluffychat/pangea/widgets/igc/word_data_card.dart';
import 'package:fluffychat/pangea/widgets/practice_activity/practice_activity_card.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/rendering.dart';
class MessageToolbar extends StatefulWidget {
final MessageTextSelection textSelection;
@@ -276,3 +277,35 @@ class MessageToolbarState extends State {
);
}
}
+
+class ToolbarSelectionArea extends StatelessWidget {
+ final ChatController controller;
+ final PangeaMessageEvent? pangeaMessageEvent;
+ final bool isOverlay;
+ final Widget child;
+
+ const ToolbarSelectionArea({
+ required this.controller,
+ this.pangeaMessageEvent,
+ this.isOverlay = false,
+ required this.child,
+ super.key,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return SelectionArea(
+ onSelectionChanged: (SelectedContent? selection) {
+ controller.textSelection.onSelection(selection?.plainText);
+ },
+ child: GestureDetector(
+ onTap: () {
+ if (pangeaMessageEvent != null && !isOverlay) {
+ controller.showToolbar(pangeaMessageEvent!);
+ }
+ },
+ child: child,
+ ),
+ );
+ }
+}
diff --git a/lib/pangea/widgets/igc/pangea_rich_text.dart b/lib/pangea/widgets/igc/pangea_rich_text.dart
index 3ff10d4c7..0115f2f6c 100644
--- a/lib/pangea/widgets/igc/pangea_rich_text.dart
+++ b/lib/pangea/widgets/igc/pangea_rich_text.dart
@@ -8,6 +8,7 @@ import 'package:fluffychat/pangea/enum/instructions_enum.dart';
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
import 'package:fluffychat/pangea/models/representation_content_model.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
+import 'package:fluffychat/pangea/widgets/chat/message_toolbar.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@@ -134,37 +135,31 @@ class PangeaRichTextState extends State {
}
//TODO - take out of build function of every message
- final Widget richText = SelectableText.rich(
- onSelectionChanged: (selection, cause) {
- if (widget.isOverlay) {
- widget.controller.textSelection.onTextSelection(selection);
- }
- },
- onTap: () {
- if (!widget.isOverlay) {
- widget.controller.showToolbar(widget.pangeaMessageEvent);
- }
- },
- enableInteractiveSelection: widget.isOverlay,
- TextSpan(
- text: textSpan,
- style: widget.style,
- children: [
- if (_fetchingRepresentation)
- const WidgetSpan(
- child: Padding(
- padding: EdgeInsets.only(left: 5.0),
- child: SizedBox(
- height: 14,
- width: 14,
- child: CircularProgressIndicator(
- strokeWidth: 2.0,
- color: AppConfig.secondaryColor,
+ final Widget richText = ToolbarSelectionArea(
+ isOverlay: widget.isOverlay,
+ pangeaMessageEvent: widget.pangeaMessageEvent,
+ controller: widget.controller,
+ child: RichText(
+ text: TextSpan(
+ text: textSpan,
+ style: widget.style,
+ children: [
+ if (_fetchingRepresentation)
+ const WidgetSpan(
+ child: Padding(
+ padding: EdgeInsets.only(left: 5.0),
+ child: SizedBox(
+ height: 14,
+ width: 14,
+ child: CircularProgressIndicator(
+ strokeWidth: 2.0,
+ color: AppConfig.secondaryColor,
+ ),
),
),
),
- ),
- ],
+ ],
+ ),
),
);