diff --git a/lib/views/home.dart b/lib/views/home.dart index 9e0278b..31ccff7 100644 --- a/lib/views/home.dart +++ b/lib/views/home.dart @@ -24,6 +24,7 @@ import 'package:prasule/pw/platformbutton.dart'; import 'package:prasule/pw/platformfield.dart'; import 'package:prasule/pw/platformroute.dart'; import 'package:prasule/util/drawer.dart'; +import 'package:prasule/util/sorting.dart'; import 'package:prasule/util/text_color.dart'; import 'package:prasule/util/utils.dart'; import 'package:prasule/views/create_entry.dart'; @@ -41,13 +42,15 @@ class HomeView extends StatefulWidget { } class _HomeViewState extends State { - Wallet? selectedWallet; - List wallets = []; + Wallet? selectedWallet; // current wallet + List wallets = []; // all available wallets DateTime? prevDate; - late String locale; - var _searchActive = false; - var _filter = ""; + late String locale; // user's locale + var _searchActive = false; // whether search field is shown + var _filter = ""; // search filter final searchFocus = FocusNode(); + var sort = SortType.newest; + @override void didChangeDependencies() { super.didChangeDependencies(); @@ -191,40 +194,67 @@ class _HomeViewState extends State { }, ), ), - actions: [ - if (!_searchActive) - IconButton( - onPressed: () { - _searchActive = true; - setState(() {}); - }, - icon: const Icon(Icons.search), - ), - if (!_searchActive) - PopupMenuButton( - itemBuilder: (context) => [ - AppLocalizations.of(context).settings, - AppLocalizations.of(context).about, - ].map((e) => PopupMenuItem(value: e, child: Text(e))).toList(), - onSelected: (value) { - if (value == AppLocalizations.of(context).settings) { - Navigator.of(context) - .push( - platformRoute( - (context) => const SettingsView(), - ), - ) - .then((value) async { - wallets = await WalletManager.listWallets(); - selectedWallet = - await WalletManager.loadWallet(selectedWallet!.name); - }); - } else if (value == AppLocalizations.of(context).about) { - showAbout(context); - } - }, - ), - ], + actions: _searchActive + ? [] + : [ + IconButton( + onPressed: () { + _searchActive = true; + setState(() {}); + }, + icon: const Icon(Icons.search), + ), + PopupMenuButton( + tooltip: AppLocalizations.of(context).sort, + icon: const Icon(Icons.sort_rounded), + itemBuilder: (context) => [ + AppLocalizations.of(context).sortNewest, + AppLocalizations.of(context).sortOldest, + ] + .map( + (e) => PopupMenuItem( + value: e, + child: Text(e), + ), + ) + .toList(), + onSelected: (value) { + if (value == AppLocalizations.of(context).sortNewest) { + sort = SortType.newest; + setState(() {}); + } else if (value == + AppLocalizations.of(context).sortOldest) { + sort = SortType.oldest; + setState(() {}); + } + }, + ), + PopupMenuButton( + itemBuilder: (context) => [ + AppLocalizations.of(context).settings, + AppLocalizations.of(context).about, + ] + .map((e) => PopupMenuItem(value: e, child: Text(e))) + .toList(), + onSelected: (value) { + if (value == AppLocalizations.of(context).settings) { + Navigator.of(context) + .push( + platformRoute( + (context) => const SettingsView(), + ), + ) + .then((value) async { + wallets = await WalletManager.listWallets(); + selectedWallet = await WalletManager.loadWallet( + selectedWallet!.name); + }); + } else if (value == AppLocalizations.of(context).about) { + showAbout(context); + } + }, + ), + ], ), body: Center( child: SizedBox( @@ -358,43 +388,15 @@ class _HomeViewState extends State { ) .toList(), itemComparator: (a, b) => - b.date.compareTo(a.date), + (sort == SortType.newest) + ? b.date.compareTo(a.date) + : a.date.compareTo(b.date), groupBy: (e) => DateFormat.yMMMM(locale).format(e.date), - groupComparator: (a, b) { - // TODO: better sorting algorithm lol - final yearA = - RegExp(r'\d+').firstMatch(a); - if (yearA == null) return 0; - final yearB = - RegExp(r'\d+').firstMatch(b); - if (yearB == null) return 0; - final compareYears = - int.parse(yearB.group(0)!).compareTo( - int.parse(yearA.group(0)!), - ); - if (compareYears != 0) { - return compareYears; - } - final months = List.generate( - 12, - (index) => - DateFormat.MMMM(locale).format( - DateTime(2023, index + 1), - ), - ); - final monthA = - RegExp('[^0-9 ]+').firstMatch(a); - if (monthA == null) return 0; - final monthB = - RegExp('[^0-9 ]+').firstMatch(b); - if (monthB == null) return 0; - return months - .indexOf(monthB.group(0)!) - .compareTo( - months.indexOf(monthA.group(0)!), - ); - }, + groupComparator: (a, b) => + (sort == SortType.newest) + ? groupSortNewest(a, b, locale) + : groupSortOldest(a, b, locale), itemBuilder: (context, element) => Slidable( endActionPane: ActionPane( motion: const ScrollMotion(), @@ -760,3 +762,12 @@ class _HomeViewState extends State { ); } } + +/// Represents entry sorting type +enum SortType { + /// Sort newest first + newest, + + /// Sort oldest first + oldest +}