Merge pull request #921 from pangeachat/no-original-sent

in message toolbar, use the display representation instead of origina…
pull/1476/head
ggurdin 1 year ago committed by GitHub
commit 9f7acff1d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -563,13 +563,13 @@ class PangeaMessageEvent {
return langCode ?? LanguageKeys.unknownLanguage; return langCode ?? LanguageKeys.unknownLanguage;
} }
RepresentationEvent? get messageDisplayRepresentation =>
representationByLanguage(messageDisplayLangCode);
/// Gets the message display text for the current language code. /// Gets the message display text for the current language code.
/// If the message display text is not available for the current language code, /// If the message display text is not available for the current language code,
/// it returns the message body. /// it returns the message body.
String get messageDisplayText { String get messageDisplayText => messageDisplayRepresentation?.text ?? body;
final String? text = representationByLanguage(messageDisplayLangCode)?.text;
return text ?? body;
}
List<PangeaMatch>? errorSteps(String lemma) { List<PangeaMatch>? errorSteps(String lemma) {
final RepresentationEvent? repEvent = originalSent ?? originalWritten; final RepresentationEvent? repEvent = originalSent ?? originalWritten;

@ -14,7 +14,6 @@ import 'package:fluffychat/pangea/widgets/chat/tts_controller.dart';
import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart'; import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
class MessageAudioCard extends StatefulWidget { class MessageAudioCard extends StatefulWidget {
@ -147,15 +146,10 @@ class MessageAudioCardState extends State<MessageAudioCard> {
try { try {
final String langCode = widget.messageEvent.messageDisplayLangCode; final String langCode = widget.messageEvent.messageDisplayLangCode;
final String? text = final Event? localEvent = widget.messageEvent.getTextToSpeechLocal(
widget.messageEvent.representationByLanguage(langCode)?.text; langCode,
widget.messageEvent.messageDisplayText,
if (text == null) { );
//TODO - handle error but get out of flow
}
final Event? localEvent =
widget.messageEvent.getTextToSpeechLocal(langCode, text!);
if (localEvent != null) { if (localEvent != null) {
audioFile = await localEvent.getPangeaAudioFile(); audioFile = await localEvent.getPangeaAudioFile();
@ -172,11 +166,6 @@ class MessageAudioCardState extends State<MessageAudioCard> {
debugPrint(StackTrace.current.toString()); debugPrint(StackTrace.current.toString());
if (!mounted) return; if (!mounted) return;
setState(() => _isLoading = false); setState(() => _isLoading = false);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(L10n.of(context)!.errorGettingAudio),
),
);
ErrorHandler.logError( ErrorHandler.logError(
e: e, e: e,
s: s, s: s,

@ -18,6 +18,7 @@ import 'package:fluffychat/pangea/widgets/chat/overlay_footer.dart';
import 'package:fluffychat/pangea/widgets/chat/overlay_header.dart'; import 'package:fluffychat/pangea/widgets/chat/overlay_header.dart';
import 'package:fluffychat/pangea/widgets/chat/overlay_message.dart'; import 'package:fluffychat/pangea/widgets/chat/overlay_message.dart';
import 'package:fluffychat/pangea/widgets/chat/tts_controller.dart'; import 'package:fluffychat/pangea/widgets/chat/tts_controller.dart';
import 'package:fluffychat/pangea/widgets/practice_activity/target_tokens_controller.dart';
import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -74,6 +75,8 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
bool isPlayingAudio = false; bool isPlayingAudio = false;
bool get showToolbarButtons => !widget._pangeaMessageEvent.isAudioMessage; bool get showToolbarButtons => !widget._pangeaMessageEvent.isAudioMessage;
final TargetTokensController targetTokensController =
TargetTokensController();
@override @override
void initState() { void initState() {
@ -107,8 +110,8 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
}, },
).listen((_) => setState(() {})); ).listen((_) => setState(() {}));
setInitialToolbarMode();
tts.setupTTS(); tts.setupTTS();
setInitialToolbarMode();
} }
/// We need to check if the setState call is safe to call immediately /// We need to check if the setState call is safe to call immediately
@ -489,7 +492,8 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
MessageToolbar( MessageToolbar(
pangeaMessageEvent: widget._pangeaMessageEvent, pangeaMessageEvent: widget._pangeaMessageEvent,
overLayController: this, overLayController: this,
tts: tts, ttsController: tts,
targetTokensController: targetTokensController,
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
SizedBox( SizedBox(

@ -10,10 +10,13 @@ import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart';
import 'package:fluffychat/pangea/widgets/chat/message_speech_to_text_card.dart'; import 'package:fluffychat/pangea/widgets/chat/message_speech_to_text_card.dart';
import 'package:fluffychat/pangea/widgets/chat/message_translation_card.dart'; import 'package:fluffychat/pangea/widgets/chat/message_translation_card.dart';
import 'package:fluffychat/pangea/widgets/chat/message_unsubscribed_card.dart'; import 'package:fluffychat/pangea/widgets/chat/message_unsubscribed_card.dart';
import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator.dart';
import 'package:fluffychat/pangea/widgets/chat/tts_controller.dart'; import 'package:fluffychat/pangea/widgets/chat/tts_controller.dart';
import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart';
import 'package:fluffychat/pangea/widgets/igc/word_data_card.dart'; import 'package:fluffychat/pangea/widgets/igc/word_data_card.dart';
import 'package:fluffychat/pangea/widgets/message_display_card.dart'; import 'package:fluffychat/pangea/widgets/message_display_card.dart';
import 'package:fluffychat/pangea/widgets/practice_activity/practice_activity_card.dart'; import 'package:fluffychat/pangea/widgets/practice_activity/practice_activity_card.dart';
import 'package:fluffychat/pangea/widgets/practice_activity/target_tokens_controller.dart';
import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -24,13 +27,15 @@ const double minCardHeight = 70;
class MessageToolbar extends StatelessWidget { class MessageToolbar extends StatelessWidget {
final PangeaMessageEvent pangeaMessageEvent; final PangeaMessageEvent pangeaMessageEvent;
final MessageOverlayController overLayController; final MessageOverlayController overLayController;
final TtsController tts; final TtsController ttsController;
final TargetTokensController targetTokensController;
const MessageToolbar({ const MessageToolbar({
super.key, super.key,
required this.pangeaMessageEvent, required this.pangeaMessageEvent,
required this.overLayController, required this.overLayController,
required this.tts, required this.ttsController,
required this.targetTokensController,
}); });
Widget toolbarContent(BuildContext context) { Widget toolbarContent(BuildContext context) {
@ -58,7 +63,7 @@ class MessageToolbar extends StatelessWidget {
messageEvent: pangeaMessageEvent, messageEvent: pangeaMessageEvent,
overlayController: overLayController, overlayController: overLayController,
selection: overLayController.selectedSpan, selection: overLayController.selectedSpan,
tts: tts, tts: ttsController,
setIsPlayingAudio: overLayController.setIsPlayingAudio, setIsPlayingAudio: overLayController.setIsPlayingAudio,
); );
case MessageMode.speechToText: case MessageMode.speechToText:
@ -67,8 +72,27 @@ class MessageToolbar extends StatelessWidget {
); );
case MessageMode.definition: case MessageMode.definition:
if (!overLayController.isSelection) { if (!overLayController.isSelection) {
return MessageDisplayCard( return FutureBuilder(
displayText: L10n.of(context)!.selectToDefine, future: targetTokensController.targetTokens(pangeaMessageEvent),
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const ToolbarContentLoadingIndicator();
} else if (snapshot.hasError ||
snapshot.data == null ||
snapshot.data!.isEmpty) {
return const Padding(
padding: EdgeInsets.all(8),
child: CardErrorWidget(
error: "No tokens available",
maxWidth: AppConfig.toolbarMinWidth,
),
);
} else {
return MessageDisplayCard(
displayText: L10n.of(context)!.selectToDefine,
);
}
},
); );
} else { } else {
try { try {
@ -106,7 +130,8 @@ class MessageToolbar extends StatelessWidget {
return PracticeActivityCard( return PracticeActivityCard(
pangeaMessageEvent: pangeaMessageEvent, pangeaMessageEvent: pangeaMessageEvent,
overlayController: overLayController, overlayController: overLayController,
tts: tts, ttsController: ttsController,
targetTokensController: targetTokensController,
); );
default: default:
debugger(when: kDebugMode); debugger(when: kDebugMode);

@ -29,17 +29,19 @@ class OverlayMessageTextState extends State<OverlayMessageText> {
@override @override
void initState() { void initState() {
tokens = widget.pangeaMessageEvent.originalSent?.tokens; final repEvent = widget.pangeaMessageEvent.messageDisplayRepresentation;
if (widget.pangeaMessageEvent.originalSent != null && tokens == null) { if (repEvent != null) {
widget.pangeaMessageEvent.originalSent! tokens = repEvent.tokens;
.tokensGlobal( if (tokens == null) {
widget.pangeaMessageEvent.senderId, repEvent
widget.pangeaMessageEvent.originServerTs, .tokensGlobal(
) widget.pangeaMessageEvent.senderId,
.then((tokens) { widget.pangeaMessageEvent.originServerTs,
// this isn't currently working because originalSent's _event is null )
setState(() => this.tokens = tokens); .then((tokens) {
}); setState(() => this.tokens = tokens);
});
}
} }
super.initState(); super.initState();
} }
@ -70,7 +72,7 @@ class OverlayMessageTextState extends State<OverlayMessageText> {
// Convert the entire message into a list of characters // Convert the entire message into a list of characters
final Characters messageCharacters = final Characters messageCharacters =
widget.pangeaMessageEvent.event.body.characters; widget.pangeaMessageEvent.messageDisplayText.characters;
// When building token positions, use grapheme cluster indices // When building token positions, use grapheme cluster indices
final List<TokenPosition> tokenPositions = []; final List<TokenPosition> tokenPositions = [];

@ -91,12 +91,7 @@ class PangeaRichTextState extends State<PangeaRichText> {
debugger(when: kDebugMode); debugger(when: kDebugMode);
} }
repEvent = widget.pangeaMessageEvent repEvent = widget.pangeaMessageEvent.messageDisplayRepresentation?.content;
.representationByLanguage(
widget.pangeaMessageEvent.messageDisplayLangCode,
)
?.content;
if (repEvent == null) { if (repEvent == null) {
setState(() => _fetchingRepresentation = true); setState(() => _fetchingRepresentation = true);
widget.pangeaMessageEvent widget.pangeaMessageEvent

@ -31,13 +31,15 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
class PracticeActivityCard extends StatefulWidget { class PracticeActivityCard extends StatefulWidget {
final PangeaMessageEvent pangeaMessageEvent; final PangeaMessageEvent pangeaMessageEvent;
final MessageOverlayController overlayController; final MessageOverlayController overlayController;
final TtsController tts; final TtsController ttsController;
final TargetTokensController targetTokensController;
const PracticeActivityCard({ const PracticeActivityCard({
super.key, super.key,
required this.pangeaMessageEvent, required this.pangeaMessageEvent,
required this.overlayController, required this.overlayController,
required this.tts, required this.ttsController,
required this.targetTokensController,
}); });
@override @override
@ -51,10 +53,6 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
PracticeActivityRecordModel? currentCompletionRecord; PracticeActivityRecordModel? currentCompletionRecord;
bool fetchingActivity = false; bool fetchingActivity = false;
// tracks the target tokens for the current message
// in a separate controller to manage the state
TargetTokensController targetTokensController = TargetTokensController();
List<PracticeActivityEvent> get practiceActivities => List<PracticeActivityEvent> get practiceActivities =>
widget.pangeaMessageEvent.practiceActivities; widget.pangeaMessageEvent.practiceActivities;
@ -124,7 +122,7 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
return null; return null;
} }
if (widget.pangeaMessageEvent.originalSent == null) { if (widget.pangeaMessageEvent.messageDisplayRepresentation == null) {
debugger(when: kDebugMode); debugger(when: kDebugMode);
_updateFetchingActivity(false); _updateFetchingActivity(false);
ErrorHandler.logError( ErrorHandler.logError(
@ -142,8 +140,8 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
MessageActivityRequest( MessageActivityRequest(
userL1: pangeaController.languageController.userL1!.langCode, userL1: pangeaController.languageController.userL1!.langCode,
userL2: pangeaController.languageController.userL2!.langCode, userL2: pangeaController.languageController.userL2!.langCode,
messageText: widget.pangeaMessageEvent.originalSent!.text, messageText: widget.pangeaMessageEvent.messageDisplayText,
tokensWithXP: await targetTokensController.targetTokens( tokensWithXP: await widget.targetTokensController.targetTokens(
widget.pangeaMessageEvent, widget.pangeaMessageEvent,
), ),
messageId: widget.pangeaMessageEvent.eventId, messageId: widget.pangeaMessageEvent.eventId,
@ -151,7 +149,8 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
.map((activity) => activity.activityRequestMetaData) .map((activity) => activity.activityRequestMetaData)
.toList(), .toList(),
activityQualityFeedback: activityFeedback, activityQualityFeedback: activityFeedback,
clientCompatibleActivities: widget.tts.isLanguageFullySupported clientCompatibleActivities: widget
.ttsController.isLanguageFullySupported
? ActivityTypeEnum.values ? ActivityTypeEnum.values
: ActivityTypeEnum.values : ActivityTypeEnum.values
.where((type) => type != ActivityTypeEnum.wordFocusListening) .where((type) => type != ActivityTypeEnum.wordFocusListening)
@ -221,7 +220,7 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
// update the target tokens with the new construct uses // update the target tokens with the new construct uses
// NOTE - multiple choice activity is handling adding these to analytics // NOTE - multiple choice activity is handling adding these to analytics
await targetTokensController.updateTokensWithConstructs( await widget.targetTokensController.updateTokensWithConstructs(
currentCompletionRecord!.usesForAllResponses( currentCompletionRecord!.usesForAllResponses(
currentActivity!, currentActivity!,
metadata, metadata,
@ -320,7 +319,7 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
return MultipleChoiceActivity( return MultipleChoiceActivity(
practiceCardController: this, practiceCardController: this,
currentActivity: currentActivity!, currentActivity: currentActivity!,
tts: widget.tts, tts: widget.ttsController,
eventID: widget.pangeaMessageEvent.eventId, eventID: widget.pangeaMessageEvent.eventId,
); );
case ActivityTypeEnum.wordFocusListening: case ActivityTypeEnum.wordFocusListening:
@ -329,7 +328,7 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
return MultipleChoiceActivity( return MultipleChoiceActivity(
practiceCardController: this, practiceCardController: this,
currentActivity: currentActivity!, currentActivity: currentActivity!,
tts: widget.tts, tts: widget.ttsController,
eventID: widget.pangeaMessageEvent.eventId, eventID: widget.pangeaMessageEvent.eventId,
); );
// default: // default:

@ -38,12 +38,11 @@ class TargetTokensController {
Future<List<TokenWithXP>> _initialize( Future<List<TokenWithXP>> _initialize(
PangeaMessageEvent pangeaMessageEvent, PangeaMessageEvent pangeaMessageEvent,
) async { ) async {
final tokens = await pangeaMessageEvent final tokens =
.representationByLanguage(pangeaMessageEvent.messageDisplayLangCode) await pangeaMessageEvent.messageDisplayRepresentation?.tokensGlobal(
?.tokensGlobal( pangeaMessageEvent.senderId,
pangeaMessageEvent.senderId, pangeaMessageEvent.originServerTs,
pangeaMessageEvent.originServerTs, );
);
if (tokens == null || tokens.isEmpty) { if (tokens == null || tokens.isEmpty) {
debugger(when: kDebugMode); debugger(when: kDebugMode);

Loading…
Cancel
Save