themes
This commit is contained in:
@@ -39,7 +39,8 @@ class HomeScreen extends StatefulWidget {
|
||||
State<HomeScreen> createState() => _HomeScreenState();
|
||||
}
|
||||
|
||||
class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateMixin {
|
||||
class _HomeScreenState extends State<HomeScreen>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late TabController _tabController;
|
||||
List<KanjiItem> _deck = [];
|
||||
bool _loading = false;
|
||||
@@ -171,8 +172,10 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
_deck.sort((a, b) {
|
||||
int getSrsStage(KanjiItem item) {
|
||||
if (mode == QuizMode.reading) {
|
||||
final onyomiStage = item.srsItems['${QuizMode.reading}onyomi']?.srsStage;
|
||||
final kunyomiStage = item.srsItems['${QuizMode.reading}kunyomi']?.srsStage;
|
||||
final onyomiStage =
|
||||
item.srsItems['${QuizMode.reading}onyomi']?.srsStage;
|
||||
final kunyomiStage =
|
||||
item.srsItems['${QuizMode.reading}kunyomi']?.srsStage;
|
||||
|
||||
if (onyomiStage != null && kunyomiStage != null) {
|
||||
return min(onyomiStage, kunyomiStage);
|
||||
@@ -184,8 +187,10 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
|
||||
DateTime getLastAsked(KanjiItem item) {
|
||||
if (mode == QuizMode.reading) {
|
||||
final onyomiLastAsked = item.srsItems['${QuizMode.reading}onyomi']?.lastAsked;
|
||||
final kunyomiLastAsked = item.srsItems['${QuizMode.reading}kunyomi']?.lastAsked;
|
||||
final onyomiLastAsked =
|
||||
item.srsItems['${QuizMode.reading}onyomi']?.lastAsked;
|
||||
final kunyomiLastAsked =
|
||||
item.srsItems['${QuizMode.reading}kunyomi']?.lastAsked;
|
||||
|
||||
if (onyomiLastAsked != null && kunyomiLastAsked != null) {
|
||||
return onyomiLastAsked.isBefore(kunyomiLastAsked)
|
||||
@@ -227,16 +232,15 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
quizState.correctAnswers = [quizState.current!.meanings.first];
|
||||
quizState.options = [
|
||||
quizState.correctAnswers.first,
|
||||
..._dg.generateMeanings(quizState.current!, _deck, 3)
|
||||
].map(_toTitleCase).toList()
|
||||
..shuffle();
|
||||
..._dg.generateMeanings(quizState.current!, _deck, 3),
|
||||
].map(_toTitleCase).toList()..shuffle();
|
||||
break;
|
||||
|
||||
case QuizMode.englishToKanji:
|
||||
quizState.correctAnswers = [quizState.current!.characters];
|
||||
quizState.options = [
|
||||
quizState.correctAnswers.first,
|
||||
..._dg.generateKanji(quizState.current!, _deck, 3)
|
||||
..._dg.generateKanji(quizState.current!, _deck, 3),
|
||||
]..shuffle();
|
||||
break;
|
||||
|
||||
@@ -249,16 +253,18 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
? _deck.expand((k) => k.onyomi)
|
||||
: _deck.expand((k) => k.kunyomi);
|
||||
|
||||
final distractors = readingsSource
|
||||
.where((r) => !quizState.correctAnswers.contains(r))
|
||||
.toSet()
|
||||
.toList()
|
||||
final distractors =
|
||||
readingsSource
|
||||
.where((r) => !quizState.correctAnswers.contains(r))
|
||||
.toSet()
|
||||
.toList()
|
||||
..shuffle();
|
||||
quizState.options = ([
|
||||
quizState.correctAnswers[_random.nextInt(quizState.correctAnswers.length)],
|
||||
...distractors.take(3)
|
||||
])
|
||||
..shuffle();
|
||||
quizState.correctAnswers[_random.nextInt(
|
||||
quizState.correctAnswers.length,
|
||||
)],
|
||||
...distractors.take(3),
|
||||
])..shuffle();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -279,26 +285,29 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
|
||||
String readingType = '';
|
||||
if (mode == QuizMode.reading) {
|
||||
readingType = quizState.readingHint.contains("on'yomi") ? 'onyomi' : 'kunyomi';
|
||||
readingType = quizState.readingHint.contains("on'yomi")
|
||||
? 'onyomi'
|
||||
: 'kunyomi';
|
||||
}
|
||||
final srsKey = mode.toString() + readingType;
|
||||
|
||||
var srsItem = current.srsItems[srsKey];
|
||||
final isNew = srsItem == null;
|
||||
final srsItemForUpdate = srsItem ??=
|
||||
SrsItem(kanjiId: current.id, quizMode: mode, readingType: readingType);
|
||||
|
||||
quizState.asked += 1;
|
||||
|
||||
quizState.selectedOption = option;
|
||||
|
||||
quizState.showResult = true;
|
||||
|
||||
setState(() {}); // Trigger UI rebuild to show selected/correct colors
|
||||
|
||||
|
||||
|
||||
if (isCorrect) {
|
||||
final srsItemForUpdate = srsItem ??= SrsItem(
|
||||
kanjiId: current.id,
|
||||
quizMode: mode,
|
||||
readingType: readingType,
|
||||
);
|
||||
|
||||
quizState.asked += 1;
|
||||
|
||||
quizState.selectedOption = option;
|
||||
|
||||
quizState.showResult = true;
|
||||
|
||||
setState(() {});
|
||||
|
||||
if (isCorrect) {
|
||||
quizState.score += 1;
|
||||
srsItemForUpdate.srsStage += 1;
|
||||
if (_playCorrectSound) {
|
||||
@@ -310,6 +319,9 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
srsItemForUpdate.lastAsked = DateTime.now();
|
||||
current.srsItems[srsKey] = srsItemForUpdate;
|
||||
|
||||
final scaffoldMessenger = ScaffoldMessenger.of(context);
|
||||
final theme = Theme.of(context);
|
||||
|
||||
if (isNew) {
|
||||
await repo.insertSrsItem(srsItemForUpdate);
|
||||
} else {
|
||||
@@ -319,26 +331,28 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
final correctDisplay = (mode == QuizMode.kanjiToEnglish)
|
||||
? _toTitleCase(quizState.correctAnswers.first)
|
||||
: (mode == QuizMode.reading
|
||||
? quizState.correctAnswers.join(', ')
|
||||
: quizState.correctAnswers.first);
|
||||
? quizState.correctAnswers.join(', ')
|
||||
: quizState.correctAnswers.first);
|
||||
|
||||
final snack = SnackBar(
|
||||
content: Text(
|
||||
isCorrect ? 'Correct!' : 'Wrong — correct: $correctDisplay',
|
||||
style: TextStyle(
|
||||
color: isCorrect ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.error,
|
||||
color: isCorrect
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.error,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
backgroundColor: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||
backgroundColor: theme.colorScheme.surfaceContainerHighest,
|
||||
duration: const Duration(milliseconds: 900),
|
||||
);
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(snack);
|
||||
scaffoldMessenger.showSnackBar(snack);
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_isAnswering = true; // Disable input after showing result
|
||||
_isAnswering = true;
|
||||
});
|
||||
|
||||
Future.delayed(const Duration(milliseconds: 900), () {
|
||||
@@ -357,7 +371,12 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text('WaniKani API key is not set.', style: TextStyle(color: Theme.of(context).colorScheme.onSurface)),
|
||||
Text(
|
||||
'WaniKani API key is not set.',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
@@ -389,11 +408,7 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
body: TabBarView(
|
||||
controller: _tabController,
|
||||
children: [
|
||||
_buildQuizPage(0),
|
||||
_buildQuizPage(1),
|
||||
_buildQuizPage(2),
|
||||
],
|
||||
children: [_buildQuizPage(0), _buildQuizPage(1), _buildQuizPage(2)],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -430,11 +445,15 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
Expanded(
|
||||
child: Text(
|
||||
_status,
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.onSurface),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_loading)
|
||||
CircularProgressIndicator(color: Theme.of(context).colorScheme.primary),
|
||||
CircularProgressIndicator(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 18),
|
||||
@@ -472,7 +491,9 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Score: ${quizState.score} / ${quizState.asked}',
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.onSurface),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -481,4 +502,4 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user