flag and end of attempt
This commit is contained in:
@@ -3,6 +3,7 @@ import 'package:practice_engine/practice_engine.dart';
|
||||
import '../routes.dart';
|
||||
import '../widgets/status_chip.dart';
|
||||
import '../services/deck_storage.dart';
|
||||
import '../utils/top_snackbar.dart';
|
||||
|
||||
class AttemptResultScreen extends StatefulWidget {
|
||||
const AttemptResultScreen({super.key});
|
||||
@@ -82,6 +83,42 @@ class _AttemptResultScreenState extends State<AttemptResultScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
Question? _currentQuestionInDeck(String questionId) {
|
||||
if (_deck == null) return null;
|
||||
try {
|
||||
return _deck!.questions.firstWhere((q) => q.id == questionId);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void _toggleFlag(String questionId) {
|
||||
if (_deck == null) return;
|
||||
setState(() {
|
||||
_deck = DeckService.toggleQuestionFlag(deck: _deck!, questionId: questionId);
|
||||
});
|
||||
_deckStorage.saveDeckSync(_deck!);
|
||||
final q = _currentQuestionInDeck(questionId);
|
||||
showTopSnackBar(
|
||||
context,
|
||||
q?.isFlagged == true ? 'Question flagged for review' : 'Question unflagged',
|
||||
backgroundColor: q?.isFlagged == true ? Colors.orange : null,
|
||||
);
|
||||
}
|
||||
|
||||
void _markNeedsPractice(String questionId) {
|
||||
if (_deck == null) return;
|
||||
setState(() {
|
||||
_deck = DeckService.markQuestionAsNeedsPractice(deck: _deck!, questionId: questionId);
|
||||
});
|
||||
_deckStorage.saveDeckSync(_deck!);
|
||||
showTopSnackBar(
|
||||
context,
|
||||
'Marked as needs practice',
|
||||
backgroundColor: Colors.blue,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_deck == null || _result == null) {
|
||||
@@ -217,6 +254,8 @@ class _AttemptResultScreenState extends State<AttemptResultScreen> {
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
..._result!.incorrectQuestions.map((answerResult) {
|
||||
final currentQ = _currentQuestionInDeck(answerResult.question.id);
|
||||
final isFlagged = currentQ?.isFlagged ?? false;
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
child: Padding(
|
||||
@@ -233,23 +272,42 @@ class _AttemptResultScreenState extends State<AttemptResultScreen> {
|
||||
children: [
|
||||
StatusChip(statusChange: answerResult.statusChange),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'Your answer${answerResult.userAnswerIndices.length > 1 ? 's' : ''}: ${answerResult.userAnswerIndices.map((idx) => answerResult.question.answers[idx]).join(', ')}',
|
||||
style: TextStyle(
|
||||
color: Colors.red,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Your answer${answerResult.userAnswerIndices.length > 1 ? 's' : ''}: ${answerResult.userAnswerIndices.map((idx) => answerResult.question.answers[idx]).join(', ')}',
|
||||
'Correct answer${answerResult.question.correctIndices.length > 1 ? 's' : ''}: ${answerResult.question.correctIndices.map((idx) => answerResult.question.answers[idx]).join(', ')}',
|
||||
style: TextStyle(
|
||||
color: Colors.red,
|
||||
color: Colors.green,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Correct answer${answerResult.question.correctIndices.length > 1 ? 's' : ''}: ${answerResult.question.correctIndices.map((idx) => answerResult.question.answers[idx]).join(', ')}',
|
||||
style: TextStyle(
|
||||
color: Colors.green,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton.icon(
|
||||
onPressed: () => _markNeedsPractice(answerResult.question.id),
|
||||
icon: const Icon(Icons.replay, size: 20),
|
||||
label: const Text('Needs practice'),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => _toggleFlag(answerResult.question.id),
|
||||
icon: Icon(
|
||||
isFlagged ? Icons.flag : Icons.outlined_flag,
|
||||
color: isFlagged ? Colors.red : null,
|
||||
),
|
||||
tooltip: isFlagged ? 'Unflag' : 'Flag for review',
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -265,6 +323,8 @@ class _AttemptResultScreenState extends State<AttemptResultScreen> {
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
..._result!.allResults.map((answerResult) {
|
||||
final currentQ = _currentQuestionInDeck(answerResult.question.id);
|
||||
final isFlagged = currentQ?.isFlagged ?? false;
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
child: ListTile(
|
||||
@@ -274,7 +334,26 @@ class _AttemptResultScreenState extends State<AttemptResultScreen> {
|
||||
? 'Correct'
|
||||
: 'Incorrect - Selected: ${answerResult.userAnswerIndices.map((idx) => answerResult.question.answers[idx]).join(', ')}',
|
||||
),
|
||||
trailing: StatusChip(statusChange: answerResult.statusChange),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
StatusChip(statusChange: answerResult.statusChange),
|
||||
IconButton(
|
||||
onPressed: () => _markNeedsPractice(answerResult.question.id),
|
||||
icon: const Icon(Icons.replay, size: 22),
|
||||
tooltip: 'Mark as needs practice',
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => _toggleFlag(answerResult.question.id),
|
||||
icon: Icon(
|
||||
isFlagged ? Icons.flag : Icons.outlined_flag,
|
||||
color: isFlagged ? Colors.red : null,
|
||||
size: 22,
|
||||
),
|
||||
tooltip: isFlagged ? 'Unflag' : 'Flag for review',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user