From 16b0f2898233212b0db54d1157de9552b23c24cc Mon Sep 17 00:00:00 2001 From: Dennis Loose Date: Fri, 18 Aug 2023 17:23:01 +0200 Subject: [PATCH] add sorting and filtering to manage page --- lib/src/l10n/app_en.arb | 2 ++ lib/src/manage/manage_page.dart | 61 +++++++++++++++++++++++++++++++-- test/manage_page_test.dart | 4 +++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/lib/src/l10n/app_en.arb b/lib/src/l10n/app_en.arb index c3a25366e..6e88fb55c 100644 --- a/lib/src/l10n/app_en.arb +++ b/lib/src/l10n/app_en.arb @@ -26,7 +26,9 @@ "managePageInstalledAndUpdatedLabel": "Installed and updated", "managePageLabel": "Manage", "managePageNoUpdatesAvailableDescription": "No updates available. Your applications are all up to date.", + "managePageSearchFieldSearchHint": "Search your installed apps", "managePageShowDetailsLabel": "Show details", + "managePageShowSystemSnapsLabel": "Show system snaps", "managePageUpdateAllLabel": "Update All", "managePageUpdatedDaysAgo": "Updated {n} days ago", "@managePageUpdatedDaysAgo": { diff --git a/lib/src/manage/manage_page.dart b/lib/src/manage/manage_page.dart index b3e6c7c90..4a84c1fc8 100644 --- a/lib/src/manage/manage_page.dart +++ b/lib/src/manage/manage_page.dart @@ -10,6 +10,7 @@ import '/layout.dart'; import '/snapd.dart'; import '/store.dart'; import '/widgets.dart'; +import 'local_snap_providers.dart'; import 'manage_model.dart'; class ManagePage extends ConsumerWidget { @@ -36,6 +37,7 @@ class _ManageView extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + final filteredLocalSnaps = ref.watch(localSnapsProvider); final l10n = AppLocalizations.of(context); return Padding( padding: const EdgeInsets.symmetric(vertical: kPagePadding), @@ -106,13 +108,66 @@ class _ManageView extends ConsumerWidget { .titleMedium! .copyWith(fontWeight: FontWeight.w500), ), + const SizedBox(height: 8), + Row( + children: [ + Expanded( + // TODO: refactor - extract common text field decoration from + // here and the `SearchField` widget + child: TextFormField( + decoration: InputDecoration( + prefixIcon: const Icon(YaruIcons.search, size: 16), + hintText: l10n.managePageSearchFieldSearchHint, + ), + initialValue: ref.watch(localSnapFilterProvider), + onChanged: (value) => ref + .read(localSnapFilterProvider.notifier) + .state = value, + ), + ), + const SizedBox(width: 16), + Text(l10n.searchPageSortByLabel), + const SizedBox(width: 8), + // TODO: refactor - create proper widget + Expanded( + child: Consumer(builder: (context, ref, child) { + final sortOrder = ref.watch(localSnapSortOrderProvider); + return MenuButtonBuilder( + values: const [ + SnapSortOrder.alphabeticalAsc, + SnapSortOrder.alphabeticalDesc, + SnapSortOrder.installedDateAsc, + SnapSortOrder.installedDateDesc, + SnapSortOrder.installedSizeAsc, + SnapSortOrder.installedSizeDesc, + ], + itemBuilder: (context, sortOrder, child) => + Text(sortOrder.localize(l10n)), + onSelected: (value) => ref + .read(localSnapSortOrderProvider.notifier) + .state = value, + child: Text(sortOrder.localize(l10n)), + ); + }), + ), + const SizedBox(width: 16), + Text(l10n.managePageShowSystemSnapsLabel), + const SizedBox(width: 8), + YaruCheckbox( + value: ref.watch(showLocalSystemAppsProvider), + onChanged: (value) => ref + .read(showLocalSystemAppsProvider.notifier) + .state = value ?? false, + ) + ], + ), const SizedBox(height: 24), ]), SliverList.builder( - itemCount: manageModel.nonRefreshableSnaps.length, + itemCount: filteredLocalSnaps.length, itemBuilder: (context, index) => _ManageSnapTile( - snap: manageModel.nonRefreshableSnaps.elementAt(index), - position: index == (manageModel.nonRefreshableSnaps.length - 1) + snap: filteredLocalSnaps.elementAt(index), + position: index == (filteredLocalSnaps.length - 1) ? index == 0 ? ManageTilePosition.single : ManageTilePosition.last diff --git a/test/manage_page_test.dart b/test/manage_page_test.dart index ed781f40a..7c8715f7a 100644 --- a/test/manage_page_test.dart +++ b/test/manage_page_test.dart @@ -1,5 +1,6 @@ import 'package:app_store/manage.dart'; import 'package:app_store/snapd.dart'; +import 'package:app_store/src/manage/local_snap_providers.dart'; import 'package:app_store/src/manage/manage_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -33,6 +34,7 @@ void main() { (_) => createMockManageModel(nonRefreshableSnaps: nonRefreshableSnaps), ), + showLocalSystemAppsProvider.overrideWith((ref) => true), updatesModelProvider.overrideWith((_) => createMockUpdatesModel()) ], child: const ManagePage(), @@ -67,6 +69,7 @@ void main() { manageModelProvider.overrideWith((_) => createMockManageModel( nonRefreshableSnaps: nonRefreshableSnaps, )), + showLocalSystemAppsProvider.overrideWith((ref) => true), updatesModelProvider.overrideWith((_) => createMockUpdatesModel()) ], child: const ManagePage(), @@ -101,6 +104,7 @@ void main() { }); // TODO: test loading states with snap change in progress + // TODO: test sorting and filtering } extension on CommonFinders {