2455 reading assistance feedback from linh (#2456)
* chore: show correct morph once matched * fix: account for morph activities in function to determine is token activity is complete * chore: on click already correctly matched item, open the toolbar for the corresponding token
This commit is contained in:
parent
43d6b992f7
commit
739e271cb4
8 changed files with 66 additions and 26 deletions
|
|
@ -406,7 +406,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
pangeaController.getAnalytics.analyticsStream.stream.listen((update) {
|
||||
if (update.targetID == null) return;
|
||||
OverlayUtil.showOverlay(
|
||||
overlayKey: update.targetID,
|
||||
overlayKey: "${update.targetID ?? ""}_points",
|
||||
followerAnchor: Alignment.bottomCenter,
|
||||
targetAnchor: Alignment.bottomCenter,
|
||||
context: context,
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ class PointsGainedAnimationState extends State<PointsGainedAnimation>
|
|||
_controller?.forward().then(
|
||||
(_) {
|
||||
if (!mounted) return;
|
||||
MatrixState.pAnyState.closeOverlay(widget.targetID);
|
||||
MatrixState.pAnyState.closeOverlay("${widget.targetID}_points");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ class PointsGainedAnimationState extends State<PointsGainedAnimation>
|
|||
_offsetAnimation == null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
MatrixState.pAnyState.closeOverlay(widget.targetID);
|
||||
MatrixState.pAnyState.closeOverlay("${widget.targetID}_points");
|
||||
}
|
||||
});
|
||||
return const SizedBox();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ import 'package:fluffychat/config/app_config.dart';
|
|||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/message_token_text/dotted_border_painter.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/activity_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart';
|
||||
import 'package:fluffychat/pangea/morphs/morph_features_enum.dart';
|
||||
import 'package:fluffychat/pangea/morphs/morph_icon.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/practice_choice.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/practice_target.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/enums/message_mode_enum.dart';
|
||||
|
|
@ -181,17 +183,12 @@ class MessageTokenButtonState extends State<MessageTokenButton>
|
|||
// );
|
||||
}
|
||||
|
||||
bool get isActivityCompleteForToken {
|
||||
if (activity?.activityType == ActivityTypeEnum.morphId) {
|
||||
return (activity?.record.completeResponses ?? 0) > 0;
|
||||
}
|
||||
for (final response in activity!.record.responses) {
|
||||
if (response.cId == widget.token.vocabConstructID && response.isCorrect) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool get isActivityCompleteForToken =>
|
||||
activity?.isCompleteByToken(
|
||||
widget.token,
|
||||
activity!.morphFeature,
|
||||
) ==
|
||||
true;
|
||||
|
||||
Color get color {
|
||||
if (activity == null) {
|
||||
|
|
@ -209,6 +206,31 @@ class MessageTokenButtonState extends State<MessageTokenButton>
|
|||
if (MessageMode.wordEmoji == widget.overlayController?.toolbarMode) {
|
||||
return SizedBox(height: height, child: emojiView);
|
||||
}
|
||||
if (MessageMode.wordMorph == widget.overlayController?.toolbarMode &&
|
||||
activity?.morphFeature != null) {
|
||||
final morphFeature = activity!.morphFeature!;
|
||||
final morphTag = widget.token.morphIdByFeature(morphFeature);
|
||||
if (morphTag != null) {
|
||||
return Tooltip(
|
||||
message: getGrammarCopy(
|
||||
category: morphFeature.toShortString(),
|
||||
lemma: morphTag.lemma,
|
||||
context: context,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: widget.width,
|
||||
height: height,
|
||||
child: Center(
|
||||
child: MorphIcon(
|
||||
morphFeature: morphFeature,
|
||||
morphTag: morphTag.lemma,
|
||||
size: const Size(24.0, 24.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return SizedBox(height: height);
|
||||
}
|
||||
|
||||
|
|
@ -216,6 +238,7 @@ class MessageTokenButtonState extends State<MessageTokenButton>
|
|||
if (activity?.morphFeature == null) {
|
||||
return SizedBox(height: height);
|
||||
}
|
||||
|
||||
final bool isSelected =
|
||||
(widget.overlayController?.selectedMorph?.token == widget.token &&
|
||||
widget.overlayController?.selectedMorph?.morph ==
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ class PracticeTarget {
|
|||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'tokens': tokens.map((e) => e.toJson()).toList(),
|
||||
'activityType': activityType.index,
|
||||
'morphFeature': morphFeature?.index,
|
||||
'activityType': activityType.name,
|
||||
'morphFeature': morphFeature?.name,
|
||||
'userL2': userL2,
|
||||
};
|
||||
}
|
||||
|
|
@ -114,6 +114,13 @@ class PracticeTarget {
|
|||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (activityType == ActivityTypeEnum.morphId) {
|
||||
return record.responses.any(
|
||||
(res) => res.cId == token.morphIdByFeature(morph!) && res.isCorrect,
|
||||
);
|
||||
}
|
||||
|
||||
return record.responses.any(
|
||||
(res) => res.cId == token.vocabConstructID && res.isCorrect,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class MessageMorphChoiceItemState extends State<MessageMorphChoiceItem> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final color = _color;
|
||||
final iconSize = FluffyThemes.isColumnMode(context) ? 40.0 : 24.0;
|
||||
final iconSize = FluffyThemes.isColumnMode(context) ? 32.0 : 24.0;
|
||||
final style = FluffyThemes.isColumnMode(context)
|
||||
? Theme.of(context).textTheme.bodyLarge
|
||||
: Theme.of(context).textTheme.bodySmall;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import 'dart:developer';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/widgets/choice_animation.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/activity_type_enum.dart';
|
||||
|
|
@ -89,6 +91,9 @@ class MatchActivityCard extends StatelessWidget {
|
|||
isSelected: overlayController.selectedChoice == cf,
|
||||
isCorrect: wasCorrect,
|
||||
child: PracticeMatchItem(
|
||||
token: currentActivity.practiceTarget.tokens.firstWhereOrNull(
|
||||
(t) => t.vocabConstructID == cf.form.cId,
|
||||
),
|
||||
isSelected: overlayController.selectedChoice == cf,
|
||||
isCorrect: wasCorrect,
|
||||
constructForm: cf,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
|||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/practice_choice.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/controllers/tts_controller.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/widgets/message_selection_overlay.dart';
|
||||
|
|
@ -13,6 +14,7 @@ class PracticeMatchItem extends StatefulWidget {
|
|||
const PracticeMatchItem({
|
||||
super.key,
|
||||
required this.content,
|
||||
required this.token,
|
||||
required this.constructForm,
|
||||
required this.isCorrect,
|
||||
required this.isSelected,
|
||||
|
|
@ -22,6 +24,7 @@ class PracticeMatchItem extends StatefulWidget {
|
|||
});
|
||||
|
||||
final Widget content;
|
||||
final PangeaToken? token;
|
||||
final PracticeChoice constructForm;
|
||||
final String? audioContent;
|
||||
final MessageOverlayController overlayController;
|
||||
|
|
@ -131,7 +134,9 @@ class PracticeMatchItemState extends State<PracticeMatchItem> {
|
|||
|
||||
void onTap() {
|
||||
play();
|
||||
widget.overlayController.onChoiceSelect(widget.constructForm);
|
||||
isCorrect == null || !isCorrect! || widget.token == null
|
||||
? widget.overlayController.onChoiceSelect(widget.constructForm)
|
||||
: widget.overlayController.updateSelectedSpan(widget.token!.text);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
return;
|
||||
}
|
||||
|
||||
_updateSelectedSpan(widget._initialSelectedToken!.text);
|
||||
updateSelectedSpan(widget._initialSelectedToken!.text);
|
||||
|
||||
int retries = 0;
|
||||
while (retries < 5 &&
|
||||
|
|
@ -285,14 +285,14 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
}
|
||||
|
||||
/// Update [selectedSpan]
|
||||
void _updateSelectedSpan(PangeaTokenText selectedSpan, [bool force = false]) {
|
||||
void updateSelectedSpan(PangeaTokenText selectedSpan, [bool force = false]) {
|
||||
if (selectedMorph != null) {
|
||||
selectedMorph = null;
|
||||
}
|
||||
// close overlay of previous token
|
||||
if (selectedToken != null) {
|
||||
MatrixState.pAnyState.closeOverlay(
|
||||
selectedToken!.text.uniqueKey,
|
||||
"${selectedToken!.text.uniqueKey}_toolbar",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +329,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
closePrevOverlay: false,
|
||||
backDropToDismiss: false,
|
||||
addBorder: false,
|
||||
overlayKey: selectedToken!.text.uniqueKey,
|
||||
overlayKey: "${selectedToken!.text.uniqueKey}_toolbar",
|
||||
maxHeight: AppConfig.toolbarMaxHeight,
|
||||
maxWidth: AppConfig.toolbarMinWidth,
|
||||
);
|
||||
|
|
@ -341,7 +341,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
|
||||
// close overlay of any selected token
|
||||
if (_selectedSpan != null) {
|
||||
_updateSelectedSpan(_selectedSpan!);
|
||||
updateSelectedSpan(_selectedSpan!);
|
||||
}
|
||||
|
||||
toolbarMode = mode;
|
||||
|
|
@ -383,7 +383,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
toolbarMode = MessageMode.wordMorph;
|
||||
// // close overlay of previous token
|
||||
if (_selectedSpan != null && _selectedSpan != newMorph.token.text) {
|
||||
_updateSelectedSpan(_selectedSpan!);
|
||||
updateSelectedSpan(_selectedSpan!);
|
||||
}
|
||||
selectedMorph = newMorph;
|
||||
setState(() {});
|
||||
|
|
@ -543,7 +543,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
);
|
||||
}
|
||||
|
||||
_updateSelectedSpan(token.text);
|
||||
updateSelectedSpan(token.text);
|
||||
}
|
||||
|
||||
/// Whether the given token is currently selected or highlighted
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue