explanation

This commit is contained in:
gitea
2026-02-03 19:34:33 +01:00
parent cd3b75995d
commit 82be8dbdf3
7 changed files with 55 additions and 0 deletions
+16
View File
@@ -209,6 +209,22 @@ class _AttemptResultScreenState extends State<AttemptResultScreen> {
),
);
}),
if (q.explanation != null && q.explanation!.trim().isNotEmpty) ...[
const SizedBox(height: 16),
const Divider(),
const SizedBox(height: 8),
Text(
'Explanation',
style: Theme.of(context).textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
q.explanation!,
style: Theme.of(context).textTheme.bodyMedium,
),
],
],
),
),
+18
View File
@@ -161,6 +161,7 @@ class _DeckEditScreenState extends State<DeckEditScreen> {
final list = questions.map((q) => {
'id': q.id,
'prompt': q.prompt,
if (q.explanation != null && q.explanation!.isNotEmpty) 'explanation': q.explanation,
'answers': q.answers,
'correctAnswerIndices': q.correctAnswerIndices,
}).toList();
@@ -378,6 +379,16 @@ class _QuestionEditorCardState extends State<QuestionEditorCard> {
),
maxLines: 2,
),
const SizedBox(height: 12),
TextField(
controller: widget.editor.explanationController,
decoration: const InputDecoration(
labelText: 'Explanation (optional)',
helperText: 'Shown when viewing question details after an attempt',
border: OutlineInputBorder(),
),
maxLines: 3,
),
const SizedBox(height: 16),
// Answers
@@ -474,12 +485,14 @@ class _QuestionEditorCardState extends State<QuestionEditorCard> {
class QuestionEditor {
final TextEditingController promptController;
final TextEditingController explanationController;
final List<TextEditingController> answerControllers;
Set<int> correctAnswerIndices;
final String? originalId;
QuestionEditor({
required this.promptController,
required this.explanationController,
required this.answerControllers,
Set<int>? correctAnswerIndices,
this.originalId,
@@ -488,6 +501,7 @@ class QuestionEditor {
factory QuestionEditor.fromQuestion(Question question) {
return QuestionEditor(
promptController: TextEditingController(text: question.prompt),
explanationController: TextEditingController(text: question.explanation ?? ''),
answerControllers: question.answers
.map((answer) => TextEditingController(text: answer))
.toList(),
@@ -499,6 +513,7 @@ class QuestionEditor {
factory QuestionEditor.empty() {
return QuestionEditor(
promptController: TextEditingController(),
explanationController: TextEditingController(),
answerControllers: [
TextEditingController(),
TextEditingController(),
@@ -521,9 +536,11 @@ class QuestionEditor {
}
Question toQuestion() {
final explanationText = explanationController.text.trim();
return Question(
id: originalId ?? DateTime.now().millisecondsSinceEpoch.toString(),
prompt: promptController.text.trim(),
explanation: explanationText.isEmpty ? null : explanationText,
answers: answerControllers.map((c) => c.text.trim()).toList(),
correctAnswerIndices: correctAnswerIndices.toList()..sort(),
);
@@ -531,6 +548,7 @@ class QuestionEditor {
void dispose() {
promptController.dispose();
explanationController.dispose();
for (final controller in answerControllers) {
controller.dispose();
}
+2
View File
@@ -64,6 +64,7 @@ class _DeckImportScreenState extends State<DeckImportScreen> {
return Question(
id: questionMap['id'] as String? ?? '',
prompt: questionMap['prompt'] as String? ?? '',
explanation: questionMap['explanation'] as String?,
answers: (questionMap['answers'] as List<dynamic>?)
?.map((e) => e.toString())
.toList() ??
@@ -643,6 +644,7 @@ class _DeckImportScreenState extends State<DeckImportScreen> {
const Text('• answers: array of strings (required)'),
const Text('• correctAnswerIndex: number (deprecated, use correctAnswerIndices)'),
const Text('• correctAnswerIndices: array of numbers (for multiple correct answers)'),
const Text('• explanation: string (optional, shown when viewing question details)'),
const Text('• isKnown: boolean (optional)'),
const Text('• consecutiveCorrect: number (optional)'),
const Text('• priorityPoints: number (optional)'),
@@ -156,8 +156,10 @@ class _FlaggedQuestionsScreenState extends State<FlaggedQuestionsScreen> {
if (id == null) continue;
final existing = questionMap[id];
if (existing == null) continue;
final explanationText = editor.explanationController.text.trim();
final updated = existing.copyWith(
prompt: editor.promptController.text.trim(),
explanation: explanationText.isEmpty ? null : explanationText,
answers: editor.answerControllers.map((c) => c.text.trim()).toList(),
correctAnswerIndices: editor.correctAnswerIndices.toList()..sort(),
);
@@ -203,6 +205,7 @@ class _FlaggedQuestionsScreenState extends State<FlaggedQuestionsScreen> {
final list = questions.map((q) => {
'id': q.id,
'prompt': q.prompt,
if (q.explanation != null && q.explanation!.isNotEmpty) 'explanation': q.explanation,
'answers': q.answers,
'correctAnswerIndices': q.correctAnswerIndices,
}).toList();