added sound
This commit is contained in:
@@ -6,6 +6,8 @@ import '../services/deck_repository.dart';
|
||||
import '../services/distractor_generator.dart';
|
||||
import '../widgets/kanji_card.dart';
|
||||
import '../widgets/options_grid.dart';
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
|
||||
import 'settings_screen.dart';
|
||||
|
||||
class _ReadingInfo {
|
||||
@@ -28,6 +30,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
String _status = 'Loading deck...';
|
||||
final DistractorGenerator _dg = DistractorGenerator();
|
||||
final Random _random = Random();
|
||||
final _audioPlayer = AudioPlayer();
|
||||
|
||||
QuizMode _mode = QuizMode.kanjiToEnglish;
|
||||
KanjiItem? _current;
|
||||
@@ -109,14 +112,20 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
|
||||
void _nextQuestion() {
|
||||
_deck.sort((a, b) {
|
||||
final aSrsItem = a.srsItems[_mode.toString()] ?? SrsItem(kanjiId: a.id, quizMode: _mode);
|
||||
final bSrsItem = b.srsItems[_mode.toString()] ?? SrsItem(kanjiId: b.id, quizMode: _mode);
|
||||
final aSrsItem = a.srsItems[_mode.toString()];
|
||||
final bSrsItem = b.srsItems[_mode.toString()];
|
||||
|
||||
final stageComparison = aSrsItem.srsStage.compareTo(bSrsItem.srsStage);
|
||||
if (stageComparison != 0) {
|
||||
return stageComparison;
|
||||
final aStage = aSrsItem?.srsStage ?? 0;
|
||||
final bStage = bSrsItem?.srsStage ?? 0;
|
||||
|
||||
if (aStage != bStage) {
|
||||
return aStage.compareTo(bStage);
|
||||
}
|
||||
return aSrsItem.lastAsked.compareTo(bSrsItem.lastAsked);
|
||||
|
||||
final aLastAsked = aSrsItem?.lastAsked ?? DateTime.fromMillisecondsSinceEpoch(0);
|
||||
final bLastAsked = bSrsItem?.lastAsked ?? DateTime.fromMillisecondsSinceEpoch(0);
|
||||
|
||||
return aLastAsked.compareTo(bLastAsked);
|
||||
});
|
||||
|
||||
_current = _deck.first;
|
||||
@@ -128,16 +137,19 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
switch (_mode) {
|
||||
case QuizMode.kanjiToEnglish:
|
||||
_correctAnswers = [_current!.meanings.first];
|
||||
_options = [_correctAnswers.first, ..._dg.generateMeanings(_current!, _deck, 3)]
|
||||
.map(_toTitleCase)
|
||||
.toList()
|
||||
_options = [
|
||||
_correctAnswers.first,
|
||||
..._dg.generateMeanings(_current!, _deck, 3)
|
||||
].map(_toTitleCase).toList()
|
||||
..shuffle();
|
||||
break;
|
||||
|
||||
case QuizMode.englishToKanji:
|
||||
_correctAnswers = [_current!.characters];
|
||||
_options = [_correctAnswers.first, ..._dg.generateKanji(_current!, _deck, 3)]
|
||||
..shuffle();
|
||||
_options = [
|
||||
_correctAnswers.first,
|
||||
..._dg.generateKanji(_current!, _deck, 3)
|
||||
]..shuffle();
|
||||
break;
|
||||
|
||||
case QuizMode.reading:
|
||||
@@ -149,10 +161,15 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
? _deck.expand((k) => k.onyomi)
|
||||
: _deck.expand((k) => k.kunyomi);
|
||||
|
||||
final distractors =
|
||||
readingsSource.where((r) => !_correctAnswers.contains(r)).toSet().toList()
|
||||
final distractors = readingsSource
|
||||
.where((r) => !_correctAnswers.contains(r))
|
||||
.toSet()
|
||||
.toList()
|
||||
..shuffle();
|
||||
_options = ([_correctAnswers[_random.nextInt(_correctAnswers.length)], ...distractors.take(3)])
|
||||
_options = ([
|
||||
_correctAnswers[_random.nextInt(_correctAnswers.length)],
|
||||
...distractors.take(3)
|
||||
])
|
||||
..shuffle();
|
||||
break;
|
||||
}
|
||||
@@ -176,29 +193,31 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
|
||||
var srsItem = current.srsItems[srsKey];
|
||||
final isNew = srsItem == null;
|
||||
srsItem ??= SrsItem(kanjiId: current.id, quizMode: _mode, readingType: readingType);
|
||||
|
||||
final srsItemForUpdate = srsItem ??=
|
||||
SrsItem(kanjiId: current.id, quizMode: _mode, readingType: readingType);
|
||||
setState(() {
|
||||
_asked += 1;
|
||||
if (isCorrect) {
|
||||
_score += 1;
|
||||
srsItem!.srsStage += 1;
|
||||
_audioPlayer.play(AssetSource('sfx/confirm.mp3'));
|
||||
} else {
|
||||
srsItem!.srsStage = max(0, srsItem.srsStage - 1);
|
||||
srsItemForUpdate.srsStage = max(0, srsItemForUpdate.srsStage - 1);
|
||||
}
|
||||
srsItem.lastAsked = DateTime.now();
|
||||
current.srsItems[srsKey] = srsItem;
|
||||
srsItemForUpdate.lastAsked = DateTime.now();
|
||||
current.srsItems[srsKey] = srsItemForUpdate;
|
||||
});
|
||||
|
||||
if (isNew) {
|
||||
await repo.insertSrsItem(srsItem);
|
||||
await repo.insertSrsItem(srsItemForUpdate);
|
||||
} else {
|
||||
await repo.updateSrsItem(srsItem);
|
||||
await repo.updateSrsItem(srsItemForUpdate);
|
||||
}
|
||||
|
||||
final correctDisplay = (_mode == QuizMode.kanjiToEnglish)
|
||||
? _toTitleCase(_correctAnswers.first)
|
||||
: (_mode == QuizMode.reading ? _correctAnswers.join(', ') : _correctAnswers.first);
|
||||
: (_mode == QuizMode.reading
|
||||
? _correctAnswers.join(', ')
|
||||
: _correctAnswers.first);
|
||||
|
||||
final snack = SnackBar(
|
||||
content: Text(
|
||||
@@ -271,7 +290,6 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
Wrap(
|
||||
spacing: 6,
|
||||
runSpacing: 4,
|
||||
@@ -282,9 +300,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
_buildChoiceChip('Reading', QuizMode.reading),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 18),
|
||||
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Center(
|
||||
@@ -303,9 +319,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
SafeArea(
|
||||
top: false,
|
||||
child: Column(
|
||||
@@ -346,4 +360,4 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
backgroundColor: const Color(0xFF1E1E1E),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,13 @@ import '../services/deck_repository.dart';
|
||||
import '../services/distractor_generator.dart';
|
||||
import '../widgets/kanji_card.dart';
|
||||
import '../widgets/options_grid.dart';
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'settings_screen.dart';
|
||||
|
||||
class VocabScreen extends StatefulWidget {
|
||||
const VocabScreen({super.key});
|
||||
|
||||
@override
|
||||
State<VocabScreen> createState() => _VocabScreenState();
|
||||
}
|
||||
|
||||
@@ -19,7 +21,7 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
bool _loading = false;
|
||||
String _status = 'Loading deck...';
|
||||
final DistractorGenerator _dg = DistractorGenerator();
|
||||
final Random _random = Random();
|
||||
final _audioPlayer = AudioPlayer();
|
||||
|
||||
VocabQuizMode _mode = VocabQuizMode.vocabToEnglish;
|
||||
VocabularyItem? _current;
|
||||
@@ -138,17 +140,19 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
|
||||
final srsKey = _mode.toString();
|
||||
|
||||
var srsItem = current.srsItems[srsKey];
|
||||
final isNew = srsItem == null;
|
||||
srsItem ??= VocabSrsItem(vocabId: current.id, quizMode: _mode);
|
||||
var srsItemNullable = current.srsItems[srsKey];
|
||||
final isNew = srsItemNullable == null;
|
||||
final srsItem =
|
||||
srsItemNullable ?? VocabSrsItem(vocabId: current.id, quizMode: _mode);
|
||||
|
||||
setState(() {
|
||||
_asked += 1;
|
||||
if (isCorrect) {
|
||||
_score += 1;
|
||||
srsItem!.srsStage += 1;
|
||||
_audioPlayer.play(AssetSource('sfx/confirm.mp3'));
|
||||
srsItem.srsStage += 1;
|
||||
} else {
|
||||
srsItem!.srsStage = max(0, srsItem.srsStage - 1);
|
||||
srsItem.srsStage = max(0, srsItem.srsStage - 1);
|
||||
}
|
||||
srsItem.lastAsked = DateTime.now();
|
||||
current.srsItems[srsKey] = srsItem;
|
||||
|
||||
Reference in New Issue
Block a user