1949-changing-it-feedback (#2088)
--------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: ggurdin <46800240+ggurdin@users.noreply.github.com> Co-authored-by: ggurdin <ggurdin@gmail.com>
This commit is contained in:
parent
6e7ae5c044
commit
96197138ba
16 changed files with 271 additions and 177 deletions
|
|
@ -4849,5 +4849,11 @@
|
|||
"wordFocusListeningMultipleChoice": "Which audio matches the word?",
|
||||
"createActivity": "Create activity",
|
||||
"startChat": "Start a chat",
|
||||
"translationProblem": "Translation problem"
|
||||
"translationProblem": "Translation problem",
|
||||
"perfectTranslation": "Perfect translation!",
|
||||
"greatJobTranslation": "Great job with this translation!",
|
||||
"goodJobTranslation": "Good work on this translation.",
|
||||
"makingProgress": "You're making progress!",
|
||||
"keepPracticing": "Keep practicing!",
|
||||
"niceJob": "Nice job!"
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/analytics_downloads/analytics_summary_enum.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/learning_skills_enum.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/activity_type_enum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
enum ConstructUseTypeEnum {
|
||||
/// produced in chat by user, igc was run, and we've judged it to be a correct use
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/bot/utils/bot_style.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PointsGainedAnimation extends StatefulWidget {
|
||||
final int points;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/practice_selection_repo.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/widgets/message_token_text.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import '../../../utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
|
||||
class ChatListItemSubtitle extends StatelessWidget {
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'package:fluffychat/pangea/choreographer/constants/choreo_constants.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/controllers/error_service.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/repo/full_text_translation_repo.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import '../repo/similarity_repo.dart';
|
||||
|
||||
class AlternativeTranslator {
|
||||
|
|
@ -18,7 +19,6 @@ class AlternativeTranslator {
|
|||
FeedbackKey? translationFeedbackKey;
|
||||
List<String> translations = [];
|
||||
SimilartyResponseModel? similarityResponse;
|
||||
|
||||
AlternativeTranslator(this.choreographer);
|
||||
|
||||
void clear() {
|
||||
|
|
@ -31,71 +31,49 @@ class AlternativeTranslator {
|
|||
similarityResponse = null;
|
||||
}
|
||||
|
||||
double get _percentCorrectChoices {
|
||||
final totalSteps = choreographer.choreoRecord.itSteps.length;
|
||||
if (totalSteps == 0) return 0.0;
|
||||
final int correctFirstAttempts = choreographer.itController.completedITSteps
|
||||
.where(
|
||||
(step) => !step.continuances.any(
|
||||
(c) =>
|
||||
c.level != ChoreoConstants.levelThresholdForGreen &&
|
||||
c.wasClicked,
|
||||
),
|
||||
)
|
||||
.length;
|
||||
final double percentage = (correctFirstAttempts / totalSteps) * 100;
|
||||
return percentage;
|
||||
}
|
||||
|
||||
int get starRating {
|
||||
final double percent = _percentCorrectChoices;
|
||||
if (percent == 100) return 5;
|
||||
if (percent >= 80) return 4;
|
||||
if (percent >= 60) return 3;
|
||||
if (percent >= 40) return 2;
|
||||
if (percent > 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Future<void> setTranslationFeedback() async {
|
||||
try {
|
||||
choreographer.startLoading();
|
||||
translationFeedbackKey = FeedbackKey.loadingPleaseWait;
|
||||
|
||||
showTranslationFeedback = true;
|
||||
|
||||
userTranslation = choreographer.currentText;
|
||||
|
||||
if (choreographer.itController.allCorrect) {
|
||||
final double percentCorrect = _percentCorrectChoices;
|
||||
|
||||
// Set feedback based on percentage
|
||||
if (percentCorrect == 100) {
|
||||
translationFeedbackKey = FeedbackKey.allCorrect;
|
||||
return;
|
||||
} else if (percentCorrect >= 80) {
|
||||
translationFeedbackKey = FeedbackKey.newWayAllGood;
|
||||
} else {
|
||||
translationFeedbackKey = FeedbackKey.othersAreBetter;
|
||||
}
|
||||
|
||||
final String? goldRouteTranslation =
|
||||
choreographer.itController.goldRouteTracker.fullTranslation;
|
||||
|
||||
final FullTextTranslationResponseModel results =
|
||||
await FullTextTranslationRepo.translate(
|
||||
accessToken: choreographer.accessToken,
|
||||
request: FullTextTranslationRequestModel(
|
||||
text: choreographer.itController.sourceText!,
|
||||
tgtLang: choreographer.l2LangCode!,
|
||||
userL2: choreographer.l2LangCode!,
|
||||
userL1: choreographer.l1LangCode!,
|
||||
deepL: goldRouteTranslation == null,
|
||||
),
|
||||
);
|
||||
translations = results.translations;
|
||||
if (results.deepL != null || goldRouteTranslation != null) {
|
||||
translations.insert(0, (results.deepL ?? goldRouteTranslation)!);
|
||||
}
|
||||
// final List<String> altAndUser = [...results.translations];
|
||||
// if (results.deepL != null) {
|
||||
// altAndUser.add(results.deepL!);
|
||||
// }
|
||||
// altAndUser.add(userTranslation);
|
||||
|
||||
if (userTranslation?.toLowerCase() ==
|
||||
results.bestTranslation.toLowerCase()) {
|
||||
translationFeedbackKey = FeedbackKey.allCorrect;
|
||||
return;
|
||||
}
|
||||
|
||||
similarityResponse = await SimilarityRepo.get(
|
||||
accessToken: choreographer.accessToken,
|
||||
request: SimilarityRequestModel(
|
||||
benchmark: results.bestTranslation,
|
||||
toCompare: [userTranslation!],
|
||||
),
|
||||
);
|
||||
|
||||
// if (similarityResponse!
|
||||
// .userTranslationIsSameAsBotTranslation(userTranslation!)) {
|
||||
// translationFeedbackKey = FeedbackKey.allCorrect;
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (similarityResponse!
|
||||
// .userTranslationIsDifferentButBetter(userTranslation!)) {
|
||||
// translationFeedbackKey = FeedbackKey.newWayAllGood;
|
||||
// return;
|
||||
// }
|
||||
showAlternativeTranslations = true;
|
||||
translationFeedbackKey = FeedbackKey.othersAreBetter;
|
||||
} catch (err, stack) {
|
||||
if (err is! http.Response) {
|
||||
ErrorHandler.logError(
|
||||
|
|
@ -119,36 +97,50 @@ class AlternativeTranslator {
|
|||
}
|
||||
}
|
||||
|
||||
String translationFeedback(BuildContext context) {
|
||||
List<PangeaToken> get _selectedTokens => choreographer.choreoRecord.itSteps
|
||||
.where((step) => step.chosenContinuance != null)
|
||||
.map(
|
||||
(step) => step.chosenContinuance!.tokens.where(
|
||||
(token) => token.lemma.saveVocab,
|
||||
),
|
||||
)
|
||||
.expand((element) => element)
|
||||
.toList();
|
||||
|
||||
int countVocabularyWordsFromSteps() =>
|
||||
_selectedTokens.map((t) => t.lemma.text.toLowerCase()).toSet().length;
|
||||
|
||||
int countGrammarConstructsFromSteps() => _selectedTokens
|
||||
.map(
|
||||
(t) => t.morph.entries.map(
|
||||
(m) => "${m.key}:${m.value}".toLowerCase(),
|
||||
),
|
||||
)
|
||||
.expand((m) => m)
|
||||
.toSet()
|
||||
.length;
|
||||
|
||||
String getDefaultFeedback(BuildContext context) {
|
||||
final l10n = L10n.of(context);
|
||||
switch (translationFeedbackKey) {
|
||||
case FeedbackKey.allCorrect:
|
||||
return "Match: 100%\n${L10n.of(context).allCorrect}";
|
||||
return l10n.perfectTranslation;
|
||||
case FeedbackKey.newWayAllGood:
|
||||
return "Match: 100%\n${L10n.of(context).newWayAllGood}";
|
||||
return l10n.greatJobTranslation;
|
||||
case FeedbackKey.othersAreBetter:
|
||||
final num userScore =
|
||||
(similarityResponse!.userScore(userTranslation!) * 100).round();
|
||||
final String displayScore = userScore.toString();
|
||||
if (userScore > 90) {
|
||||
return "Match: $displayScore%\n${L10n.of(context).almostPerfect}";
|
||||
if (_percentCorrectChoices >= 60) {
|
||||
return l10n.goodJobTranslation;
|
||||
}
|
||||
if (userScore > 80) {
|
||||
return "Match: $displayScore%\n${L10n.of(context).prettyGood}";
|
||||
if (_percentCorrectChoices >= 40) {
|
||||
return l10n.makingProgress;
|
||||
}
|
||||
return "Match: $displayScore%\n${L10n.of(context).othersAreBetter}";
|
||||
// case FeedbackKey.commonalityFeedback:
|
||||
// final int count = controller.completedITSteps
|
||||
// .where((element) => element.isCorrect)
|
||||
// .toList()
|
||||
// .length;
|
||||
// final int total = controller.completedITSteps.length;
|
||||
// return L10n.of(context).commonalityFeedback(count,total);
|
||||
return l10n.keepPracticing;
|
||||
case FeedbackKey.loadingPleaseWait:
|
||||
return L10n.of(context).letMeThink;
|
||||
return l10n.letMeThink;
|
||||
case FeedbackKey.allDone:
|
||||
return L10n.of(context).allDone;
|
||||
return l10n.allDone;
|
||||
default:
|
||||
return L10n.of(context).loadingPleaseWait;
|
||||
return l10n.loadingPleaseWait;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,6 +230,15 @@ class ITBarState extends State<ITBar> with SingleTickerProviderStateMixin {
|
|||
: itController.isTranslationDone
|
||||
? TranslationFeedback(
|
||||
controller: itController,
|
||||
vocabCount: itController
|
||||
.choreographer.altTranslator
|
||||
.countVocabularyWordsFromSteps(),
|
||||
grammarCount: itController
|
||||
.choreographer.altTranslator
|
||||
.countGrammarConstructsFromSteps(),
|
||||
feedbackText: itController
|
||||
.choreographer.altTranslator
|
||||
.getDefaultFeedback(context),
|
||||
)
|
||||
: ITChoices(controller: itController),
|
||||
),
|
||||
|
|
|
|||
64
lib/pangea/choreographer/widgets/it_feedback_stars.dart
Normal file
64
lib/pangea/choreographer/widgets/it_feedback_stars.dart
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/widgets/choice_animation.dart';
|
||||
|
||||
class FillingStars extends StatefulWidget {
|
||||
final int rating;
|
||||
|
||||
const FillingStars({
|
||||
super.key,
|
||||
required this.rating,
|
||||
});
|
||||
|
||||
@override
|
||||
State<FillingStars> createState() => _FillingStarsState();
|
||||
}
|
||||
|
||||
class _FillingStarsState extends State<FillingStars> {
|
||||
final List<bool> _isFilledList = List.filled(5, false);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _animate());
|
||||
}
|
||||
|
||||
Future<void> _animate() async {
|
||||
for (int i = 0; i < widget.rating; i++) {
|
||||
await Future.delayed(
|
||||
const Duration(milliseconds: choiceArrayAnimationDuration), () {
|
||||
if (mounted) {
|
||||
setState(() => _isFilledList[i] = true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: List.generate(5, (index) {
|
||||
return AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: choiceArrayAnimationDuration),
|
||||
transitionBuilder: (Widget child, Animation<double> animation) {
|
||||
return ScaleTransition(
|
||||
scale: animation,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: Icon(
|
||||
_isFilledList[index] ? Icons.star_rounded : Icons.star_rounded,
|
||||
key: ValueKey<bool>(_isFilledList[index]),
|
||||
color: _isFilledList[index]
|
||||
? AppConfig.gold
|
||||
: Theme.of(context).cardColor.withAlpha(180),
|
||||
size: 32.0,
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,94 +1,99 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/analytics_summary/progress_indicators_enum.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/widgets/it_feedback_stars.dart';
|
||||
import '../../bot/utils/bot_style.dart';
|
||||
import '../../common/utils/error_handler.dart';
|
||||
import '../controllers/it_controller.dart';
|
||||
import 'choice_array.dart';
|
||||
|
||||
class TranslationFeedback extends StatelessWidget {
|
||||
final int vocabCount;
|
||||
final int grammarCount;
|
||||
final String feedbackText;
|
||||
|
||||
final ITController controller;
|
||||
const TranslationFeedback({super.key, required this.controller});
|
||||
const TranslationFeedback({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.vocabCount,
|
||||
required this.grammarCount,
|
||||
required this.feedbackText,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String feedbackText;
|
||||
TextStyle? style;
|
||||
final altTranslator = controller.choreographer.altTranslator;
|
||||
try {
|
||||
feedbackText =
|
||||
controller.choreographer.altTranslator.translationFeedback(context);
|
||||
style = BotStyle.text(context);
|
||||
return Column(
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
FillingStars(rating: altTranslator.starRating),
|
||||
if (vocabCount > 0 || grammarCount > 0)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
if (vocabCount > 0)
|
||||
Row(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
Icon(
|
||||
Symbols.dictionary,
|
||||
color: ProgressIndicatorEnum.wordsUsed.color(context),
|
||||
size: 24,
|
||||
),
|
||||
Text(
|
||||
"+ $vocabCount",
|
||||
style: TextStyle(
|
||||
color: ProgressIndicatorEnum.wordsUsed.color(context),
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (grammarCount > 0)
|
||||
Row(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
Icon(
|
||||
Symbols.toys_and_games,
|
||||
color: ProgressIndicatorEnum.morphsUsed.color(context),
|
||||
size: 24,
|
||||
),
|
||||
Text(
|
||||
"+ $grammarCount",
|
||||
style: TextStyle(
|
||||
color:
|
||||
ProgressIndicatorEnum.morphsUsed.color(context),
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
else
|
||||
Text(
|
||||
feedbackText,
|
||||
textAlign: TextAlign.center,
|
||||
style: BotStyle.text(context),
|
||||
),
|
||||
const SizedBox(height: 16.0),
|
||||
],
|
||||
);
|
||||
} catch (err, stack) {
|
||||
feedbackText = "Nice job!";
|
||||
style = null;
|
||||
debugPrint("error getting copy and styles");
|
||||
debugPrint("Error in TranslationFeedback: $err");
|
||||
ErrorHandler.logError(
|
||||
e: err,
|
||||
s: stack,
|
||||
data: {
|
||||
"feedbackText": controller.choreographer.altTranslator
|
||||
.translationFeedback(context),
|
||||
},
|
||||
data: {},
|
||||
);
|
||||
|
||||
// Fallback to a simple message if anything goes wrong
|
||||
return Center(child: Text(L10n.of(context).niceJob));
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Column(
|
||||
children: [
|
||||
if (controller.choreographer.altTranslator.showTranslationFeedback)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 30),
|
||||
child: RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: "$feedbackText ",
|
||||
style: style,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
if (controller
|
||||
.choreographer.altTranslator.showAlternativeTranslations)
|
||||
AlternativeTranslations(controller: controller),
|
||||
// if (!controller
|
||||
// .choreographer.altTranslator.showAlternativeTranslations &&
|
||||
// !controller.choreographer.isFetching)
|
||||
// ITRestartButton(controller: controller),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AlternativeTranslations extends StatelessWidget {
|
||||
const AlternativeTranslations({
|
||||
super.key,
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
final ITController controller;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChoicesArray(
|
||||
originalSpan: controller.sourceText ?? "dummy",
|
||||
isLoading:
|
||||
controller.choreographer.altTranslator.loadingAlternativeTranslations,
|
||||
// choices: controller.choreographer.altTranslator.similarityResponse.scores
|
||||
choices: [
|
||||
Choice(text: controller.choreographer.altTranslator.translations.first),
|
||||
],
|
||||
// choices: controller.choreographer.altTranslator.translations,
|
||||
onPressed: (String value, int index) {
|
||||
controller.choreographer.onSelectAlternativeTranslation(
|
||||
controller.choreographer.altTranslator.translations[index],
|
||||
);
|
||||
},
|
||||
selectedChoiceIndex: null,
|
||||
tts: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
|
||||
class CustomizedSvg extends StatefulWidget {
|
||||
/// URL of the SVG file
|
||||
final String svgUrl;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart';
|
||||
|
|
@ -17,10 +23,6 @@ import 'package:fluffychat/pangea/practice_activities/practice_record.dart';
|
|||
import 'package:fluffychat/pangea/practice_activities/practice_target.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/relevant_span_display_details.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class PracticeActivityModel {
|
||||
List<PangeaToken> targetTokens;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart';
|
||||
import 'package:fluffychat/pangea/lemmas/lemma_info_response.dart';
|
||||
|
|
@ -9,7 +12,6 @@ import 'package:fluffychat/pangea/practice_activities/activity_type_enum.dart';
|
|||
import 'package:fluffychat/pangea/practice_activities/practice_selection_repo.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/practice_target.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class PracticeSelection {
|
||||
late String _userL2;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/practice_activities/practice_selection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
|
||||
class PracticeSelectionRepo {
|
||||
static final GetStorage _storage = GetStorage('practice_selection_cache');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.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';
|
||||
|
|
@ -9,8 +12,6 @@ import 'package:fluffychat/pangea/toolbar/enums/message_mode_enum.dart';
|
|||
import 'package:fluffychat/pangea/toolbar/reading_assistance_input_row/practice_match_item.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/widgets/message_audio_card.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/widgets/message_selection_overlay.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MatchActivityCard extends StatelessWidget {
|
||||
final PracticeActivityModel currentActivity;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
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/practice_activities/practice_choice.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/controllers/tts_controller.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/widgets/message_selection_overlay.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PracticeMatchItem extends StatefulWidget {
|
||||
const PracticeMatchItem({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/any_state_holder.dart';
|
||||
import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart';
|
||||
|
|
@ -11,8 +15,6 @@ import 'package:fluffychat/pangea/toolbar/enums/message_mode_enum.dart';
|
|||
import 'package:fluffychat/pangea/toolbar/widgets/message_selection_overlay.dart';
|
||||
import 'package:fluffychat/utils/url_launcher.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||
|
||||
/// Question - does this need to be stateful or does this work?
|
||||
/// Need to test.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart';
|
||||
|
|
@ -9,8 +13,6 @@ import 'package:fluffychat/pangea/toolbar/enums/message_mode_enum.dart';
|
|||
import 'package:fluffychat/pangea/toolbar/widgets/message_selection_overlay.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/widgets/practice_activity/word_audio_button.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class LemmaWidget extends StatefulWidget {
|
||||
final PangeaToken token;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue