re-integrated select defintions with new fluffychat merge

pull/1011/head
ggurdin 2 years ago
parent 84d0dd13b9
commit ad16c6dfef

@ -23,7 +23,6 @@ import 'package:fluffychat/pangea/models/message_data_models.dart';
import 'package:fluffychat/pangea/models/student_analytics_summary_model.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:fluffychat/pangea/utils/firebase_analytics.dart';
import 'package:fluffychat/pangea/utils/instructions.dart';
import 'package:fluffychat/pangea/utils/report_message.dart';
import 'package:fluffychat/pangea/widgets/igc/pangea_text_controller.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
@ -1282,11 +1281,6 @@ class ChatController extends State<ChatPageWithRoom>
if (choreographer.itController.isOpen) {
return;
}
pangeaController.instructions.show(
context,
InstructionsEnum.understandingMessages,
event.eventId,
);
// Pangea#
if (!event.redacted) {
if (selectedEvents.contains(event)) {

@ -1,11 +1,13 @@
import 'package:fluffychat/pages/chat/events/video_player.dart';
import 'package:fluffychat/pangea/models/language_model.dart';
import 'package:fluffychat/pangea/models/pangea_message_event.dart';
import 'package:fluffychat/pangea/utils/show_defintion_util.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:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
@ -36,9 +38,10 @@ class MessageContent extends StatelessWidget {
final LanguageModel? selectedDisplayLang;
final bool immersionMode;
final bool definitions;
ShowDefintionUtil? messageToolbar;
// Pangea#
const MessageContent(
MessageContent(
this.event, {
this.onInfoTab,
super.key,
@ -121,6 +124,18 @@ class MessageContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
// #Pangea
messageToolbar = ShowDefintionUtil(
targetId: pangeaMessageEvent.eventId,
room: pangeaMessageEvent.room,
langCode: selectedDisplayLang?.langCode ??
MatrixState.pangeaController.languageController.activeL2Code(
roomID: pangeaMessageEvent.room.id,
) ??
LanguageModel.unknown.langCode,
messageText: "",
);
// Pangea#
final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
final buttonTextColor = textColor;
switch (event.type) {
@ -263,17 +278,23 @@ class MessageContent extends StatelessWidget {
height: 1.3,
);
if (pangeaMessageEvent.showRichText) {
return PangeaRichText(
return MouseRegion(
onHover: messageToolbar?.onMouseRegionUpdate,
child: PangeaRichText(
existingStyle: messageTextStyle,
selected: selected,
pangeaMessageEvent: pangeaMessageEvent,
immersionMode: immersionMode,
definitions: definitions,
selectedDisplayLang: selectedDisplayLang,
messageToolbar: messageToolbar,
),
);
}
return MouseRegion(
onHover: messageToolbar?.onMouseRegionUpdate,
child: FutureBuilder<String>(
// Pangea#
return FutureBuilder<String>(
future: event.calcLocalizedBody(
MatrixLocals(L10n.of(context)!),
hideReply: true,
@ -289,13 +310,23 @@ class MessageContent extends StatelessWidget {
style: messageTextStyle,
);
}
// Pangea#
return Linkify(
text: snapshot.data ??
// return Linkify(
final String messageText = snapshot.data ??
event.calcLocalizedBodyFallback(
MatrixLocals(L10n.of(context)!),
hideReply: true,
),
);
messageToolbar?.messageText = messageText;
return SelectableLinkify(
// Pangea#
text: messageText,
focusNode: messageToolbar?.focusNode,
contextMenuBuilder: messageToolbar?.contextMenuOverride,
// text: snapshot.data ??
// event.calcLocalizedBodyFallback(
// MatrixLocals(L10n.of(context)!),
// hideReply: true,
// ),
style: TextStyle(
color: textColor,
fontSize: bigEmotes ? fontSize * 3 : fontSize,
@ -310,8 +341,11 @@ class MessageContent extends StatelessWidget {
decorationColor: textColor.withAlpha(150),
),
onOpen: (url) => UrlLauncher(context, url.url).launchUrl(),
onSelectionChanged: (selection, cause) => messageToolbar
?.onTextSelection(selection, cause, context),
);
},
),
);
}
case EventTypes.CallInvite:

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import '../../config/app_config.dart';
@ -96,7 +95,6 @@ class InstructionsController {
enum InstructionsEnum {
itInstructions,
clickMessage,
understandingMessages,
blurMeansTranslate,
}
@ -107,8 +105,6 @@ extension Copy on InstructionsEnum {
return L10n.of(context)!.itInstructionsTitle;
case InstructionsEnum.clickMessage:
return L10n.of(context)!.clickMessageTitle;
case InstructionsEnum.understandingMessages:
return L10n.of(context)!.understandingMessagesTitle;
case InstructionsEnum.blurMeansTranslate:
return L10n.of(context)!.blurMeansTranslateTitle;
}
@ -120,8 +116,6 @@ extension Copy on InstructionsEnum {
return L10n.of(context)!.itInstructionsBody;
case InstructionsEnum.clickMessage:
return L10n.of(context)!.clickMessageBody;
case InstructionsEnum.understandingMessages:
return L10n.of(context)!.understandingMessagesBody;
case InstructionsEnum.blurMeansTranslate:
return L10n.of(context)!.blurMeansTranslateBody;
}

@ -11,13 +11,15 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
class ShowDefintionUtil {
final String messageText;
String messageText;
final String langCode;
final String targetId;
final FocusNode focusNode = FocusNode();
final Room room;
TextSelection? textSelection;
bool inCooldown = false;
double? dx;
double? dy;
ShowDefintionUtil({
required this.targetId,
@ -93,17 +95,18 @@ class ShowDefintionUtil {
Future<dynamic> showToolbar(BuildContext context) async {
final LayerLinkAndKey layerLinkAndKey =
MatrixState.pAnyState.layerLinkAndKey(targetId);
final RenderBox? targetRenderBox =
(layerLinkAndKey.key.currentContext!.findRenderObject() as RenderBox?);
final Size? transformTargetSize = targetRenderBox?.size;
Offset? transformTargetOffset;
if (transformTargetSize != null) {
transformTargetOffset = Offset(
(transformTargetSize.width / 2) - 65,
transformTargetSize.height * -1,
);
final RenderObject? targetRenderBox =
layerLinkAndKey.key.currentContext!.findRenderObject();
final Offset transformTargetOffset =
(targetRenderBox as RenderBox).localToGlobal(Offset.zero);
if (dx != null && dx! > MediaQuery.of(context).size.width - 130) {
dx = MediaQuery.of(context).size.width - 130;
}
final double xOffset = dx != null ? dx! - transformTargetOffset.dx : 0;
final double yOffset =
dy != null ? dy! - transformTargetOffset.dy + 10 : 10;
OverlayUtil.showOverlay(
context: context,
@ -124,7 +127,28 @@ class ShowDefintionUtil {
),
size: const Size(130, 45),
transformTargetId: targetId,
offset: transformTargetOffset,
offset: Offset(xOffset, yOffset),
);
}
void onMouseRegionUpdate(PointerEvent event) {
dx = event.position.dx;
dy = event.position.dy;
}
Widget contextMenuOverride(BuildContext context, EditableTextState selection) {
return AdaptiveTextSelectionToolbar.buttonItems(
anchors: selection.contextMenuAnchors,
buttonItems: [
...selection.contextMenuButtonItems,
ContextMenuButtonItem(
label: L10n.of(context)!.showDefinition,
onPressed: () {
showDefinition(context);
focusNode.unfocus();
},
),
],
);
}
}

@ -1,4 +1,3 @@
import 'dart:async';
import 'dart:developer';
import 'dart:ui';
@ -13,13 +12,13 @@ import 'package:fluffychat/pangea/utils/show_defintion_util.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import '../../models/igc_text_data_model.dart';
import '../../models/language_detection_model.dart';
import '../../models/pangea_match_model.dart';
import '../../models/pangea_representation_event.dart';
import '../../utils/bot_style.dart';
import '../../utils/instructions.dart';
class PangeaRichText extends StatefulWidget {
@ -30,6 +29,7 @@ class PangeaRichText extends StatefulWidget {
final bool immersionMode;
final bool definitions;
final Choreographer? choreographer;
final ShowDefintionUtil? messageToolbar;
const PangeaRichText({
super.key,
@ -40,6 +40,7 @@ class PangeaRichText extends StatefulWidget {
required this.definitions,
this.choreographer,
this.existingStyle,
this.messageToolbar,
});
@override
@ -52,32 +53,30 @@ class PangeaRichTextState extends State<PangeaRichText> {
bool _fetchingTokens = false;
double get blur => _fetchingRepresentation && widget.immersionMode ? 5 : 0;
List<TextSpan> textSpan = [];
ShowDefintionUtil? messageToolbar;
@override
void initState() {
super.initState();
setState(() => textSpan = getTextSpan(context));
updateTextSpan();
}
@override
void didUpdateWidget(PangeaRichText oldWidget) {
super.didUpdateWidget(oldWidget);
setState(() => textSpan = getTextSpan(context));
updateTextSpan();
}
void updateTextSpan() {
setState(() {
textSpan = getTextSpan(context);
widget.messageToolbar?.messageText = textSpan.map((e) => e.text).join();
});
}
@override
Widget build(BuildContext context) {
//TODO - take out of build function of every message
// if (areLanguagesSet) {
messageToolbar = ShowDefintionUtil(
targetId: widget.pangeaMessageEvent.eventId,
room: widget.pangeaMessageEvent.room,
langCode: widget.selectedDisplayLang?.langCode ??
userL2LangCode ??
LanguageKeys.unknownLanguage,
messageText: textSpan.map((x) => x.text).join(),
);
if (!widget.selected &&
widget.selectedDisplayLang != null &&
@ -95,10 +94,16 @@ class PangeaRichTextState extends State<PangeaRichText> {
);
}
final TextSpan richTextSpan = TextSpan(
final Widget richText = SelectableText.rich(
onSelectionChanged: (selection, cause) =>
widget.messageToolbar?.onTextSelection(selection, cause, context),
focusNode: widget.messageToolbar?.focusNode,
contextMenuBuilder: widget.messageToolbar?.contextMenuOverride,
TextSpan(
children: [
...textSpan,
if (widget.selected && (_fetchingRepresentation || _fetchingTokens))
// if (widget.selected)
const WidgetSpan(
child: Padding(
padding: EdgeInsets.only(left: 5.0),
@ -113,32 +118,8 @@ class PangeaRichTextState extends State<PangeaRichText> {
),
),
],
);
final Widget richText = widget.selected
? SelectableText.rich(
richTextSpan,
onSelectionChanged: (selection, cause) => kIsWeb
? messageToolbar?.onTextSelection(selection, cause, context)
: null,
focusNode: messageToolbar?.focusNode,
contextMenuBuilder: (context, selection) {
return AdaptiveTextSelectionToolbar.buttonItems(
anchors: selection.contextMenuAnchors,
buttonItems: [
...selection.contextMenuButtonItems,
ContextMenuButtonItem(
label: L10n.of(context)!.showDefinition,
onPressed: () {
messageToolbar?.showDefinition(context);
messageToolbar?.focusNode.unfocus();
},
),
],
);
},
)
: RichText(text: richTextSpan);
return blur > 0
? ImageFiltered(
@ -222,8 +203,8 @@ class PangeaRichTextState extends State<PangeaRichText> {
userL1: userL1LangCode ?? LanguageKeys.unknownLanguage,
).constructTokenSpan(
context: context,
defaultStyle: widget.existingStyle,
handleClick: true,
defaultStyle: textStyle(repEvent, context),
handleClick: false,
spanCardModel: null,
transformTargetId: widget.pangeaMessageEvent.eventId,
room: widget.pangeaMessageEvent.room,
@ -244,10 +225,20 @@ class PangeaRichTextState extends State<PangeaRichText> {
[
TextSpan(
text: repEvent.text,
style: widget.existingStyle,
style: textStyle(repEvent, context),
),
];
TextStyle? textStyle(RepresentationEvent repEvent, BuildContext context) =>
// !repEvent.botAuthored
true
? widget.existingStyle
: BotStyle.text(
context,
existingStyle: widget.existingStyle,
setColor: false,
);
bool get areLanguagesSet =>
userL2LangCode != null && userL2LangCode != LanguageKeys.unknownLanguage;
@ -279,75 +270,4 @@ class PangeaRichTextState extends State<PangeaRichText> {
Future<void> onSentenceRewrite(String sentenceRewrite) async {
debugPrint("PTODO implement onSentenceRewrite");
}
// void onTextSelection(
// TextSelection selection,
// SelectionChangedCause? _,
// ) =>
// selection.isCollapsed
// ? clearTextSelection()
// : setTextSelection(selection);
// void setTextSelection(TextSelection selection) {
// textSelection = selection;
// if (BrowserContextMenu.enabled && kIsWeb) {
// BrowserContextMenu.disableContextMenu();
// }
// kIsWeb ? showToolbar() : showDefinition();
// }
// void clearTextSelection() {
// textSelection = null;
// if (kIsWeb && !BrowserContextMenu.enabled) {
// BrowserContextMenu.enableContextMenu();
// }
// }
// void showToolbar() async {
// if (toolbarShowing || !kIsWeb) return;
// toolbarShowing = true;
// await Future.delayed(const Duration(seconds: 2));
// final toolbarFuture = MessageToolbar.showToolbar(
// context,
// widget.pangeaMessageEvent.eventId,
// _focusNode.offset,
// );
// final resp = await toolbarFuture;
// toolbarShowing = false;
// switch (resp) {
// case null:
// break;
// case 1:
// showDefinition();
// break;
// default:
// break;
// }
// }
// void showDefinition() {
// final String messageText = textSpan.map((x) => x.text).join();
// final String fullText = textSelection!.textInside(messageText);
// final String langCode = widget.selectedDisplayLang?.langCode ??
// userL2LangCode ??
// LanguageKeys.unknownLanguage;
// OverlayUtil.showPositionedCard(
// context: context,
// cardToShow: WordDataCard(
// word: fullText,
// wordLang: langCode,
// fullText: messageText,
// fullTextLang: langCode,
// hasInfo: false,
// room: widget.pangeaMessageEvent.room,
// ),
// cardSize: const Size(300, 300),
// transformTargetId: widget.pangeaMessageEvent.eventId,
// backDropToDismiss: false,
// );
// }
}

Loading…
Cancel
Save