|
|
|
@ -161,6 +161,7 @@ class _DeckEditScreenState extends State<DeckEditScreen> {
|
|
|
|
final list = questions.map((q) => {
|
|
|
|
final list = questions.map((q) => {
|
|
|
|
'id': q.id,
|
|
|
|
'id': q.id,
|
|
|
|
'prompt': q.prompt,
|
|
|
|
'prompt': q.prompt,
|
|
|
|
|
|
|
|
if (q.explanation != null && q.explanation!.isNotEmpty) 'explanation': q.explanation,
|
|
|
|
'answers': q.answers,
|
|
|
|
'answers': q.answers,
|
|
|
|
'correctAnswerIndices': q.correctAnswerIndices,
|
|
|
|
'correctAnswerIndices': q.correctAnswerIndices,
|
|
|
|
}).toList();
|
|
|
|
}).toList();
|
|
|
|
@ -378,6 +379,16 @@ class _QuestionEditorCardState extends State<QuestionEditorCard> {
|
|
|
|
),
|
|
|
|
),
|
|
|
|
maxLines: 2,
|
|
|
|
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),
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
|
|
|
|
|
|
|
// Answers
|
|
|
|
// Answers
|
|
|
|
@ -474,12 +485,14 @@ class _QuestionEditorCardState extends State<QuestionEditorCard> {
|
|
|
|
|
|
|
|
|
|
|
|
class QuestionEditor {
|
|
|
|
class QuestionEditor {
|
|
|
|
final TextEditingController promptController;
|
|
|
|
final TextEditingController promptController;
|
|
|
|
|
|
|
|
final TextEditingController explanationController;
|
|
|
|
final List<TextEditingController> answerControllers;
|
|
|
|
final List<TextEditingController> answerControllers;
|
|
|
|
Set<int> correctAnswerIndices;
|
|
|
|
Set<int> correctAnswerIndices;
|
|
|
|
final String? originalId;
|
|
|
|
final String? originalId;
|
|
|
|
|
|
|
|
|
|
|
|
QuestionEditor({
|
|
|
|
QuestionEditor({
|
|
|
|
required this.promptController,
|
|
|
|
required this.promptController,
|
|
|
|
|
|
|
|
required this.explanationController,
|
|
|
|
required this.answerControllers,
|
|
|
|
required this.answerControllers,
|
|
|
|
Set<int>? correctAnswerIndices,
|
|
|
|
Set<int>? correctAnswerIndices,
|
|
|
|
this.originalId,
|
|
|
|
this.originalId,
|
|
|
|
@ -488,6 +501,7 @@ class QuestionEditor {
|
|
|
|
factory QuestionEditor.fromQuestion(Question question) {
|
|
|
|
factory QuestionEditor.fromQuestion(Question question) {
|
|
|
|
return QuestionEditor(
|
|
|
|
return QuestionEditor(
|
|
|
|
promptController: TextEditingController(text: question.prompt),
|
|
|
|
promptController: TextEditingController(text: question.prompt),
|
|
|
|
|
|
|
|
explanationController: TextEditingController(text: question.explanation ?? ''),
|
|
|
|
answerControllers: question.answers
|
|
|
|
answerControllers: question.answers
|
|
|
|
.map((answer) => TextEditingController(text: answer))
|
|
|
|
.map((answer) => TextEditingController(text: answer))
|
|
|
|
.toList(),
|
|
|
|
.toList(),
|
|
|
|
@ -499,6 +513,7 @@ class QuestionEditor {
|
|
|
|
factory QuestionEditor.empty() {
|
|
|
|
factory QuestionEditor.empty() {
|
|
|
|
return QuestionEditor(
|
|
|
|
return QuestionEditor(
|
|
|
|
promptController: TextEditingController(),
|
|
|
|
promptController: TextEditingController(),
|
|
|
|
|
|
|
|
explanationController: TextEditingController(),
|
|
|
|
answerControllers: [
|
|
|
|
answerControllers: [
|
|
|
|
TextEditingController(),
|
|
|
|
TextEditingController(),
|
|
|
|
TextEditingController(),
|
|
|
|
TextEditingController(),
|
|
|
|
@ -521,9 +536,11 @@ class QuestionEditor {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Question toQuestion() {
|
|
|
|
Question toQuestion() {
|
|
|
|
|
|
|
|
final explanationText = explanationController.text.trim();
|
|
|
|
return Question(
|
|
|
|
return Question(
|
|
|
|
id: originalId ?? DateTime.now().millisecondsSinceEpoch.toString(),
|
|
|
|
id: originalId ?? DateTime.now().millisecondsSinceEpoch.toString(),
|
|
|
|
prompt: promptController.text.trim(),
|
|
|
|
prompt: promptController.text.trim(),
|
|
|
|
|
|
|
|
explanation: explanationText.isEmpty ? null : explanationText,
|
|
|
|
answers: answerControllers.map((c) => c.text.trim()).toList(),
|
|
|
|
answers: answerControllers.map((c) => c.text.trim()).toList(),
|
|
|
|
correctAnswerIndices: correctAnswerIndices.toList()..sort(),
|
|
|
|
correctAnswerIndices: correctAnswerIndices.toList()..sort(),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
@ -531,6 +548,7 @@ class QuestionEditor {
|
|
|
|
|
|
|
|
|
|
|
|
void dispose() {
|
|
|
|
void dispose() {
|
|
|
|
promptController.dispose();
|
|
|
|
promptController.dispose();
|
|
|
|
|
|
|
|
explanationController.dispose();
|
|
|
|
for (final controller in answerControllers) {
|
|
|
|
for (final controller in answerControllers) {
|
|
|
|
controller.dispose();
|
|
|
|
controller.dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|