resolve merge conflict
This commit is contained in:
commit
de927aa6b4
25 changed files with 248 additions and 133 deletions
|
|
@ -4303,6 +4303,7 @@
|
|||
"grammarCopyAccDat": "Accusative, Dative",
|
||||
"grammarCopyInf": "Infinitive",
|
||||
"grammarCopyLong": "Long",
|
||||
"grammarCopyLoc": "Locative",
|
||||
"grammarCopyInd": "Indicative",
|
||||
"grammarCopyCmp": "Comparative",
|
||||
"grammarCopyRelative_case": "Relative Case",
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ class ConstructListModel {
|
|||
/// All unique lemmas used in the construct events
|
||||
List<String> get lemmas => constructList.map((e) => e.lemma).toSet().toList();
|
||||
|
||||
/// All unique lemmas used in the construct events with non-zero points
|
||||
List<String> 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<ConstructUses> get constructListWithPoints =>
|
||||
constructList.where((constructUse) => constructUse.points > 0).toList();
|
||||
|
||||
get maxXPPerLemma {
|
||||
return type != null
|
||||
? type!.maxXPPerLemma
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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<PUserAge> {
|
|||
@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() {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,33 +65,71 @@ class OverlayMessageTextState extends State<OverlayMessageText> {
|
|||
);
|
||||
}
|
||||
|
||||
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<TokenPosition> 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<OverlayMessageText> {
|
|||
);
|
||||
setState(() {});
|
||||
},
|
||||
text: tokenPosition.token!.text.content,
|
||||
text: substring,
|
||||
style: style.merge(
|
||||
TextStyle(
|
||||
backgroundColor: isSelected
|
||||
|
|
@ -119,10 +157,7 @@ class OverlayMessageTextState extends State<OverlayMessageText> {
|
|||
);
|
||||
} else {
|
||||
return TextSpan(
|
||||
text: widget.pangeaMessageEvent.event.body.substring(
|
||||
tokenPosition.start,
|
||||
tokenPosition.end,
|
||||
),
|
||||
text: substring,
|
||||
style: style,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ packages:
|
|||
source: hosted
|
||||
version: "1.1.2"
|
||||
characters:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: characters
|
||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue