diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 1cd522a5c..b5310c8e3 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4303,6 +4303,7 @@ "grammarCopyAccDat": "Accusative, Dative", "grammarCopyInf": "Infinitive", "grammarCopyLong": "Long", + "grammarCopyLoc": "Locative", "grammarCopyInd": "Indicative", "grammarCopyCmp": "Comparative", "grammarCopyRelative_case": "Relative Case", diff --git a/assets/l10n/intl_es.arb b/assets/l10n/intl_es.arb index a833f813c..fd478e870 100644 --- a/assets/l10n/intl_es.arb +++ b/assets/l10n/intl_es.arb @@ -4962,6 +4962,7 @@ "grammarCopyAccDat": "Acusativo, Dativo", "grammarCopyInf": "Infinitivo", "grammarCopyLong": "Largo", + "grammarCopyLoc": "Locativa", "grammarCopyInd": "Indicativo", "grammarCopyCmp": "Comparativa", "grammarCopyRelative_case": "Caso relativo", @@ -5008,4 +5009,4 @@ "spaceCapacityNotSet": "Este espacio no tiene lĂ­mite de capacidad.", "chatExceedsCapacity": "Este chat supera su capacidad.", "spaceExceedsCapacity": "Este espacio supera su capacidad." -} +} \ No newline at end of file diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index 90f2a8927..72441e450 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -7,7 +7,6 @@ import 'package:fluffychat/pangea/pages/class_settings/class_name_header.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_description_button.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_invitation_buttons.dart'; -import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_name_button.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart'; import 'package:fluffychat/pangea/utils/lock_room.dart'; import 'package:fluffychat/pangea/widgets/conversation_bot/conversation_bot_settings.dart'; @@ -213,11 +212,6 @@ class ChatDetailsView extends StatelessWidget { ), Divider(color: theme.dividerColor), // #Pangea - if (room.isRoomAdmin) - ClassNameButton( - room: room, - controller: controller, - ), if (room.canSendEvent('m.room.topic')) ClassDescriptionButton( room: room, diff --git a/lib/pangea/choreographer/controllers/choreographer.dart b/lib/pangea/choreographer/controllers/choreographer.dart index 04e10ae0d..3e13549f6 100644 --- a/lib/pangea/choreographer/controllers/choreographer.dart +++ b/lib/pangea/choreographer/controllers/choreographer.dart @@ -542,9 +542,9 @@ class Choreographer { chatController.room, ); - bool get itAutoPlayEnabled { - return pangeaController.userController.profile.userSettings.itAutoPlay; - } + // bool get itAutoPlayEnabled { + // return pangeaController.userController.profile.userSettings.itAutoPlay; + // } bool get definitionsEnabled => pangeaController.permissionsController.isToolEnabled( diff --git a/lib/pangea/choreographer/controllers/igc_controller.dart b/lib/pangea/choreographer/controllers/igc_controller.dart index ed770cca4..6d0e848aa 100644 --- a/lib/pangea/choreographer/controllers/igc_controller.dart +++ b/lib/pangea/choreographer/controllers/igc_controller.dart @@ -99,7 +99,7 @@ class IgcController { final PangeaMatch match = igcTextData!.matches[firstMatchIndex]; if (match.isITStart && - choreographer.itAutoPlayEnabled && + // choreographer.itAutoPlayEnabled && igcTextData != null) { choreographer.onITStart(igcTextData!.matches[firstMatchIndex]); return; diff --git a/lib/pangea/choreographer/widgets/it_bar.dart b/lib/pangea/choreographer/widgets/it_bar.dart index 9b81eb960..529100d94 100644 --- a/lib/pangea/choreographer/widgets/it_bar.dart +++ b/lib/pangea/choreographer/widgets/it_bar.dart @@ -352,7 +352,7 @@ class ITChoices extends StatelessWidget { void selectContinuance(int index, BuildContext context) { final Continuance continuance = controller.currentITStep!.continuances[index]; - if (continuance.level == 1 || continuance.wasClicked) { + if (continuance.level == 1) { Future.delayed( const Duration(milliseconds: 500), () => controller.selectTranslation(index), diff --git a/lib/pangea/constants/model_keys.dart b/lib/pangea/constants/model_keys.dart index 424c07830..253d73e55 100644 --- a/lib/pangea/constants/model_keys.dart +++ b/lib/pangea/constants/model_keys.dart @@ -24,7 +24,7 @@ class ModelKey { // making this a random string so that it's harder to guess static const String activatedTrialKey = '7C4EuKIsph'; static const String autoPlayMessages = 'autoPlayMessages'; - static const String itAutoPlay = 'itAutoPlay'; + static const String itAutoPlay = 'autoPlayIT'; static const String clientClassCity = "city"; static const String clientClassCountry = "country"; diff --git a/lib/pangea/controllers/pangea_controller.dart b/lib/pangea/controllers/pangea_controller.dart index 3f0938052..c24e8b3d2 100644 --- a/lib/pangea/controllers/pangea_controller.dart +++ b/lib/pangea/controllers/pangea_controller.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:developer'; import 'dart:math'; +import 'package:fluffychat/pangea/constants/bot_mode.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; import 'package:fluffychat/pangea/controllers/class_controller.dart'; @@ -22,6 +23,7 @@ import 'package:fluffychat/pangea/controllers/user_controller.dart'; import 'package:fluffychat/pangea/controllers/word_net_controller.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/guard/p_vguard.dart'; +import 'package:fluffychat/pangea/models/bot_options_model.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/utils/instructions.dart'; @@ -205,15 +207,88 @@ class PangeaController { if (botDMs.isEmpty) { try { - await matrixState.client.startDirectChat( - BotName.byEnvironment, - enableEncryption: false, + // Copied from client.dart.startDirectChat + final directChatRoomId = + matrixState.client.getDirectChatFromUserId(BotName.byEnvironment); + if (directChatRoomId != null) { + final room = matrixState.client.getRoomById(directChatRoomId); + if (room != null) { + if (room.membership == Membership.join) { + return null; + } else if (room.membership == Membership.invite) { + // we might already have an invite into a DM room. If that is the case, we should try to join. If the room is + // unjoinable, that will automatically leave the room, so in that case we need to continue creating a new + // room. (This implicitly also prevents the room from being returned as a DM room by getDirectChatFromUserId, + // because it only returns joined or invited rooms atm.) + await room.join(); + if (room.membership != Membership.leave) { + if (room.membership != Membership.join) { + // Wait for room actually appears in sync with the right membership + await matrixState.client + .waitForRoomInSync(directChatRoomId, join: true); + } + return null; + } + } + } + } + // enableEncryption ??= + // encryptionEnabled && await userOwnsEncryptionKeys(mxid); + // if (enableEncryption) { + // initialState ??= []; + // if (!initialState.any((s) => s.type == EventTypes.Encryption)) { + // initialState.add( + // StateEvent( + // content: { + // 'algorithm': supportedGroupEncryptionAlgorithms.first, + // }, + // type: EventTypes.Encryption, + // ), + // ); + // } + // } + + // Start a new direct chat + final roomId = await matrixState.client.createRoom( + invite: [], // intentionally not invite bot yet + isDirect: true, + preset: CreateRoomPreset.trustedPrivateChat, + initialState: [ + BotOptionsModel(mode: BotMode.directChat).toStateEvent, + ], ); + + final room = matrixState.client.getRoomById(roomId); + if (room == null || room.membership != Membership.join) { + // Wait for room actually appears in sync + await matrixState.client.waitForRoomInSync(roomId, join: true); + } + + final botOptions = room!.getState(PangeaEventTypes.botOptions); + if (botOptions == null) { + await matrixState.client.setRoomStateWithKey( + roomId, + PangeaEventTypes.botOptions, + "", + BotOptionsModel(mode: BotMode.directChat).toJson(), + ); + await matrixState.client + .getRoomStateWithKey(roomId, PangeaEventTypes.botOptions, ""); + } + + // invite bot to direct chat + await matrixState.client.setRoomStateWithKey( + roomId, EventTypes.RoomMember, BotName.byEnvironment, { + "membership": Membership.invite.name, + "is_direct": true, + }); + await room.addToDirectChat(BotName.byEnvironment); + + return null; } catch (err, stack) { debugger(when: kDebugMode); ErrorHandler.logError(e: err, s: stack); } - return; } final Room botDMWithLatestActivity = botDMs.reduce((a, b) { diff --git a/lib/pangea/enum/construct_use_type_enum.dart b/lib/pangea/enum/construct_use_type_enum.dart index 6ced270b7..196cf89b4 100644 --- a/lib/pangea/enum/construct_use_type_enum.dart +++ b/lib/pangea/enum/construct_use_type_enum.dart @@ -105,23 +105,23 @@ extension ConstructUseTypeExtension on ConstructUseTypeEnum { return 2; case ConstructUseTypeEnum.corIt: + return 1; + case ConstructUseTypeEnum.ignIt: case ConstructUseTypeEnum.ignIGC: case ConstructUseTypeEnum.ignPA: case ConstructUseTypeEnum.ignWL: - return 1; - case ConstructUseTypeEnum.unk: case ConstructUseTypeEnum.nan: return 0; case ConstructUseTypeEnum.incIt: case ConstructUseTypeEnum.incIGC: - return -1; + return -2; case ConstructUseTypeEnum.incPA: case ConstructUseTypeEnum.incWL: - return -2; + return -3; } } } diff --git a/lib/pangea/models/analytics/construct_list_model.dart b/lib/pangea/models/analytics/construct_list_model.dart index d73b5060a..23763824c 100644 --- a/lib/pangea/models/analytics/construct_list_model.dart +++ b/lib/pangea/models/analytics/construct_list_model.dart @@ -26,6 +26,10 @@ class ConstructListModel { /// All unique lemmas used in the construct events List get lemmas => constructList.map((e) => e.lemma).toSet().toList(); + /// All unique lemmas used in the construct events with non-zero points + List get lemmasWithPoints => + constructListWithPoints.map((e) => e.lemma).toSet().toList(); + /// A map of lemmas to ConstructUses, each of which contains a lemma /// key = lemmma + constructType.string, value = ConstructUses void _buildConstructMap() { @@ -72,6 +76,9 @@ class ConstructListModel { return _constructList!; } + List get constructListWithPoints => + constructList.where((constructUse) => constructUse.points > 0).toList(); + get maxXPPerLemma { return type != null ? type!.maxXPPerLemma diff --git a/lib/pangea/models/user_model.dart b/lib/pangea/models/user_model.dart index 7ef85fbd5..1fdebef3a 100644 --- a/lib/pangea/models/user_model.dart +++ b/lib/pangea/models/user_model.dart @@ -12,7 +12,7 @@ class UserSettings { DateTime? dateOfBirth; DateTime? createdAt; bool autoPlayMessages; - bool itAutoPlay; + // bool itAutoPlay; bool activatedFreeTrial; bool publicProfile; String? targetLanguage; @@ -23,7 +23,7 @@ class UserSettings { this.dateOfBirth, this.createdAt, this.autoPlayMessages = false, - this.itAutoPlay = false, + // this.itAutoPlay = true, this.activatedFreeTrial = false, this.publicProfile = false, this.targetLanguage, @@ -37,7 +37,7 @@ class UserSettings { ? DateTime.parse(json[ModelKey.userCreatedAt]) : null, autoPlayMessages: json[ModelKey.autoPlayMessages] ?? false, - itAutoPlay: json[ModelKey.itAutoPlay] ?? false, + // itAutoPlay: json[ModelKey.itAutoPlay] ?? true, activatedFreeTrial: json[ModelKey.activatedTrialKey] ?? false, publicProfile: json[ModelKey.publicProfile] ?? false, targetLanguage: json[ModelKey.l2LanguageKey], @@ -50,7 +50,7 @@ class UserSettings { data[ModelKey.userDateOfBirth] = dateOfBirth?.toIso8601String(); data[ModelKey.userCreatedAt] = createdAt?.toIso8601String(); data[ModelKey.autoPlayMessages] = autoPlayMessages; - data[ModelKey.itAutoPlay] = itAutoPlay; + // data[ModelKey.itAutoPlay] = itAutoPlay; data[ModelKey.activatedTrialKey] = activatedFreeTrial; data[ModelKey.publicProfile] = publicProfile; data[ModelKey.l2LanguageKey] = targetLanguage; @@ -96,9 +96,9 @@ class UserSettings { autoPlayMessages: (accountData[ModelKey.autoPlayMessages] ?.content[ModelKey.autoPlayMessages] as bool?) ?? false, - itAutoPlay: (accountData[ModelKey.itAutoPlay] - ?.content[ModelKey.itAutoPlay] as bool?) ?? - false, + // itAutoPlay: (accountData[ModelKey.itAutoPlay] + // ?.content[ModelKey.itAutoPlay] as bool?) ?? + // true, activatedFreeTrial: (accountData[ModelKey.activatedTrialKey] ?.content[ModelKey.activatedTrialKey] as bool?) ?? false, diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart index cea57995f..35d787fce 100644 --- a/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart @@ -42,7 +42,7 @@ class ClassDescriptionButton extends StatelessWidget { ? (room.isRoomAdmin ? (room.isSpace ? L10n.of(context)!.classDescriptionDesc - : L10n.of(context)!.chatTopicDesc) + : L10n.of(context)!.setChatDescription) : L10n.of(context)!.topicNotSet) : room.topic, ), diff --git a/lib/pangea/pages/p_user_age/p_user_age.dart b/lib/pangea/pages/p_user_age/p_user_age.dart index fd937485c..d7e36f200 100644 --- a/lib/pangea/pages/p_user_age/p_user_age.dart +++ b/lib/pangea/pages/p_user_age/p_user_age.dart @@ -2,7 +2,6 @@ import 'dart:developer'; import 'package:fluffychat/pangea/constants/age_limits.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; -import 'package:fluffychat/pangea/extensions/client_extension/client_extension.dart'; import 'package:fluffychat/pangea/pages/p_user_age/p_user_age_view.dart'; import 'package:fluffychat/pangea/utils/p_extension.dart'; import 'package:fluffychat/widgets/fluffy_chat_app.dart'; @@ -11,7 +10,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import '../../utils/bot_name.dart'; import '../../utils/error_handler.dart'; class PUserAge extends StatefulWidget { @@ -34,20 +32,7 @@ class PUserAgeController extends State { @override void initState() { super.initState(); - Future.delayed(Duration.zero, () async { - if (!(await Matrix.of(context).client.hasBotDM)) { - Matrix.of(context) - .client - .startDirectChat( - BotName.byEnvironment, - enableEncryption: false, - ) - .onError( - (error, stackTrace) => - ErrorHandler.logError(e: error, s: stackTrace), - ); - } - }); + pangeaController.startChatWithBotIfNotPresent(); } String? dobValidator() { diff --git a/lib/pangea/pages/settings_learning/settings_learning_view.dart b/lib/pangea/pages/settings_learning/settings_learning_view.dart index 943d81ca2..13dd8d4d7 100644 --- a/lib/pangea/pages/settings_learning/settings_learning_view.dart +++ b/lib/pangea/pages/settings_learning/settings_learning_view.dart @@ -48,19 +48,19 @@ class SettingsLearningView extends StatelessWidget { value, ), ), - ProfileSettingsSwitchListTile.adaptive( - defaultValue: controller.pangeaController.userController.profile - .userSettings.itAutoPlay, - title: - L10n.of(context)!.interactiveTranslatorAutoPlaySliderHeader, - subtitle: L10n.of(context)!.interactiveTranslatorAutoPlayDesc, - onChange: (bool value) => controller - .pangeaController.userController - .updateProfile((profile) { - profile.userSettings.itAutoPlay = value; - return profile; - }), - ), + // ProfileSettingsSwitchListTile.adaptive( + // defaultValue: controller.pangeaController.userController.profile + // .userSettings.itAutoPlay, + // title: + // L10n.of(context)!.interactiveTranslatorAutoPlaySliderHeader, + // subtitle: L10n.of(context)!.interactiveTranslatorAutoPlayDesc, + // onChange: (bool value) => controller + // .pangeaController.userController + // .updateProfile((profile) { + // profile.userSettings.itAutoPlay = value; + // return profile; + // }), + // ), // ProfileSettingsSwitchListTile.adaptive( // defaultValue: controller.pangeaController.userController.profile // .userSettings.autoPlayMessages, diff --git a/lib/pangea/utils/inline_tooltip.dart b/lib/pangea/utils/inline_tooltip.dart index 4c81e1bbd..f96cc05bb 100644 --- a/lib/pangea/utils/inline_tooltip.dart +++ b/lib/pangea/utils/inline_tooltip.dart @@ -41,14 +41,16 @@ class InlineTooltip extends StatelessWidget { ), const SizedBox(width: 8), // Text in the middle - Center( - child: Text( - instructionsEnum.body(L10n.of(context)!), - style: TextStyle( - color: Theme.of(context).colorScheme.onSurface, - height: 1.5, + Flexible( + child: Center( + child: Text( + instructionsEnum.body(L10n.of(context)!), + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + height: 1.5, + ), + textAlign: TextAlign.left, ), - textAlign: TextAlign.left, ), ), // Close button on the right diff --git a/lib/pangea/widgets/chat/missing_voice_button.dart b/lib/pangea/widgets/chat/missing_voice_button.dart index e1f8b74fb..1765a9d20 100644 --- a/lib/pangea/widgets/chat/missing_voice_button.dart +++ b/lib/pangea/widgets/chat/missing_voice_button.dart @@ -40,21 +40,27 @@ class MissingVoiceButton extends StatelessWidget { ), padding: const EdgeInsets.all(8), margin: const EdgeInsets.only(top: 8), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - L10n.of(context)!.voiceNotAvailable, - textAlign: TextAlign.center, - ), - TextButton( - onPressed: () => launchTTSSettings, - style: const ButtonStyle( - tapTargetSize: MaterialTapTargetSize.shrinkWrap, + child: SizedBox( + width: AppConfig.toolbarMinWidth, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + L10n.of(context)!.voiceNotAvailable, + textAlign: TextAlign.center, ), - child: Text(L10n.of(context)!.openVoiceSettings), - ), - ], + TextButton( + onPressed: () => launchTTSSettings, + // commenting out as suspecting this is causing an issue + // #freeze-activity + style: const ButtonStyle( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + child: Text(L10n.of(context)!.openVoiceSettings), + ), + ], + ), ), ); } diff --git a/lib/pangea/widgets/chat/overlay_message_text.dart b/lib/pangea/widgets/chat/overlay_message_text.dart index 4d91ed359..1ca2f8473 100644 --- a/lib/pangea/widgets/chat/overlay_message_text.dart +++ b/lib/pangea/widgets/chat/overlay_message_text.dart @@ -65,33 +65,71 @@ class OverlayMessageTextState extends State { ); } - int lastEnd = 0; +// Convert the entire message into a list of characters + final Characters messageCharacters = + widget.pangeaMessageEvent.event.body.characters; + + // When building token positions, use grapheme cluster indices final List tokenPositions = []; + int globalIndex = 0; for (int i = 0; i < tokens!.length; i++) { final token = tokens![i]; final start = token.start; final end = token.end; - if (lastEnd < start) { - tokenPositions.add(TokenPosition(start: lastEnd, end: start)); + // Calculate the number of grapheme clusters up to the start and end positions + final int startIndex = messageCharacters.take(start).length; + final int endIndex = messageCharacters.take(end).length; + + if (globalIndex < startIndex) { + tokenPositions.add(TokenPosition(start: globalIndex, end: startIndex)); } tokenPositions.add( TokenPosition( - start: start, - end: end, + start: startIndex, + end: endIndex, tokenIndex: i, token: token, ), ); - lastEnd = end; + globalIndex = endIndex; } + // debug prints for fixing words sticking together + // void printEscapedString(String input) { + // // Escaped string using Unicode escape sequences + // final String escapedString = input.replaceAllMapped( + // RegExp(r'[^\w\s]', unicode: true), + // (match) { + // final codeUnits = match.group(0)!.runes; + // String unicodeEscapes = ''; + // for (final rune in codeUnits) { + // unicodeEscapes += '\\u{${rune.toRadixString(16)}}'; + // } + // return unicodeEscapes; + // }, + // ); + // print("Escaped String: $escapedString"); + + // // Printing each character with its index + // int index = 0; + // for (final char in input.characters) { + // print("Index $index: $char"); + // index++; + // } + // } + //TODO - take out of build function of every message return RichText( text: TextSpan( children: tokenPositions.map((tokenPosition) { + final substring = messageCharacters + .skip(tokenPosition.start) + .take(tokenPosition.end - tokenPosition.start) + .toString(); + if (tokenPosition.token != null) { final isSelected = widget.overlayController.isTokenSelected(tokenPosition.token!); @@ -106,7 +144,7 @@ class OverlayMessageTextState extends State { ); setState(() {}); }, - text: tokenPosition.token!.text.content, + text: substring, style: style.merge( TextStyle( backgroundColor: isSelected @@ -119,10 +157,7 @@ class OverlayMessageTextState extends State { ); } else { return TextSpan( - text: widget.pangeaMessageEvent.event.body.substring( - tokenPosition.start, - tokenPosition.end, - ), + text: substring, style: style, ); } diff --git a/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart b/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart index 9dcc7b06b..d7978af73 100644 --- a/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart +++ b/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart @@ -36,31 +36,32 @@ class AnalyticsPopup extends StatelessWidget { ), body: Padding( padding: const EdgeInsets.symmetric(vertical: 20), - child: constructsModel.constructList.isEmpty + child: constructsModel.constructListWithPoints.isEmpty ? Center( child: Text(L10n.of(context)!.noDataFound), ) : ListView.builder( - itemCount: constructsModel.constructList.length, + itemCount: constructsModel.constructListWithPoints.length, itemBuilder: (context, index) { return Tooltip( message: - "${constructsModel.constructList[index].points} / ${constructsModel.maxXPPerLemma}", + "${constructsModel.constructListWithPoints[index].points} / ${constructsModel.maxXPPerLemma}", child: ListTile( onTap: () {}, title: Text( constructsModel.type == ConstructTypeEnum.morph ? getGrammarCopy( constructsModel - .constructList[index].lemma, + .constructListWithPoints[index].lemma, context, ) - : constructsModel.constructList[index].lemma, + : constructsModel + .constructListWithPoints[index].lemma, ), subtitle: LinearProgressIndicator( - value: - constructsModel.constructList[index].points / - constructsModel.maxXPPerLemma, + value: constructsModel + .constructListWithPoints[index].points / + constructsModel.maxXPPerLemma, minHeight: 20, borderRadius: const BorderRadius.all( Radius.circular(AppConfig.borderRadius), diff --git a/lib/pangea/widgets/chat_list/analytics_summary/learning_progress_indicators.dart b/lib/pangea/widgets/chat_list/analytics_summary/learning_progress_indicators.dart index 6695d2673..0a616c6bd 100644 --- a/lib/pangea/widgets/chat_list/analytics_summary/learning_progress_indicators.dart +++ b/lib/pangea/widgets/chat_list/analytics_summary/learning_progress_indicators.dart @@ -111,9 +111,9 @@ class LearningProgressIndicatorsState int? getProgressPoints(ProgressIndicatorEnum indicator) { switch (indicator) { case ProgressIndicatorEnum.wordsUsed: - return words?.lemmas.length; + return words?.lemmasWithPoints.length; case ProgressIndicatorEnum.morphsUsed: - return morphs?.lemmas.length; + return morphs?.lemmasWithPoints.length; case ProgressIndicatorEnum.level: return level; } diff --git a/lib/pangea/widgets/conversation_bot/conversation_bot_mode_dynamic_zone.dart b/lib/pangea/widgets/conversation_bot/conversation_bot_mode_dynamic_zone.dart index 5a3082610..e691cbcb5 100644 --- a/lib/pangea/widgets/conversation_bot/conversation_bot_mode_dynamic_zone.dart +++ b/lib/pangea/widgets/conversation_bot/conversation_bot_mode_dynamic_zone.dart @@ -24,6 +24,7 @@ class ConversationBotModeDynamicZone extends StatelessWidget { Widget build(BuildContext context) { final discussionChildren = [ TextFormField( + onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), decoration: InputDecoration( hintText: L10n.of(context)! .conversationBotDiscussionZone_discussionTopicPlaceholder, @@ -43,6 +44,7 @@ class ConversationBotModeDynamicZone extends StatelessWidget { ), const SizedBox(height: 12), TextFormField( + onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), decoration: InputDecoration( hintText: L10n.of(context)! .conversationBotDiscussionZone_discussionKeywordsPlaceholder, @@ -58,6 +60,7 @@ class ConversationBotModeDynamicZone extends StatelessWidget { final customChildren = [ TextFormField( + onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), decoration: InputDecoration( hintText: L10n.of(context)! .conversationBotCustomZone_customSystemPromptPlaceholder, diff --git a/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart b/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart index 044fcc214..e30429214 100644 --- a/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart +++ b/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart @@ -200,27 +200,31 @@ class ConversationBotSettingsDialogState ), Expanded( child: SingleChildScrollView( - child: Column( - children: [ - const SizedBox(height: 20), - AnimatedOpacity( - duration: FluffyThemes.animationDuration, - opacity: addBot ? 1.0 : 0.5, - child: ConversationBotSettingsForm( - botOptions: botOptions, - discussionKeywordsController: - discussionKeywordsController, - discussionTopicController: discussionTopicController, - customSystemPromptController: - customSystemPromptController, - enabled: addBot, - onUpdateBotMode: onUpdateChatMode, - onUpdateBotLanguage: onUpdateBotLanguage, - onUpdateBotVoice: onUpdateBotVoice, - onUpdateBotLanguageLevel: onUpdateBotLanguageLevel, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + children: [ + const SizedBox(height: 20), + AnimatedOpacity( + duration: FluffyThemes.animationDuration, + opacity: addBot ? 1.0 : 0.5, + child: ConversationBotSettingsForm( + botOptions: botOptions, + discussionKeywordsController: + discussionKeywordsController, + discussionTopicController: + discussionTopicController, + customSystemPromptController: + customSystemPromptController, + enabled: addBot, + onUpdateBotMode: onUpdateChatMode, + onUpdateBotLanguage: onUpdateBotLanguage, + onUpdateBotVoice: onUpdateBotVoice, + onUpdateBotLanguageLevel: onUpdateBotLanguageLevel, + ), ), - ), - ], + ], + ), ), ), ), diff --git a/lib/pangea/widgets/igc/pangea_text_controller.dart b/lib/pangea/widgets/igc/pangea_text_controller.dart index b7bbc1af8..a8ad07d71 100644 --- a/lib/pangea/widgets/igc/pangea_text_controller.dart +++ b/lib/pangea/widgets/igc/pangea_text_controller.dart @@ -90,7 +90,7 @@ class PangeaTextController extends TextEditingController { // if autoplay on and it start then just start it if (matchIndex != -1 && - choreographer.itAutoPlayEnabled && + // choreographer.itAutoPlayEnabled && choreographer.igc.igcTextData!.matches[matchIndex].isITStart) { return choreographer.onITStart( choreographer.igc.igcTextData!.matches[matchIndex], diff --git a/lib/pangea/widgets/igc/span_card.dart b/lib/pangea/widgets/igc/span_card.dart index ddfa43ba4..63ecad332 100644 --- a/lib/pangea/widgets/igc/span_card.dart +++ b/lib/pangea/widgets/igc/span_card.dart @@ -355,16 +355,16 @@ class WordMatchContent extends StatelessWidget { ), ], ), - if (controller.widget.scm.pangeaMatch!.isITStart) - DontShowSwitchListTile( - controller: pangeaController, - onSwitch: (bool value) { - pangeaController.userController.updateProfile((profile) { - profile.userSettings.itAutoPlay = value; - return profile; - }); - }, - ), + // if (controller.widget.scm.pangeaMatch!.isITStart) + // DontShowSwitchListTile( + // controller: pangeaController, + // onSwitch: (bool value) { + // pangeaController.userController.updateProfile((profile) { + // profile.userSettings.itAutoPlay = value; + // return profile; + // }); + // }, + // ), ], ), ], diff --git a/pubspec.lock b/pubspec.lock index 62b8d21a7..f1eff4109 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -162,7 +162,7 @@ packages: source: hosted version: "1.1.2" characters: - dependency: transitive + dependency: "direct main" description: name: characters sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" diff --git a/pubspec.yaml b/pubspec.yaml index 788d4d1ca..25c564cef 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: 1.23.2+3561 +version: 1.23.3+3562 environment: sdk: ">=3.0.0 <4.0.0" @@ -19,6 +19,7 @@ dependencies: badges: ^3.1.2 blurhash_dart: ^1.2.1 callkeep: ^0.3.2 + characters: ^1.2.0 chewie: ^1.8.1 collection: ^1.18.0 cupertino_icons: any