V1.0.0
This commit is contained in:
+314
-131
@@ -5,6 +5,7 @@ import 'package:intl/intl.dart'; // For DateFormat
|
||||
import 'package:path_provider/path_provider.dart'; // For getApplicationDocumentsDirectory
|
||||
import 'target_view.dart'; // Import the TargetViewScreen
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../utils/translations.dart';
|
||||
|
||||
class BookScreen extends StatefulWidget {
|
||||
const BookScreen({super.key});
|
||||
@@ -17,21 +18,34 @@ class _BookScreenState extends State<BookScreen> with WidgetsBindingObserver {
|
||||
Map<String, List<File>> _groupedFiles = {}; // Files grouped by folder
|
||||
Map<String, DateTime> _folderCreationDates = {}; // Folder creation dates
|
||||
Map<String, int> _folderScores = {}; // Folder scores (sum of scores of all target files inside)
|
||||
String? _expandedFolder;
|
||||
Color _bulletColor = Colors.blue; // default fallback
|
||||
Map<String, bool> _folderTypes = {}; // true = tournament, false = training
|
||||
String _folderFilter = 'all';
|
||||
bool isRenameEnabled = false;
|
||||
String _sortMode = 'date'; // or 'score'
|
||||
String _selectedLanguage = 'English';
|
||||
String? _expandedFolder; // Track which folder is expanded
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this); // Register to listen for lifecycle events
|
||||
_loadBulletColor();
|
||||
_loadLanguage();
|
||||
_loadTargetDataFiles(); // Initial load when the screen is first created
|
||||
}
|
||||
|
||||
String _t(String key) {
|
||||
return AppTranslations.translate(key, _selectedLanguage);
|
||||
}
|
||||
|
||||
Future<void> _loadLanguage() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
setState(() {
|
||||
_selectedLanguage = prefs.getString('language') ?? 'English';
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this); // Unregister from lifecycle events when disposed
|
||||
@@ -192,7 +206,7 @@ Color _getColorFromName(String colorName) {
|
||||
Future<void> _deleteFile(File file) async {
|
||||
bool? confirmDeletion = await _showConfirmationDialog(
|
||||
context,
|
||||
'Are you sure you want to delete this file?',
|
||||
_t('Are you sure you want to delete this file?'),
|
||||
);
|
||||
|
||||
if (confirmDeletion == true) {
|
||||
@@ -309,9 +323,9 @@ Future<void> _renameFolder(String oldFolderName) async {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
'Folder Settings',
|
||||
style: TextStyle(
|
||||
Text(
|
||||
_t('Folder Settings'),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -325,7 +339,7 @@ Future<void> _renameFolder(String oldFolderName) async {
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Colors.grey[800],
|
||||
hintText: 'Enter new folder name',
|
||||
hintText: _t('Enter new folder name'),
|
||||
hintStyle: const TextStyle(color: Colors.white54),
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
@@ -363,7 +377,7 @@ Future<void> _renameFolder(String oldFolderName) async {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
child: Center(
|
||||
child: Text(
|
||||
isTournament ? 'Tournament Mode 🏆' : 'Mark as Tournament 🏆',
|
||||
isTournament ? _t('Tournament Mode 🏆') : _t('Mark as Tournament 🏆'),
|
||||
style: TextStyle(
|
||||
color: isTournament ? _bulletColor : Colors.white70,
|
||||
fontWeight: FontWeight.w500,
|
||||
@@ -387,7 +401,7 @@ Future<void> _renameFolder(String oldFolderName) async {
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: const Text('Cancel'),
|
||||
child: Text(_t('Cancel')),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@@ -405,7 +419,7 @@ Future<void> _renameFolder(String oldFolderName) async {
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: const Text('Apply'),
|
||||
child: Text(_t('Apply')),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -471,7 +485,7 @@ Future<void> _renameFolder(String oldFolderName) async {
|
||||
Future<void> _deleteFolder(String folderName) async {
|
||||
bool? confirmDeletion = await _showConfirmationDialog(
|
||||
context,
|
||||
'Are you sure you want to delete the folder "$folderName" and all of its contents?',
|
||||
'${_t('Are you sure you want to delete the folder')} "$folderName" ${_t('and all of its contents?')}',
|
||||
);
|
||||
|
||||
if (confirmDeletion == true) {
|
||||
@@ -485,12 +499,6 @@ Future<void> _renameFolder(String oldFolderName) async {
|
||||
|
||||
_loadTargetDataFiles(); // Refresh file/folder list
|
||||
|
||||
if (_expandedFolder == folderName) {
|
||||
setState(() {
|
||||
_expandedFolder = null;
|
||||
});
|
||||
}
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Folder "$folderName" deleted successfully.'),
|
||||
@@ -517,9 +525,9 @@ Future<void> _renameFolder(String oldFolderName) async {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
'Confirm Deletion',
|
||||
style: TextStyle(
|
||||
Text(
|
||||
_t('Confirm Deletion'),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -547,7 +555,7 @@ Future<void> _renameFolder(String oldFolderName) async {
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: const Text("Yes, delete"),
|
||||
child: Text(_t("Yes, delete")),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -565,7 +573,7 @@ Future<void> _renameFolder(String oldFolderName) async {
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
child: Text(_t("Cancel")),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -582,125 +590,292 @@ Widget _buildFolderRow(String folderName) {
|
||||
final totalScore = _folderScores[folderName];
|
||||
final folderDate = _folderCreationDates[folderName];
|
||||
final formattedDate = folderDate != null
|
||||
? DateFormat('yyyy-MM-dd').format(folderDate)
|
||||
? DateFormat('dd/MM/yyyy').format(folderDate)
|
||||
: 'Unknown Date';
|
||||
|
||||
final isExpanded = _expandedFolder == folderName;
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
|
||||
margin: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: isExpanded ? _bulletColor.withOpacity(0.15) : Colors.grey[300],
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: isExpanded ? _bulletColor : Colors.transparent,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ListTile(
|
||||
dense: true, // Compact layout
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text(
|
||||
_folderTypes[folderName] == true
|
||||
? '🏆 $folderName'
|
||||
: folderName,
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
||||
),
|
||||
subtitle: Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
child: Text(
|
||||
"📝 $numberOfTargets / 🎯 $totalScore / 📅 $formattedDate",
|
||||
style: const TextStyle(fontSize: 13, color: Colors.black87),
|
||||
// Header section: Name and Date
|
||||
InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_expandedFolder = _expandedFolder == folderName ? null : folderName;
|
||||
});
|
||||
},
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(12),
|
||||
topRight: Radius.circular(12),
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
// Small colored indicator
|
||||
Container(
|
||||
width: 4,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
color: _bulletColor,
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
_folderTypes[folderName] == true
|
||||
? '🏆 $folderName'
|
||||
: folderName,
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
"📅 $formattedDate",
|
||||
style: const TextStyle(fontSize: 13, color: Colors.black87),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Icon(
|
||||
_expandedFolder == folderName ? Icons.expand_less : Icons.expand_more,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
),
|
||||
// Expandable targets list (in the middle)
|
||||
if (_expandedFolder == folderName) ...[
|
||||
Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
),
|
||||
child: _buildTargetsList(folderName),
|
||||
),
|
||||
],
|
||||
// Bottom section: Info badge and action buttons
|
||||
IntrinsicHeight(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
IconButton(
|
||||
iconSize: 22,
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: Icon(Icons.my_location, color: _bulletColor),
|
||||
onPressed: () => _openFolderTargetView(folderName),
|
||||
// Info badge section (non-clickable, matches button style)
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[200],
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: const Radius.circular(12),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
// Targets count
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.filter_center_focus, size: 16, color: Colors.black87),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
"$numberOfTargets",
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.black87),
|
||||
),
|
||||
],
|
||||
),
|
||||
// Score
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.emoji_events, size: 16, color: Colors.amber),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
"$totalScore",
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.black87),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
iconSize: 22,
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: Icon(Icons.edit, color: _bulletColor),
|
||||
onPressed: () => _renameFolder(folderName),
|
||||
// Preview button section
|
||||
InkWell(
|
||||
onTap: () => _openFolderTargetView(folderName),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: _bulletColor.withValues(alpha: 0.2),
|
||||
border: Border(
|
||||
left: BorderSide(color: Colors.grey[400]!, width: 1),
|
||||
),
|
||||
),
|
||||
child: Icon(Icons.visibility, color: _bulletColor, size: 20),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
iconSize: 22,
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: const Icon(Icons.delete, color: Colors.red),
|
||||
onPressed: () => _deleteFolder(folderName),
|
||||
// Edit button section
|
||||
InkWell(
|
||||
onTap: () => _renameFolder(folderName),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: _bulletColor.withValues(alpha: 0.2),
|
||||
border: Border(
|
||||
left: BorderSide(color: Colors.grey[400]!, width: 1),
|
||||
),
|
||||
),
|
||||
child: Icon(Icons.edit, color: _bulletColor, size: 20),
|
||||
),
|
||||
),
|
||||
// Delete button section
|
||||
InkWell(
|
||||
onTap: () => _deleteFolder(folderName),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red.withValues(alpha: 0.2),
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomRight: Radius.circular(12),
|
||||
),
|
||||
border: Border(
|
||||
left: BorderSide(color: Colors.grey[400]!, width: 1),
|
||||
),
|
||||
),
|
||||
child: const Icon(Icons.delete, color: Colors.red, size: 20),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_expandedFolder = isExpanded ? null : folderName;
|
||||
});
|
||||
},
|
||||
),
|
||||
if (isExpanded)
|
||||
..._groupedFiles[folderName]!
|
||||
.asMap()
|
||||
.entries
|
||||
.map((entry) => _buildFileRow(entry.value, folderName, entry.key))
|
||||
.toList(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Build the row for files in the folder with everything in a single row
|
||||
Widget _buildFileRow(File file, String folderName, int index) {
|
||||
final fileName = "Target ${index + 1}"; // Use number starting from 1
|
||||
final folderDate = _folderCreationDates[folderName];
|
||||
final formattedDate = folderDate != null
|
||||
? DateFormat('yyyy-MM-dd').format(folderDate)
|
||||
: 'Unknown Date'; // or any default fallback string
|
||||
Widget _buildTargetsList(String folderName) {
|
||||
final targetFiles = _groupedFiles[folderName] ?? [];
|
||||
|
||||
final score = _getScoreFromJson(jsonDecode(file.readAsStringSync())); // Read the score for the file
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), // Reduced vertical padding for compact height
|
||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), // Tight margin
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[200], // Light grey background for files
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: Colors.grey[300]!, width: 1), // Light border around the file
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () => _openFilePreview(file), // Open the file preview when the row is tapped
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, // Distribute space across the row
|
||||
children: [
|
||||
// File name
|
||||
Text(fileName, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
|
||||
|
||||
// Date
|
||||
Text(formattedDate, style: const TextStyle(fontSize: 12, color: Colors.black54)),
|
||||
|
||||
// Target emoji and score
|
||||
Text("🎯 $score", style: const TextStyle(fontSize: 14, color: Colors.black54)),
|
||||
|
||||
// Delete button
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete, color: Color.fromARGB(255, 252, 102, 92)),
|
||||
onPressed: () => _deleteFile(file), // Trigger file deletion
|
||||
),
|
||||
],
|
||||
if (targetFiles.isEmpty) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
_t("No targets in this folder"),
|
||||
style: const TextStyle(color: Colors.black54, fontSize: 14),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: targetFiles.asMap().entries.map((entry) {
|
||||
final index = entry.key;
|
||||
final file = entry.value;
|
||||
final score = _getScoreFromJson(jsonDecode(file.readAsStringSync()));
|
||||
final fileName = "${_t('Target')} ${index + 1}";
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(color: Colors.grey[300]!, width: 1),
|
||||
),
|
||||
child: IntrinsicHeight(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Target info section
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
fileName,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(
|
||||
Icons.emoji_events,
|
||||
color: Colors.amber,
|
||||
size: 14,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
"$score",
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// Preview button
|
||||
InkWell(
|
||||
onTap: () => _openFilePreview(file),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: _bulletColor.withValues(alpha: 0.15),
|
||||
border: Border(
|
||||
left: BorderSide(color: Colors.grey[300]!, width: 1),
|
||||
),
|
||||
),
|
||||
child: Icon(Icons.visibility, color: _bulletColor, size: 18),
|
||||
),
|
||||
),
|
||||
// Delete button
|
||||
InkWell(
|
||||
onTap: () => _deleteFile(file),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red.withValues(alpha: 0.1),
|
||||
border: Border(
|
||||
left: BorderSide(color: Colors.grey[300]!, width: 1),
|
||||
),
|
||||
borderRadius: const BorderRadius.only(
|
||||
topRight: Radius.circular(10),
|
||||
bottomRight: Radius.circular(10),
|
||||
),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.delete,
|
||||
color: Colors.red,
|
||||
size: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -723,10 +898,10 @@ Widget build(BuildContext context) {
|
||||
children: [
|
||||
Text(
|
||||
_folderFilter == 'all'
|
||||
? 'Showing: 📂 All folders'
|
||||
? _t('Showing: 📂 All folders')
|
||||
: _folderFilter == 'tournament'
|
||||
? 'Showing: 🏆 Tournament folders'
|
||||
: 'Showing: 🎯 Training folders',
|
||||
? _t('Showing: 🏆 Tournament folders')
|
||||
: _t('Showing: 🎯 Training folders'),
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
const Icon(Icons.filter_list),
|
||||
@@ -738,7 +913,7 @@ Widget build(BuildContext context) {
|
||||
// 📁 Folder list or empty state
|
||||
Expanded(
|
||||
child: _groupedFiles.isEmpty
|
||||
? const Center(child: Text("No saved target data found", style: TextStyle(fontSize: 18)))
|
||||
? Center(child: Text(_t("No saved target data found"), style: const TextStyle(fontSize: 18)))
|
||||
: Scrollbar(
|
||||
thumbVisibility: true, // always show scrollbar
|
||||
thickness: 6, // optional: adjust width
|
||||
@@ -771,9 +946,9 @@ void _showFolderFilterPopup(BuildContext context) {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
'Filter Folders',
|
||||
style: TextStyle(
|
||||
Text(
|
||||
_t('Filter Folders'),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -782,21 +957,22 @@ void _showFolderFilterPopup(BuildContext context) {
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Folder type filters
|
||||
_buildStyledFilterButton('all', '📂 All folders', context),
|
||||
_buildStyledFilterButton('all', _t('📂 All folders'), context),
|
||||
const SizedBox(height: 12),
|
||||
_buildStyledFilterButton('tournament', '🏆 Tournament', context),
|
||||
_buildStyledFilterButton('tournament', _t('🏆 Tournament'), context),
|
||||
const SizedBox(height: 12),
|
||||
_buildStyledFilterButton('training', '🎯 Training', context),
|
||||
_buildStyledFilterButton('training', _t('🎯 Training'), context),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
const Text(
|
||||
'Sort By',
|
||||
style: TextStyle(color: Colors.white70, fontSize: 16, fontWeight: FontWeight.w500),
|
||||
Text(
|
||||
_t('Sort By'),
|
||||
style: const TextStyle(color: Colors.white70, fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
@@ -805,20 +981,23 @@ void _showFolderFilterPopup(BuildContext context) {
|
||||
this.setState(() {}); // 👈 refresh parent widget
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
margin: const EdgeInsets.only(right: 8),
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 8),
|
||||
margin: const EdgeInsets.only(right: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: _sortMode == 'date' ? _bulletColor : Colors.grey[800],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'📅 Sort by Date',
|
||||
_t('📅 Sort by Date'),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: _sortMode == 'date' ? Colors.white : Colors.white70,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 15,
|
||||
fontSize: 14,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -831,19 +1010,23 @@ void _showFolderFilterPopup(BuildContext context) {
|
||||
this.setState(() {}); // 👈 refresh parent widget
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 8),
|
||||
margin: const EdgeInsets.only(left: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: _sortMode == 'score' ? _bulletColor : Colors.grey[800],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'🏆 Sort by Score',
|
||||
_t('🏆 Sort by Score'),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: _sortMode == 'score' ? Colors.white : Colors.white70,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 15,
|
||||
fontSize: 14,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user