fluffychat/lib/pangea/toolbar/message_practice/message_morph_choice.dart

170 lines
5.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/analytics_details_popup/morph_meaning_widget.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart';
import 'package:fluffychat/pangea/common/widgets/choice_animation.dart';
import 'package:fluffychat/pangea/constructs/construct_form.dart';
import 'package:fluffychat/pangea/constructs/construct_identifier.dart';
import 'package:fluffychat/pangea/events/models/pangea_token_model.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_activity_model.dart';
import 'package:fluffychat/pangea/practice_activities/practice_choice.dart';
import 'package:fluffychat/pangea/toolbar/message_practice/message_morph_choice_item.dart';
import 'package:fluffychat/pangea/toolbar/message_practice/practice_controller.dart';
// this widget will handle the content of the input bar when mode == MessageMode.wordMorph
// if initializing, with a selectedToken then we should show an activity if one is available
// in this case, we'll set selectedMorph to the first morph available for the selected token
// if initializing with a selectedMorph then we should show the first activity available for that morph
// if no activity available for that morph, then we should just show the details of the feature and tag
// the details of a morph will allow the user to edit the morphological tag of that feature.
const int numberOfMorphDistractors = 3;
class MessageMorphInputBarContent extends StatefulWidget {
final PracticeController controller;
final MorphPracticeActivityModel activity;
final PangeaToken? selectedToken;
final double maxWidth;
const MessageMorphInputBarContent({
super.key,
required this.controller,
required this.activity,
required this.selectedToken,
required this.maxWidth,
});
@override
MessageMorphInputBarContentState createState() =>
MessageMorphInputBarContentState();
}
class MessageMorphInputBarContentState
extends State<MessageMorphInputBarContent> {
String? selectedTag;
PangeaToken get token => widget.activity.tokens.first;
MorphFeaturesEnum get morph => widget.activity.morphFeature;
@override
void didUpdateWidget(covariant MessageMorphInputBarContent oldWidget) {
final selected = widget.controller.selectedMorph?.morph;
if (morph != selected || token != oldWidget.selectedToken) {
setState(() {});
}
super.didUpdateWidget(oldWidget);
}
TextStyle? textStyle(BuildContext context) => widget.maxWidth > 600
? Theme.of(context).textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.bold,
)
: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.bold,
);
@override
Widget build(BuildContext context) {
final iconSize = widget.maxWidth > 600
? 28.0
: widget.maxWidth > 600
? 24.0
: 16.0;
final spacing = widget.maxWidth > 600
? 16.0
: widget.maxWidth > 600
? 8.0
: 4.0;
return Column(
spacing: spacing,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
spacing: spacing,
children: [
MorphIcon(
morphFeature: morph,
morphTag: null,
size: Size(iconSize, iconSize),
showTooltip: false,
),
Flexible(
child: Text(
L10n.of(context).whatIsTheMorphTag(
morph.getDisplayCopy(context),
token.text.content,
),
style: textStyle(context),
textAlign: TextAlign.center,
),
),
],
),
Wrap(
alignment: WrapAlignment.center,
runAlignment: WrapAlignment.center,
spacing: spacing,
runSpacing: spacing,
children: widget.activity.multipleChoiceContent.choices.mapIndexed(
(index, choice) {
final wasCorrect = widget.controller.wasCorrectChoice(choice);
return ChoiceAnimationWidget(
isSelected: selectedTag == choice,
isCorrect: wasCorrect,
child: MessageMorphChoiceItem(
cId: ConstructIdentifier(
lemma: choice,
type: ConstructTypeEnum.morph,
category: morph.name,
),
onTap: () {
setState(() => selectedTag = choice);
widget.controller.onMatch(
token,
PracticeChoice(
choiceContent: choice,
form: ConstructForm(
cId: widget.activity.tokens.first.morphIdByFeature(
widget.activity.morphFeature,
)!,
form: token.text.content,
),
),
);
},
isSelected: selectedTag == choice,
isGold: wasCorrect,
shimmer: widget.controller.showChoiceShimmer,
),
);
},
).toList(),
),
if (selectedTag != null)
Container(
constraints: BoxConstraints(
minHeight: widget.maxWidth > 600 ? 20 : 34,
),
alignment: Alignment.center,
child: MorphMeaningWidget(
feature: morph,
tag: selectedTag!,
style: widget.maxWidth > 600
? Theme.of(context).textTheme.bodyLarge
: Theme.of(context).textTheme.bodySmall,
),
),
],
);
}
}