diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 127ae2c40..1a366e6da 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -400,7 +400,12 @@ class ChatView extends StatelessWidget { // #Pangea // Keep messages above minimum input bar height if (!controller.room.isAbandonedDMRoom) - SizedBox(height: controller.inputBarHeight), + AnimatedSize( + duration: const Duration(milliseconds: 200), + child: SizedBox( + height: controller.inputBarHeight, + ), + ), // Pangea# ], ), diff --git a/lib/pages/chat/events/html_message.dart b/lib/pages/chat/events/html_message.dart index 055f6b9f9..75ed9ffb4 100644 --- a/lib/pages/chat/events/html_message.dart +++ b/lib/pages/chat/events/html_message.dart @@ -162,65 +162,68 @@ class HtmlMessage extends StatelessWidget { String fullHtml, List remainingTokens, ) { - for (final node in element.nodes) { - node.replaceWith(_tokenizeHtml(node, fullHtml, remainingTokens)); - } + final regex = RegExp(r'(<[^>]+>)'); - if (element is dom.Text) { - // once a text element in reached in the HTML tree, find and - // wrap all the spans with matching tokens until all tokens - // have been wrapped or no more text elements remain - String tokenizedText = element.text; - while (remainingTokens.isNotEmpty) { - final tokenText = remainingTokens.first.text.content; + final matches = regex.allMatches(fullHtml); + final List result = []; + int lastEnd = 0; - int startIndex = tokenizedText.lastIndexOf(''); - startIndex = startIndex == -1 ? 0 : startIndex + 8; - final int tokenIndex = tokenizedText.indexOf( - tokenText, - startIndex, - ); - - // if the token is not found in the text, check if the token exist in the full HTML. - // If not, remove the token and continue. If so, break to move on to the next node in the HTML. - if (tokenIndex == -1) { - final fullHtmlIndex = fullHtml.indexOf(tokenText); - if (fullHtmlIndex == -1) { - remainingTokens.removeAt(0); - continue; - } else { - break; - } - } - - final token = remainingTokens.removeAt(0); - final tokenEnd = tokenIndex + tokenText.length; - final before = tokenizedText.substring(0, tokenIndex); - final after = tokenizedText.substring(tokenEnd); - - tokenizedText = - "$before$tokenText$after"; + for (final match in matches) { + if (match.start > lastEnd) { + result.add(fullHtml.substring(lastEnd, match.start)); // Text before tag } - - final newElement = dom.Element.html('$tokenizedText'); - return newElement; + result.add(match.group(0)!); // The tag itself + lastEnd = match.end; } - return element; + if (lastEnd < fullHtml.length) { + result.add(fullHtml.substring(lastEnd)); // Remaining text after last tag + } + + for (final PangeaToken token in tokens ?? []) { + final String tokenText = token.text.content; + final substringIndex = result.indexWhere( + (string) => + string.contains(tokenText) && + !(string.startsWith('<') && string.endsWith('>')), + ); + + if (substringIndex == -1) continue; + final int tokenIndex = result[substringIndex].indexOf(tokenText); + if (tokenIndex == -1) continue; + + final int tokenLength = tokenText.characters.length; + final before = result[substringIndex].substring(0, tokenIndex); + final after = result[substringIndex].substring(tokenIndex + tokenLength); + result.replaceRange(substringIndex, substringIndex + 1, [ + if (before.isNotEmpty) before, + '$tokenText', + if (after.isNotEmpty) after, + ]); + } + + return dom.Element.html('${result.join()}'); } // Pangea# /// Adding line breaks before block elements. List _renderWithLineBreaks( dom.NodeList nodes, - BuildContext context, { + // #Pangea + // BuildContext context, { + BuildContext context, + TextStyle textStyle, { + // Pangea# int depth = 1, }) { final onlyElements = nodes.whereType().toList(); return [ for (var i = 0; i < nodes.length; i++) ...[ // Actually render the node child: - _renderHtml(nodes[i], context, depth: depth + 1), + // #Pangea + // _renderHtml(nodes[i], context, depth: depth + 1), + _renderHtml(nodes[i], context, textStyle, depth: depth + 1), + // Pangea# // Add linebreaks between blocks: if (nodes[i] is dom.Element && onlyElements.indexOf(nodes[i] as dom.Element) < @@ -237,7 +240,11 @@ class HtmlMessage extends StatelessWidget { /// Transforms a Node to an InlineSpan. InlineSpan _renderHtml( dom.Node node, - BuildContext context, { + // #Pangea + // BuildContext context, { + BuildContext context, + TextStyle textStyle, { + // Pangea# int depth = 1, }) { // We must not render elements nested more than 100 elements deep: @@ -276,9 +283,11 @@ class HtmlMessage extends StatelessWidget { final renderer = TokenRenderingUtil( pangeaMessageEvent: pangeaMessageEvent, readingAssistanceMode: readingAssistanceMode, - existingStyle: AppConfig.messageTextStyle( - pangeaMessageEvent!.event, - textColor, + existingStyle: textStyle.merge( + AppConfig.messageTextStyle( + pangeaMessageEvent!.event, + textColor, + ), ), overlayController: overlayController, isTransitionAnimation: isTransitionAnimation, @@ -418,6 +427,11 @@ class HtmlMessage extends StatelessWidget { children: _renderWithLineBreaks( node.nodes, context, + // #Pangea + textStyle.merge( + linkStyle.copyWith(height: 1.25), + ), + // Pangea# depth: depth, ), style: linkStyle, @@ -450,6 +464,9 @@ class HtmlMessage extends StatelessWidget { ..._renderWithLineBreaks( node.nodes, context, + // #Pangea + textStyle, + // Pangea# depth: depth, ), ], @@ -478,6 +495,9 @@ class HtmlMessage extends StatelessWidget { children: _renderWithLineBreaks( node.nodes, context, + // #Pangea + textStyle.copyWith(fontStyle: FontStyle.italic), + // Pangea# depth: depth, ), ), @@ -576,12 +596,28 @@ class HtmlMessage extends StatelessWidget { node.localName == 'summary', ) .map( - (node) => _renderHtml(node, context, depth: depth), + // #Pangea + // (node) => _renderHtml(node, context, depth: depth), + (node) => _renderHtml( + node, + context, + textStyle.merge( + TextStyle( + fontSize: fontSize, + color: textColor, + ), + ), + depth: depth, + ), + // Pangea# ) else ..._renderWithLineBreaks( node.nodes, context, + // #Pangea + textStyle, + // Pangea# depth: depth, ), ], @@ -614,6 +650,11 @@ class HtmlMessage extends StatelessWidget { children: _renderWithLineBreaks( node.nodes, context, + // #Pangea + textStyle.copyWith( + backgroundColor: obscure ? textColor : null, + ), + // Pangea# depth: depth, ), ), @@ -628,6 +669,36 @@ class HtmlMessage extends StatelessWidget { ); block: default: + // #Pangea + final style = switch (node.localName) { + 'body' => TextStyle( + fontSize: fontSize, + color: textColor, + ), + 'a' => linkStyle, + 'strong' => const TextStyle(fontWeight: FontWeight.bold), + 'em' || 'i' => const TextStyle(fontStyle: FontStyle.italic), + 'del' || + 'strikethrough' => + const TextStyle(decoration: TextDecoration.lineThrough), + 'u' => const TextStyle(decoration: TextDecoration.underline), + 'h1' => TextStyle(fontSize: fontSize * 1.6, height: 2), + 'h2' => TextStyle(fontSize: fontSize * 1.5, height: 2), + 'h3' => TextStyle(fontSize: fontSize * 1.4, height: 2), + 'h4' => TextStyle(fontSize: fontSize * 1.3, height: 1.75), + 'h5' => TextStyle(fontSize: fontSize * 1.2, height: 1.75), + 'h6' => TextStyle(fontSize: fontSize * 1.1, height: 1.5), + 'span' => TextStyle( + color: node.attributes['color']?.hexToColor ?? + node.attributes['data-mx-color']?.hexToColor ?? + textColor, + backgroundColor: node.attributes['data-mx-bg-color']?.hexToColor, + ), + 'sup' => const TextStyle(fontFeatures: [FontFeature.superscripts()]), + 'sub' => const TextStyle(fontFeatures: [FontFeature.subscripts()]), + _ => null, + }; + // Pangea# return TextSpan( style: switch (node.localName) { 'body' => TextStyle( @@ -663,6 +734,9 @@ class HtmlMessage extends StatelessWidget { children: _renderWithLineBreaks( node.nodes, context, + // #Pangea + textStyle.merge(style ?? const TextStyle()), + // Pangea# depth: depth, ), ); @@ -698,6 +772,12 @@ class HtmlMessage extends StatelessWidget { parsed, // Pangea# context, + // #Pangea + TextStyle( + fontSize: fontSize, + color: textColor, + ), + // Pangea# ), style: TextStyle( fontSize: fontSize, diff --git a/lib/pages/new_group/new_group.dart b/lib/pages/new_group/new_group.dart index 4e9d4cc57..bcb397fd7 100644 --- a/lib/pages/new_group/new_group.dart +++ b/lib/pages/new_group/new_group.dart @@ -48,6 +48,8 @@ class NewGroupController extends State { bool requiredCodeToJoin = false; // bool publicGroup = false; + + bool get canSubmit => nameController.text.trim().isNotEmpty; // Pangea# bool groupCanBeFound = false; @@ -250,10 +252,11 @@ class NewGroupController extends State { focusNode.requestFocus(); return; } - // Pangea# - if (nameController.text.trim().isEmpty && - createGroupType == CreateGroupType.space) { + // if (nameController.text.trim().isEmpty && + // createGroupType == CreateGroupType.space) { + if (!canSubmit) { + // Pangea# setState(() => error = L10n.of(context).pleaseFillOut); return; } diff --git a/lib/pages/new_group/new_group_view.dart b/lib/pages/new_group/new_group_view.dart index fc99a5225..6bbae6fe4 100644 --- a/lib/pages/new_group/new_group_view.dart +++ b/lib/pages/new_group/new_group_view.dart @@ -131,9 +131,9 @@ class NewGroupView extends StatelessWidget { onFieldSubmitted: (value) { controller.loading ? null : controller.submitAction(); }, - validator: (value) => value == null || value.isEmpty - ? L10n.of(context).pleaseFillOut - : null, + validator: (value) => controller.canSubmit + ? null + : L10n.of(context).pleaseFillOut, focusNode: controller.focusNode, // Pangea# ), diff --git a/lib/pangea/chat/widgets/chat_floating_action_button.dart b/lib/pangea/chat/widgets/chat_floating_action_button.dart index a024d5b97..cec4648f0 100644 --- a/lib/pangea/chat/widgets/chat_floating_action_button.dart +++ b/lib/pangea/chat/widgets/chat_floating_action_button.dart @@ -74,7 +74,8 @@ class ChatFloatingActionButtonState extends State { child: const Icon(Icons.arrow_downward_outlined), ); } - if (widget.controller.choreographer.errorService.error != null) { + if (widget.controller.choreographer.errorService.error != null && + !widget.controller.choreographer.itController.willOpen) { return ChoreographerHasErrorButton( widget.controller.choreographer.errorService.error!, widget.controller.choreographer, diff --git a/lib/pangea/chat/widgets/chat_input_bar.dart b/lib/pangea/chat/widgets/chat_input_bar.dart index ae13b985c..37fb3d397 100644 --- a/lib/pangea/chat/widgets/chat_input_bar.dart +++ b/lib/pangea/chat/widgets/chat_input_bar.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:fluffychat/config/themes.dart'; @@ -22,17 +24,27 @@ class ChatInputBar extends StatefulWidget { } class ChatInputBarState extends State { - void updateHeight() { - final renderBox = context.findRenderObject() as RenderBox?; - if (renderBox == null || !renderBox.hasSize) return; - widget.controller.updateInputBarHeight(renderBox.size.height); + Timer? _debounceTimer; + + void _updateHeight() { + _debounceTimer = Timer(const Duration(milliseconds: 100), () { + final renderBox = context.findRenderObject() as RenderBox?; + if (renderBox == null || !renderBox.hasSize) return; + widget.controller.updateInputBarHeight(renderBox.size.height); + }); + } + + @override + void dispose() { + _debounceTimer?.cancel(); + super.dispose(); } @override Widget build(BuildContext context) { return NotificationListener( onNotification: (SizeChangedLayoutNotification notification) { - WidgetsBinding.instance.addPostFrameCallback((_) => updateHeight()); + WidgetsBinding.instance.addPostFrameCallback((_) => _updateHeight()); return true; }, child: SizeChangedLayoutNotifier( diff --git a/lib/pangea/choreographer/controllers/choreographer.dart b/lib/pangea/choreographer/controllers/choreographer.dart index 301fda833..9be056e3a 100644 --- a/lib/pangea/choreographer/controllers/choreographer.dart +++ b/lib/pangea/choreographer/controllers/choreographer.dart @@ -13,7 +13,6 @@ import 'package:fluffychat/pangea/choreographer/enums/edit_type.dart'; import 'package:fluffychat/pangea/choreographer/models/choreo_record.dart'; import 'package:fluffychat/pangea/choreographer/models/it_step.dart'; import 'package:fluffychat/pangea/choreographer/models/pangea_match_model.dart'; -import 'package:fluffychat/pangea/choreographer/repo/language_detection_repo.dart'; import 'package:fluffychat/pangea/choreographer/utils/input_paste_listener.dart'; import 'package:fluffychat/pangea/choreographer/widgets/igc/pangea_text_controller.dart'; import 'package:fluffychat/pangea/choreographer/widgets/igc/paywall_card.dart'; @@ -21,7 +20,6 @@ import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/common/utils/any_state_holder.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/common/utils/overlay.dart'; -import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/events/models/representation_content_model.dart'; import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'; import 'package:fluffychat/pangea/events/repo/token_api_models.dart'; @@ -148,56 +146,57 @@ class Choreographer { ) : null; - final detectionResp = await LanguageDetectionRepo.get( - MatrixState.pangeaController.userController.accessToken, - request: LanguageDetectionRequest( + PangeaMessageTokens? tokensSent; + PangeaRepresentation? originalSent; + try { + TokensResponseModel? res; + if (l1LangCode != null && l2LangCode != null) { + res = await pangeaController.messageData + .getTokens( + repEventId: null, + room: chatController.room, + req: TokensRequestModel( + fullText: currentText, + senderL1: l1LangCode!, + senderL2: l2LangCode!, + ), + ) + .timeout(const Duration(seconds: 10)); + } + + originalSent = PangeaRepresentation( + langCode: res?.detections.firstOrNull?.langCode ?? + LanguageKeys.unknownLanguage, text: currentText, - senderl1: l1LangCode, - senderl2: l2LangCode, - ), - ); - final detections = detectionResp.detections; - final detectedLanguage = - detections.firstOrNull?.langCode ?? LanguageKeys.unknownLanguage; - - final PangeaRepresentation originalSent = PangeaRepresentation( - langCode: detectedLanguage, - text: currentText, - originalSent: true, - originalWritten: originalWritten == null, - ); - - List? res; - if (l1LangCode != null && l2LangCode != null) { - res = await pangeaController.messageData.getTokens( - repEventId: null, - room: chatController.room, - req: TokensRequestModel( - fullText: currentText, - langCode: detectedLanguage, - senderL1: l1LangCode!, - senderL2: l2LangCode!, - ), + originalSent: true, + originalWritten: originalWritten == null, ); + + tokensSent = res != null + ? PangeaMessageTokens( + tokens: res.tokens, + detections: res.detections, + ) + : null; + } catch (e, s) { + ErrorHandler.logError( + e: e, + s: s, + data: { + "currentText": currentText, + "l1LangCode": l1LangCode, + "l2LangCode": l2LangCode, + "choreoRecord": choreoRecord.toJson(), + }, + ); + } finally { + chatController.send( + originalSent: originalSent, + tokensSent: tokensSent, + choreo: choreoRecord, + ); + clear(); } - - final PangeaMessageTokens? tokensSent = res != null - ? PangeaMessageTokens( - tokens: res, - detections: detections, - ) - : null; - - chatController.send( - // originalWritten: originalWritten, - originalSent: originalSent, - tokensSent: tokensSent, - //TODO - save originalwritten tokens - // choreo: applicableChoreo, - choreo: choreoRecord, - ); - - clear(); } _resetDebounceTimer() { diff --git a/lib/pangea/choreographer/controllers/igc_controller.dart b/lib/pangea/choreographer/controllers/igc_controller.dart index cecf03ea0..76eaed5cb 100644 --- a/lib/pangea/choreographer/controllers/igc_controller.dart +++ b/lib/pangea/choreographer/controllers/igc_controller.dart @@ -104,7 +104,9 @@ class IgcController { } final IGCTextData igcTextDataResponse = - await _igcTextDataCache[reqBody.hashCode]!.data; + await _igcTextDataCache[reqBody.hashCode]! + .data + .timeout((const Duration(seconds: 10))); // this will happen when the user changes the input while igc is fetching results if (igcTextDataResponse.originalInput != choreographer.currentText) { diff --git a/lib/pangea/choreographer/controllers/it_controller.dart b/lib/pangea/choreographer/controllers/it_controller.dart index 93fa51623..8dfcca3de 100644 --- a/lib/pangea/choreographer/controllers/it_controller.dart +++ b/lib/pangea/choreographer/controllers/it_controller.dart @@ -57,7 +57,7 @@ class ITController { choreographer.setState(); } - Duration get animationSpeed => const Duration(milliseconds: 500); + Duration get animationSpeed => const Duration(milliseconds: 300); Future initializeIT(ITStartData itStartData) async { _willOpen = true; @@ -136,7 +136,8 @@ class ITController { // During first IT step, next step will not be set if (nextITStep == null) { - final ITResponseModel res = await _customInputTranslation(currentText); + final ITResponseModel res = await _customInputTranslation(currentText) + .timeout(const Duration(seconds: 10)); if (sourceText == null) return; if (res.goldContinuances != null && res.goldContinuances!.isNotEmpty) { diff --git a/lib/pangea/choreographer/widgets/it_bar.dart b/lib/pangea/choreographer/widgets/it_bar.dart index 085156c54..b5b704d08 100644 --- a/lib/pangea/choreographer/widgets/it_bar.dart +++ b/lib/pangea/choreographer/widgets/it_bar.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'package:fluffychat/pangea/choreographer/constants/choreo_constants.dart'; import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; import 'package:fluffychat/pangea/choreographer/controllers/it_controller.dart'; -import 'package:fluffychat/pangea/choreographer/widgets/it_bar_buttons.dart'; import 'package:fluffychat/pangea/choreographer/widgets/it_feedback_card.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; @@ -206,12 +205,14 @@ class ITBarState extends State with SingleTickerProviderStateMixin { if (!itController.isEditingSourceText) Padding( padding: const EdgeInsets.only(top: 8.0), - child: itController.sourceText != null - ? Text( - itController.sourceText!, - textAlign: TextAlign.center, - ) - : const LinearProgressIndicator(), + child: !itController.willOpen + ? const SizedBox() + : itController.sourceText != null + ? Text( + itController.sourceText!, + textAlign: TextAlign.center, + ) + : const LinearProgressIndicator(), ), const SizedBox(height: 8.0), Container( @@ -391,10 +392,12 @@ class ITChoices extends StatelessWidget { return const SizedBox(); } if (controller.currentITStep == null) { - return CircularProgressIndicator( - strokeWidth: 2.0, - color: Theme.of(context).colorScheme.primary, - ); + return controller.willOpen + ? CircularProgressIndicator( + strokeWidth: 2.0, + color: Theme.of(context).colorScheme.primary, + ) + : const SizedBox(); } return ChoicesArray( id: controller.currentITStep.hashCode.toString(), @@ -438,23 +441,38 @@ class ITError extends StatelessWidget { final ErrorCopy errorCopy = ErrorCopy(context, error); return Padding( padding: const EdgeInsets.symmetric(horizontal: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 300), - child: Text( - // Text( - "${errorCopy.title}\n${errorCopy.body}", - // Haga clic en su mensaje para ver los significados de las palabras. - style: TextStyle( - fontStyle: FontStyle.italic, + child: RichText( + text: TextSpan( + children: [ + WidgetSpan( + alignment: PlaceholderAlignment.middle, + child: Icon( + Icons.error_outline, + size: 20, color: Theme.of(context).colorScheme.error, ), ), + TextSpan(text: " ${errorCopy.title} "), + WidgetSpan( + alignment: PlaceholderAlignment.middle, + child: IconButton( + onPressed: () { + controller.closeIT(); + controller.choreographer.errorService.resetError(); + }, + icon: const Icon( + Icons.close, + size: 20, + ), + ), + ), + ], + style: TextStyle( + fontStyle: FontStyle.italic, + color: Theme.of(context).colorScheme.error, ), - ITRestartButton(controller: controller), - ], + ), + textAlign: TextAlign.center, ), ); } diff --git a/lib/pangea/choreographer/widgets/it_bar_buttons.dart b/lib/pangea/choreographer/widgets/it_bar_buttons.dart deleted file mode 100644 index bcc7704d7..000000000 --- a/lib/pangea/choreographer/widgets/it_bar_buttons.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart'; -import 'package:fluffychat/widgets/matrix.dart'; -import '../controllers/it_controller.dart'; - -class ITRestartButton extends StatelessWidget { - ITRestartButton({ - super.key, - required this.controller, - }); - - final ITController controller; - final PangeaController pangeaController = MatrixState.pangeaController; - - @override - Widget build(BuildContext context) { - return IconButton( - onPressed: () async { - controller.choreographer.errorService.resetError(); - controller.currentITStep = null; - controller.choreographer.getLanguageHelp(); - }, - icon: const Icon(Icons.refresh_outlined), - ); - } -} diff --git a/lib/pangea/events/controllers/message_data_controller.dart b/lib/pangea/events/controllers/message_data_controller.dart index 1421b187d..bfdee9313 100644 --- a/lib/pangea/events/controllers/message_data_controller.dart +++ b/lib/pangea/events/controllers/message_data_controller.dart @@ -12,7 +12,6 @@ import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; -import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/events/models/representation_content_model.dart'; import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'; import 'package:fluffychat/pangea/events/repo/token_api_models.dart'; @@ -23,7 +22,7 @@ import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; class MessageDataController extends BaseController { late PangeaController _pangeaController; - final Map>> _tokensCache = {}; + final Map> _tokensCache = {}; final Map> _representationCache = {}; late Timer _cacheTimer; @@ -54,7 +53,7 @@ class MessageDataController extends BaseController { /// get tokens from the server /// if repEventId is not null, send the tokens to the room - Future> _getTokens({ + Future _getTokens({ required String? repEventId, required TokensRequestModel req, required Room? room, @@ -83,13 +82,13 @@ class MessageDataController extends BaseController { ); } - return res.tokens; + return res; } /// get tokens from the server /// first check if the tokens are in the cache /// if repEventId is not null, send the tokens to the room - Future> getTokens({ + Future getTokens({ required String? repEventId, required TokensRequestModel req, required Room? room, diff --git a/lib/pangea/events/event_wrappers/pangea_representation_event.dart b/lib/pangea/events/event_wrappers/pangea_representation_event.dart index 27431695b..7e10fd14b 100644 --- a/lib/pangea/events/event_wrappers/pangea_representation_event.dart +++ b/lib/pangea/events/event_wrappers/pangea_representation_event.dart @@ -162,7 +162,7 @@ class RepresentationEvent { ), ); } - final List res = + final TokensResponseModel res = await MatrixState.pangeaController.messageData.getTokens( repEventId: _event?.eventId, room: _event?.room ?? parentMessageEvent.room, @@ -180,7 +180,7 @@ class RepresentationEvent { ), ); - return res; + return res.tokens; } Future sendTokensEvent( diff --git a/lib/pangea/events/repo/token_api_models.dart b/lib/pangea/events/repo/token_api_models.dart index cbd0035b5..2c3744454 100644 --- a/lib/pangea/events/repo/token_api_models.dart +++ b/lib/pangea/events/repo/token_api_models.dart @@ -1,6 +1,7 @@ import 'package:fluffychat/pangea/choreographer/models/language_detection_model.dart'; import 'package:fluffychat/pangea/common/constants/model_keys.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; +import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; class TokensRequestModel { /// the text to be tokenized @@ -24,16 +25,16 @@ class TokensRequestModel { TokensRequestModel({ required this.fullText, - required this.langCode, required this.senderL1, required this.senderL2, + this.langCode, }); Map toJson() => { ModelKey.fullText: fullText, ModelKey.userL1: senderL1, ModelKey.userL2: senderL2, - ModelKey.langCode: langCode, + ModelKey.langCode: langCode ?? LanguageKeys.unknownLanguage, }; // override equals and hashcode diff --git a/lib/pangea/public_spaces/public_room_bottom_sheet.dart b/lib/pangea/public_spaces/public_room_bottom_sheet.dart index 6d0ca3ca3..2a5381fc4 100644 --- a/lib/pangea/public_spaces/public_room_bottom_sheet.dart +++ b/lib/pangea/public_spaces/public_room_bottom_sheet.dart @@ -208,6 +208,7 @@ class PublicRoomBottomSheetState extends State { child: Column( spacing: 16.0, mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Row( spacing: 8.0, @@ -226,6 +227,7 @@ class PublicRoomBottomSheetState extends State { child: Text( chunk!.topic!, softWrap: true, + textAlign: TextAlign.start, maxLines: null, ), ), diff --git a/lib/pangea/public_spaces/public_space_card.dart b/lib/pangea/public_spaces/public_space_card.dart index a4873e65d..8d1c58ddf 100644 --- a/lib/pangea/public_spaces/public_space_card.dart +++ b/lib/pangea/public_spaces/public_space_card.dart @@ -74,7 +74,7 @@ class PublicSpaceCard extends StatelessWidget { padding: const EdgeInsets.all(8.0), child: Column( spacing: 4.0, - mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Column(