flagging and exclude
This commit is contained in:
@@ -24,6 +24,7 @@ class _DeckConfigScreenState extends State<DeckConfigScreen> {
|
||||
late bool _immediateFeedback;
|
||||
late bool _includeKnownInAttempts;
|
||||
late bool _shuffleAnswerOrder;
|
||||
late bool _excludeFlaggedQuestions;
|
||||
bool _timeLimitEnabled = false;
|
||||
String? _lastDeckId;
|
||||
int _configHashCode = 0;
|
||||
@@ -74,6 +75,7 @@ class _DeckConfigScreenState extends State<DeckConfigScreen> {
|
||||
_immediateFeedback = _config!.immediateFeedbackEnabled;
|
||||
_includeKnownInAttempts = _config!.includeKnownInAttempts;
|
||||
_shuffleAnswerOrder = _config!.shuffleAnswerOrder;
|
||||
_excludeFlaggedQuestions = _config!.excludeFlaggedQuestions;
|
||||
|
||||
// Initialize time limit controllers
|
||||
_timeLimitEnabled = _config!.timeLimitSeconds != null;
|
||||
@@ -196,6 +198,7 @@ class _DeckConfigScreenState extends State<DeckConfigScreen> {
|
||||
immediateFeedbackEnabled: _immediateFeedback,
|
||||
includeKnownInAttempts: _includeKnownInAttempts,
|
||||
shuffleAnswerOrder: _shuffleAnswerOrder,
|
||||
excludeFlaggedQuestions: _excludeFlaggedQuestions,
|
||||
timeLimitSeconds: timeLimitSeconds,
|
||||
);
|
||||
|
||||
@@ -416,6 +419,21 @@ class _DeckConfigScreenState extends State<DeckConfigScreen> {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Exclude Flagged Questions Toggle
|
||||
SwitchListTile(
|
||||
title: const Text('Exclude flagged questions'),
|
||||
subtitle: const Text(
|
||||
'Flagged questions are not used in attempts and do not count in progress',
|
||||
),
|
||||
value: _excludeFlaggedQuestions,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_excludeFlaggedQuestions = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Time Limit Section
|
||||
SwitchListTile(
|
||||
title: const Text('Enable Time Limit'),
|
||||
|
||||
@@ -40,6 +40,7 @@ class _DeckImportScreenState extends State<DeckImportScreen> {
|
||||
immediateFeedbackEnabled: configJson['immediateFeedbackEnabled'] as bool? ?? true,
|
||||
includeKnownInAttempts: configJson['includeKnownInAttempts'] as bool? ?? false,
|
||||
shuffleAnswerOrder: configJson['shuffleAnswerOrder'] as bool? ?? true,
|
||||
excludeFlaggedQuestions: configJson['excludeFlaggedQuestions'] as bool? ?? false,
|
||||
);
|
||||
|
||||
// Parse questions
|
||||
@@ -249,6 +250,7 @@ class _DeckImportScreenState extends State<DeckImportScreen> {
|
||||
'immediateFeedbackEnabled': true,
|
||||
'includeKnownInAttempts': false,
|
||||
'shuffleAnswerOrder': true,
|
||||
'excludeFlaggedQuestions': false,
|
||||
},
|
||||
'questions': List.generate(20, (i) {
|
||||
return {
|
||||
@@ -545,6 +547,7 @@ class _DeckImportScreenState extends State<DeckImportScreen> {
|
||||
const Text('• immediateFeedbackEnabled: boolean'),
|
||||
const Text('• includeKnownInAttempts: boolean'),
|
||||
const Text('• shuffleAnswerOrder: boolean'),
|
||||
const Text('• excludeFlaggedQuestions: boolean'),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -59,10 +59,14 @@ class _DeckOverviewScreenState extends State<DeckOverviewScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
if (deckToCheck == null || deckToCheck.questions.isEmpty) {
|
||||
if (deckToCheck == null || deckToCheck.activeQuestionCount == 0) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Cannot start attempt: No questions in deck'),
|
||||
SnackBar(
|
||||
content: Text(
|
||||
deckToCheck != null && deckToCheck.questions.isNotEmpty && deckToCheck.config.excludeFlaggedQuestions
|
||||
? 'Cannot start attempt: All questions are flagged. Unflag some or turn off "Exclude flagged questions" in settings.'
|
||||
: 'Cannot start attempt: No questions in deck',
|
||||
),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
@@ -158,8 +162,8 @@ class _DeckOverviewScreenState extends State<DeckOverviewScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if all questions are known and includeKnownInAttempts is disabled
|
||||
final allKnown = deckToCheck.knownCount == deckToCheck.numberOfQuestions && deckToCheck.numberOfQuestions > 0;
|
||||
// Check if all active questions are known and includeKnownInAttempts is disabled
|
||||
final allKnown = deckToCheck.knownCount == deckToCheck.activeQuestionCount && deckToCheck.activeQuestionCount > 0;
|
||||
final includeKnownDisabled = !deckToCheck.config.includeKnownInAttempts;
|
||||
|
||||
if (allKnown && includeKnownDisabled) {
|
||||
@@ -285,7 +289,7 @@ class _DeckOverviewScreenState extends State<DeckOverviewScreen> {
|
||||
Widget _buildProgressStats(BuildContext context) {
|
||||
if (_deck == null) return const SizedBox.shrink();
|
||||
|
||||
final totalQuestions = _deck!.numberOfQuestions;
|
||||
final totalQuestions = _deck!.activeQuestionCount;
|
||||
final knownCount = _deck!.knownCount;
|
||||
final unknownCount = totalQuestions - knownCount;
|
||||
final unknownPercentage = totalQuestions > 0
|
||||
@@ -484,7 +488,7 @@ class _DeckOverviewScreenState extends State<DeckOverviewScreen> {
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'${_deck!.knownCount} of ${_deck!.numberOfQuestions} questions known',
|
||||
'${_deck!.knownCount} of ${_deck!.activeQuestionCount} questions known',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
@@ -505,7 +509,7 @@ class _DeckOverviewScreenState extends State<DeckOverviewScreen> {
|
||||
children: [
|
||||
_StatItem(
|
||||
label: 'Total',
|
||||
value: '${_deck!.numberOfQuestions}',
|
||||
value: '${_deck!.activeQuestionCount}',
|
||||
icon: Icons.quiz,
|
||||
),
|
||||
_StatItem(
|
||||
@@ -515,7 +519,7 @@ class _DeckOverviewScreenState extends State<DeckOverviewScreen> {
|
||||
),
|
||||
_StatItem(
|
||||
label: 'Practice',
|
||||
value: '${_deck!.numberOfQuestions - _deck!.knownCount}',
|
||||
value: '${_deck!.activeQuestionCount - _deck!.knownCount}',
|
||||
icon: Icons.school,
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user