diff --git a/lib/pages/chat/events/html_message.dart b/lib/pages/chat/events/html_message.dart index 877ddf428..9ddaa4fce 100644 --- a/lib/pages/chat/events/html_message.dart +++ b/lib/pages/chat/events/html_message.dart @@ -26,6 +26,30 @@ import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/mxc_image.dart'; import '../../../utils/url_launcher.dart'; +class _TokenPosition { + final PangeaToken token; + final int startIndex; + final int endIndex; + + _TokenPosition({ + required this.token, + required this.startIndex, + required this.endIndex, + }); +} + +class _MessageChunk { + final int startIndex; + final int endIndex; + final String text; + + _MessageChunk({ + required this.startIndex, + required this.endIndex, + required this.text, + }); +} + class HtmlMessage extends StatelessWidget { final String html; final Room room; @@ -229,7 +253,59 @@ class HtmlMessage extends StatelessWidget { ]); } - return result.join(); + for (int i = 0; i < result.length; i++) { + final tag = result[i]; + if (blockHtmlTags.contains(tag.htmlTagName) || + fullLineHtmlTag.contains(tag.htmlTagName)) { + result[i] = ", "; + } + } + + if (pangeaMessageEvent?.textDirection == TextDirection.rtl) { + final inverted = _invertTags(result); + return inverted.join().trim(); + } + return result.join().trim(); + } + + List _invertTags(List tags) { + final List<(String, int)> stack = []; + final List<(int, int)> invertedTags = []; + for (int i = 0; i < tags.length; i++) { + final tag = tags[i]; + if (!tag.contains('<') || tag.contains(" + element.$1.htmlTagName == tag.htmlTagName && + !element.$1.contains(" onClick?.call(token) : null, child: RichText( + textDirection: pangeaMessageEvent?.textDirection, text: TextSpan( children: [ LinkifySpan( @@ -1008,3 +1085,8 @@ extension on String { extension on dom.Element { dom.Element get rootElement => parent?.rootElement ?? this; } + +extension on String { + String get htmlTagName => + replaceAll('<', '').replaceAll('>', '').replaceAll('/', '').split(' ')[0]; +} diff --git a/lib/pangea/events/event_wrappers/pangea_message_event.dart b/lib/pangea/events/event_wrappers/pangea_message_event.dart index 0f01f2655..f6f7e6b91 100644 --- a/lib/pangea/events/event_wrappers/pangea_message_event.dart +++ b/lib/pangea/events/event_wrappers/pangea_message_event.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:developer'; +import 'dart:ui'; import 'package:flutter/foundation.dart'; @@ -18,6 +19,7 @@ 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/stt_translation_model.dart'; import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'; +import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart'; import 'package:fluffychat/pangea/morphs/morph_features_enum.dart'; import 'package:fluffychat/pangea/practice_activities/activity_type_enum.dart'; import 'package:fluffychat/pangea/spaces/models/space_model.dart'; @@ -768,4 +770,9 @@ class PangeaMessageEvent { tag: tag, ); } + + TextDirection get textDirection => + PLanguageStore.rtlLanguageCodes.contains(messageDisplayLangCode) + ? TextDirection.rtl + : TextDirection.ltr; } diff --git a/lib/pangea/learning_settings/models/language_model.dart b/lib/pangea/learning_settings/models/language_model.dart index 4029b9507..5e62e312e 100644 --- a/lib/pangea/learning_settings/models/language_model.dart +++ b/lib/pangea/learning_settings/models/language_model.dart @@ -1,21 +1,26 @@ import 'package:flutter/material.dart'; +import 'package:collection/collection.dart'; + import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; import 'package:fluffychat/pangea/learning_settings/enums/l2_support_enum.dart'; +import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart'; class LanguageModel { final String langCode; final String displayName; final String script; final L2SupportEnum l2Support; + final TextDirection? _textDirection; LanguageModel({ required this.langCode, required this.displayName, this.script = LanguageKeys.unknownLanguage, this.l2Support = L2SupportEnum.na, - }); + TextDirection? textDirection, + }) : _textDirection = textDirection; factory LanguageModel.fromJson(json) { final String code = json['language_code'] ?? @@ -31,6 +36,11 @@ class LanguageModel { ? L2SupportEnum.na.fromStorageString(json['l2_support']) : L2SupportEnum.na, script: json['script'] ?? LanguageKeys.unknownLanguage, + textDirection: json['text_direction'] != null + ? TextDirection.values.firstWhereOrNull( + (e) => e.name == json['text_direction'], + ) + : null, ); } @@ -39,6 +49,7 @@ class LanguageModel { 'language_name': displayName, 'script': script, 'l2_support': l2Support.storageString, + 'text_direction': textDirection.name, }; bool get l2 => l2Support != L2SupportEnum.na; @@ -73,6 +84,16 @@ class LanguageModel { String get langCodeShort => langCode.split('-').first; + TextDirection get _defaultTextDirection { + return PLanguageStore.rtlLanguageCodes.contains(langCodeShort) + ? TextDirection.rtl + : TextDirection.ltr; + } + + TextDirection get textDirection { + return _textDirection ?? _defaultTextDirection; + } + @override bool operator ==(Object other) { if (other is LanguageModel) { diff --git a/lib/pangea/learning_settings/utils/p_language_store.dart b/lib/pangea/learning_settings/utils/p_language_store.dart index ed66d2bf9..075912e75 100644 --- a/lib/pangea/learning_settings/utils/p_language_store.dart +++ b/lib/pangea/learning_settings/utils/p_language_store.dart @@ -107,4 +107,19 @@ class PLanguageStore { } return null; } + + static final List rtlLanguageCodes = [ + 'ar', + 'arc', + 'dv', + 'fa', + 'ha', + 'he', + 'khw', + 'ks', + 'ku', + 'ps', + 'ur', + 'yi', + ]; } diff --git a/pubspec.yaml b/pubspec.yaml index 2e67fdca8..6045a6386 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,7 +6,7 @@ description: Learn a language while texting your friends. # Pangea# publish_to: none # On version bump also increase the build number for F-Droid -version: 4.1.10+2 +version: 4.1.12+2 environment: sdk: ">=3.0.0 <4.0.0" @@ -168,8 +168,8 @@ flutter: # #Pangea # uncomment this to enable mobile builds # causes error with github actions - # - .env - # - assets/.env + - .env + - assets/.env - assets/pangea/ - assets/pangea/bot_faces/ # Pangea#