Files

58 lines
1.9 KiB
Dart

import 'courses/courses.dart';
import 'models.dart';
import 'speech_compare.dart';
class ReviewCheckResult {
const ReviewCheckResult({
required this.complete,
required this.message,
this.dictation,
});
final bool complete;
final String message;
/// Word-by-word comparison with the dictated sentence; null otherwise.
final SpokenComparison? dictation;
}
/// Checks only the minimum information a learner needs to produce in a
/// review. The rule and the hint come from the core item's course JSON, which
/// accepts contractions and variable slot values instead of one fixed
/// sentence.
class ReviewFeedback {
const ReviewFeedback._();
static ReviewCheckResult check(ReviewItem item, String input) {
final dictation = item.skill == dictationSkill
? coreDictationSentences[item.id]
: null;
if (dictation != null) {
final comparison = compareSpoken(dictation.sentence, input);
final missing = comparison.total - comparison.heardCount;
final wrong = missing + comparison.extraWords.length;
return ReviewCheckResult(
complete: comparison.matches,
message: comparison.matches
? '听写正确。'
: '有 $wrong 处和听到的句子不一致。再听一次,检查拼写和漏掉的词。',
dictation: comparison,
);
}
final complete = isCoreItem(item.id)
? coreItemUsedIn(item.id, input)
: RegExp(r"[a-z]+(?:'[a-z]+)?")
.allMatches(normalizeAnswer(input))
.map((match) => match.group(0))
.toSet()
.length >=
2;
return ReviewCheckResult(
complete: complete,
message: complete
? '表达已完成,可以进入下一次复习安排。'
: coreReviewHints[item.id] ?? '再补充本次目标中的关键英文词或句型。',
);
}
}