custom_srs #5
@@ -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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user