add custom srs
This commit is contained in:
@@ -18,14 +18,14 @@ class VocabScreen extends StatefulWidget {
|
||||
State<VocabScreen> createState() => _VocabScreenState();
|
||||
}
|
||||
|
||||
class _VocabScreenState extends State<VocabScreen> {
|
||||
class _VocabScreenState extends State<VocabScreen> with SingleTickerProviderStateMixin {
|
||||
late TabController _tabController;
|
||||
List<VocabularyItem> _deck = [];
|
||||
bool _loading = false;
|
||||
String _status = 'Loading deck...';
|
||||
final DistractorGenerator _dg = DistractorGenerator();
|
||||
final _audioPlayer = AudioPlayer();
|
||||
|
||||
VocabQuizMode _mode = VocabQuizMode.vocabToEnglish;
|
||||
VocabularyItem? _current;
|
||||
List<String> _options = [];
|
||||
List<String> _correctAnswers = [];
|
||||
@@ -33,14 +33,26 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
int _asked = 0;
|
||||
bool _playAudio = true;
|
||||
bool _playCorrectSound = true;
|
||||
bool _apiKeyMissing = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tabController = TabController(length: 3, vsync: this);
|
||||
_tabController.addListener(() {
|
||||
setState(() {});
|
||||
_nextQuestion();
|
||||
});
|
||||
_loadSettings();
|
||||
_loadDeck();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_tabController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _loadSettings() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
setState(() {
|
||||
@@ -61,11 +73,10 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
final apiKey = repo.apiKey;
|
||||
|
||||
if (apiKey == null || apiKey.isEmpty) {
|
||||
if (mounted) {
|
||||
Navigator.of(context).pushReplacement(
|
||||
MaterialPageRoute(builder: (_) => const SettingsScreen()),
|
||||
);
|
||||
}
|
||||
setState(() {
|
||||
_apiKeyMissing = true;
|
||||
_loading = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -82,6 +93,7 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
_deck = items;
|
||||
_status = 'Loaded ${items.length} vocabulary';
|
||||
_loading = false;
|
||||
_apiKeyMissing = false;
|
||||
});
|
||||
|
||||
_nextQuestion();
|
||||
@@ -101,6 +113,19 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
VocabQuizMode get _mode {
|
||||
switch (_tabController.index) {
|
||||
case 0:
|
||||
return VocabQuizMode.vocabToEnglish;
|
||||
case 1:
|
||||
return VocabQuizMode.englishToVocab;
|
||||
case 2:
|
||||
return VocabQuizMode.audioToEnglish;
|
||||
default:
|
||||
return VocabQuizMode.vocabToEnglish;
|
||||
}
|
||||
}
|
||||
|
||||
void _nextQuestion() {
|
||||
if (_deck.isEmpty) return;
|
||||
|
||||
@@ -257,6 +282,30 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_apiKeyMissing) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Vocabulary Quiz')),
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text('WaniKani API key is not set.', style: TextStyle(color: Colors.white)),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (_) => const SettingsScreen()),
|
||||
);
|
||||
_loadDeck();
|
||||
},
|
||||
child: const Text('Go to Settings'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget promptWidget;
|
||||
|
||||
if (_current == null) {
|
||||
@@ -283,24 +332,18 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFF121212),
|
||||
appBar: AppBar(
|
||||
title: const Text('Hirameki SRS - Vocab'),
|
||||
backgroundColor: const Color(0xFF1F1F1F),
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 2,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.settings),
|
||||
onPressed: () async {
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (_) => const SettingsScreen()),
|
||||
);
|
||||
_loadSettings();
|
||||
},
|
||||
)
|
||||
],
|
||||
title: const Text('Vocabulary Quiz'),
|
||||
bottom: TabBar(
|
||||
controller: _tabController,
|
||||
tabs: const [
|
||||
Tab(text: 'Vocab→English'),
|
||||
Tab(text: 'English→Vocab'),
|
||||
Tab(text: 'Listening'),
|
||||
],
|
||||
),
|
||||
),
|
||||
backgroundColor: const Color(0xFF121212),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
@@ -317,17 +360,6 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
const CircularProgressIndicator(color: Colors.blueAccent),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Wrap(
|
||||
spacing: 6,
|
||||
runSpacing: 4,
|
||||
alignment: WrapAlignment.center,
|
||||
children: [
|
||||
_buildChoiceChip('Vocab→English', VocabQuizMode.vocabToEnglish),
|
||||
_buildChoiceChip('English→Vocab', VocabQuizMode.englishToVocab),
|
||||
_buildChoiceChip('Listening', VocabQuizMode.audioToEnglish),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 18),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
@@ -370,23 +402,5 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
ChoiceChip _buildChoiceChip(String label, VocabQuizMode mode) {
|
||||
final selected = _mode == mode;
|
||||
return ChoiceChip(
|
||||
label: Text(
|
||||
label,
|
||||
style: TextStyle(color: selected ? Colors.white : Colors.grey[400]),
|
||||
),
|
||||
selected: selected,
|
||||
onSelected: (v) {
|
||||
setState(() => _mode = mode);
|
||||
_nextQuestion();
|
||||
},
|
||||
selectedColor: Colors.blueAccent,
|
||||
backgroundColor: const Color(0xFF1E1E1E),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user