custom_srs #5

Merged
Crylia merged 3 commits from custom_srs into master 2025-10-30 17:42:48 +01:00
2 changed files with 87 additions and 35 deletions
Showing only changes of commit d8a5c27fb3 - Show all commits

View File

@@ -530,13 +530,21 @@ class _BrowseScreenState extends State<BrowseScreen> with SingleTickerProviderSt
onPressed: _deleteSelected,
),
IconButton(
icon: const Icon(Icons.timer_off),
icon: Icon(_toggleIntervalIcon),
onPressed: _toggleIntervalForSelected,
),
],
);
}
IconData get _toggleIntervalIcon {
if (_selectedItems.isEmpty) {
return Icons.timer_off;
}
final bool willEnable = _selectedItems.any((item) => !item.useInterval);
return willEnable ? Icons.timer : Icons.timer_off;
}
void _selectAll() {
setState(() {
if (_selectedItems.length == _customDeck.length) {
@@ -577,23 +585,40 @@ class _BrowseScreenState extends State<BrowseScreen> with SingleTickerProviderSt
);
}
void _toggleIntervalForSelected() {
Future<void> _toggleIntervalForSelected() async {
if (_selectedItems.isEmpty) {
return;
}
final bool targetState = _selectedItems.any((item) => !item.useInterval);
final selectedCharacters = _selectedItems.map((item) => item.characters).toSet();
final List<CustomKanjiItem> updatedItems = [];
for (final item in _selectedItems) {
final updatedItem = CustomKanjiItem(
characters: item.characters,
meaning: item.meaning,
kanji: item.kanji,
useInterval: !item.useInterval,
useInterval: targetState,
srsLevel: item.srsLevel,
nextReview: item.nextReview,
);
_customDeckRepository.updateCard(updatedItem);
updatedItems.add(updatedItem);
}
await _customDeckRepository.updateCards(updatedItems);
await _loadCustomDeck();
final newSelectedItems = _customDeck
.where((item) => selectedCharacters.contains(item.characters))
.toList();
setState(() {
_isSelectionMode = false;
_selectedItems.clear();
_selectedItems = newSelectedItems;
if (_selectedItems.isEmpty) {
_isSelectionMode = false;
}
});
_loadCustomDeck();
}
Widget _buildCustomGridView(List<CustomKanjiItem> items) {
@@ -639,35 +664,53 @@ class _BrowseScreenState extends State<BrowseScreen> with SingleTickerProviderSt
}
},
child: Card(
shape: RoundedRectangleBorder(
side: isSelected
? const BorderSide(color: Colors.blue, width: 2.0)
: BorderSide.none,
borderRadius: BorderRadius.circular(12.0),
),
color: isSelected
? Colors.blue.withOpacity(0.5)
: item.useInterval
? Color.lerp(const Color(0xFF1E1E1E), Colors.blue, 0.1)
: const Color(0xFF1E1E1E),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FittedBox(
fit: BoxFit.scaleDown,
child: Text(
item.kanji ?? item.characters,
style: const TextStyle(fontSize: 32, color: Colors.white),
textAlign: TextAlign.center,
: const Color(0xFF1E1E1E),
child: Stack(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FittedBox(
fit: BoxFit.scaleDown,
child: Text(
item.kanji ?? item.characters,
style: const TextStyle(fontSize: 32, color: Colors.white),
textAlign: TextAlign.center,
),
),
const SizedBox(height: 8),
Text(
item.meaning,
style: const TextStyle(color: Colors.grey, fontSize: 16),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 8),
_buildSrsIndicator(item.srsLevel),
],
),
),
if (item.useInterval)
Positioned(
top: 4,
right: 4,
child: Icon(
Icons.timer,
color: Colors.green,
size: 16,
),
),
const SizedBox(height: 8),
Text(
item.meaning,
style: const TextStyle(color: Colors.grey, fontSize: 16),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 8),
_buildSrsIndicator(item.srsLevel),
],
),
],
),
),
);
@@ -675,6 +718,4 @@ class _BrowseScreenState extends State<BrowseScreen> with SingleTickerProviderSt
padding: const EdgeInsets.all(8),
);
}
}
}

View File

@@ -31,6 +31,17 @@ class CustomDeckRepository {
}
}
Future<void> updateCards(List<CustomKanjiItem> itemsToUpdate) async {
final deck = await getCustomDeck();
for (var item in itemsToUpdate) {
final index = deck.indexWhere((element) => element.characters == item.characters);
if (index != -1) {
deck[index] = item;
}
}
await saveDeck(deck);
}
Future<void> deleteCard(CustomKanjiItem item) async {
final deck = await getCustomDeck();
deck.removeWhere((element) => element.characters == item.characters);