From 1caf79d66019dde766f8eb06cf36df44d25f2e5a Mon Sep 17 00:00:00 2001 From: Dennis Loose Date: Tue, 15 Aug 2023 11:07:04 +0200 Subject: [PATCH 1/5] move snap l10n extensions into separate file --- lib/snapd.dart | 1 + lib/src/detail/detail_page.dart | 17 ----------------- lib/src/snapd/snap_l10n.dart | 20 ++++++++++++++++++++ 3 files changed, 21 insertions(+), 17 deletions(-) create mode 100644 lib/src/snapd/snap_l10n.dart diff --git a/lib/snapd.dart b/lib/snapd.dart index 59eac6ac8..bd259f342 100644 --- a/lib/snapd.dart +++ b/lib/snapd.dart @@ -1,4 +1,5 @@ export 'src/snapd/snap_category_enum.dart'; +export 'src/snapd/snap_l10n.dart'; export 'src/snapd/snap_launcher.dart'; export 'src/snapd/snap_model.dart'; export 'src/snapd/snapd_service.dart'; diff --git a/lib/src/detail/detail_page.dart b/lib/src/detail/detail_page.dart index e743de903..b6c8c3067 100644 --- a/lib/src/detail/detail_page.dart +++ b/lib/src/detail/detail_page.dart @@ -509,20 +509,3 @@ class _ChannelDropdownEntry extends StatelessWidget { ); } } - -extension SnapdChangeL10n on SnapdChange { - String? localize(AppLocalizations l10n) => switch (kind) { - 'install-snap' => l10n.snapActionInstallingLabel, - 'remove-snap' => l10n.snapActionRemovingLabel, - _ => null, - }; -} - -extension SnapConfinementL10n on SnapConfinement { - String localize(AppLocalizations l10n) => switch (this) { - SnapConfinement.classic => l10n.snapConfinementClassic, - SnapConfinement.devmode => l10n.snapConfinementDevmode, - SnapConfinement.strict => l10n.snapConfinementStrict, - _ => name, - }; -} diff --git a/lib/src/snapd/snap_l10n.dart b/lib/src/snapd/snap_l10n.dart new file mode 100644 index 000000000..f98ab3b1c --- /dev/null +++ b/lib/src/snapd/snap_l10n.dart @@ -0,0 +1,20 @@ +import 'package:snapd/snapd.dart'; + +import '/l10n.dart'; + +extension SnapdChangeL10n on SnapdChange { + String? localize(AppLocalizations l10n) => switch (kind) { + 'install-snap' => l10n.snapActionInstallingLabel, + 'remove-snap' => l10n.snapActionRemovingLabel, + _ => null, + }; +} + +extension SnapConfinementL10n on SnapConfinement { + String localize(AppLocalizations l10n) => switch (this) { + SnapConfinement.classic => l10n.snapConfinementClassic, + SnapConfinement.devmode => l10n.snapConfinementDevmode, + SnapConfinement.strict => l10n.snapConfinementStrict, + _ => name, + }; +} From 29851eb46cc323fc84604a8a77d3ec1876a96410 Mon Sep 17 00:00:00 2001 From: Dennis Loose Date: Tue, 15 Aug 2023 11:07:51 +0200 Subject: [PATCH 2/5] show change progress in 'update all' button --- lib/src/manage/manage_page.dart | 63 +++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/lib/src/manage/manage_page.dart b/lib/src/manage/manage_page.dart index 2eeec7853..f2b901bd9 100644 --- a/lib/src/manage/manage_page.dart +++ b/lib/src/manage/manage_page.dart @@ -127,6 +127,7 @@ class _ManageView extends ConsumerWidget { } } +// TODO: refactor/generalize - similar to `_SnapActionButtons` class _ActionButtons extends ConsumerWidget { const _ActionButtons(); @@ -152,7 +153,9 @@ class _ActionButtons extends ConsumerWidget { mainAxisSize: MainAxisSize.min, children: [ PushButton.outlined( - onPressed: ref.read(updatesModelProvider).refresh, + onPressed: updatesModel.activeChangeId != null + ? null + : ref.read(updatesModelProvider).refresh, child: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -170,23 +173,53 @@ class _ActionButtons extends ConsumerWidget { ), const SizedBox(width: 8), PushButton.elevated( - onPressed: updatesModel.refreshableSnapNames.isNotEmpty + onPressed: updatesModel.refreshableSnapNames.isNotEmpty && + !updatesModel.state.isLoading ? ref.read(updatesModelProvider).updateAll : null, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon(YaruIcons.download), - const SizedBox(width: 8), - Flexible( - child: Text( - l10n.managePageUpdateAllLabel, - maxLines: 1, - overflow: TextOverflow.ellipsis, + child: updatesModel.activeChangeId != null + ? Consumer( + builder: (context, ref, child) { + final change = ref + .watch(changeProvider(updatesModel.activeChangeId)) + .whenOrNull(data: (data) => data); + return Row( + children: [ + SizedBox.square( + dimension: 16, + child: YaruCircularProgressIndicator( + value: change?.progress, + strokeWidth: 2, + ), + ), + if (change != null) ...[ + const SizedBox(width: 8), + Flexible( + child: Text( + change.localize(l10n) ?? '', + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ] + ], + ); + }, + ) + : Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(YaruIcons.download), + const SizedBox(width: 8), + Flexible( + child: Text( + l10n.managePageUpdateAllLabel, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], ), - ), - ], - ), ), ], ); From adb79b98ac50bbe9f438df615903e1ea2963cf74 Mon Sep 17 00:00:00 2001 From: Dennis Loose Date: Tue, 15 Aug 2023 11:08:40 +0200 Subject: [PATCH 3/5] update tests, leave todo notes --- test/detail_page_test.dart | 2 ++ test/manage_page_test.dart | 2 ++ test/test_utils.dart | 1 + 3 files changed, 5 insertions(+) diff --git a/test/detail_page_test.dart b/test/detail_page_test.dart index d8a4015c4..47ab27294 100644 --- a/test/detail_page_test.dart +++ b/test/detail_page_test.dart @@ -228,4 +228,6 @@ void main() { expect(find.text(tester.l10n.snapActionInstallLabel), findsNothing); expect(find.byType(YaruCircularProgressIndicator), findsOneWidget); }); + + // TODO: test loading states with snap change in progress } diff --git a/test/manage_page_test.dart b/test/manage_page_test.dart index 98cdbf0fe..ed781f40a 100644 --- a/test/manage_page_test.dart +++ b/test/manage_page_test.dart @@ -99,6 +99,8 @@ void main() { await tester.tap(openButton); verify(snapLauncher.open()).called(1); }); + + // TODO: test loading states with snap change in progress } extension on CommonFinders { diff --git a/test/test_utils.dart b/test/test_utils.dart index fbdfd4539..d68b87937 100644 --- a/test/test_utils.dart +++ b/test/test_utils.dart @@ -125,6 +125,7 @@ MockUpdatesModel createMockUpdatesModel( when(model.hasUpdate(any)).thenAnswer((i) => refreshableSnapNames?.contains(i.positionalArguments.single) ?? false); when(model.state).thenReturn(AsyncValue.data(() {}())); + when(model.activeChangeId).thenReturn(null); return model; } From e32897b2a2af388d56c6d3088e0ac0ad6ba85cb8 Mon Sep 17 00:00:00 2001 From: Dennis Loose Date: Tue, 15 Aug 2023 11:20:51 +0200 Subject: [PATCH 4/5] add 'updating' l10n string --- lib/src/l10n/app_en.arb | 1 + lib/src/snapd/snap_l10n.dart | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/src/l10n/app_en.arb b/lib/src/l10n/app_en.arb index 2c71c521c..d2108bb3b 100644 --- a/lib/src/l10n/app_en.arb +++ b/lib/src/l10n/app_en.arb @@ -92,6 +92,7 @@ "snapActionRemovingLabel": "Uninstalling", "snapActionSwitchChannelLabel": "Switch Channel", "snapActionUpdateLabel": "Update", + "snapActionUpdatingLabel": "Updating", "snapCategoryArtAndDesign": "Art and Design", "snapCategoryBooksAndReference": "Books and Reference", "snapCategoryDefaultButtonLabel": "Discover more", diff --git a/lib/src/snapd/snap_l10n.dart b/lib/src/snapd/snap_l10n.dart index f98ab3b1c..b734999c2 100644 --- a/lib/src/snapd/snap_l10n.dart +++ b/lib/src/snapd/snap_l10n.dart @@ -5,6 +5,7 @@ import '/l10n.dart'; extension SnapdChangeL10n on SnapdChange { String? localize(AppLocalizations l10n) => switch (kind) { 'install-snap' => l10n.snapActionInstallingLabel, + 'refresh-snap' => l10n.snapActionUpdatingLabel, 'remove-snap' => l10n.snapActionRemovingLabel, _ => null, }; From 38df7a4cdb822a9433cd63d501ee2b919658a7e3 Mon Sep 17 00:00:00 2001 From: Dennis Loose Date: Tue, 15 Aug 2023 17:38:53 +0200 Subject: [PATCH 5/5] re-use updatesModel --- lib/src/manage/manage_page.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/src/manage/manage_page.dart b/lib/src/manage/manage_page.dart index f2b901bd9..95b2a3a5c 100644 --- a/lib/src/manage/manage_page.dart +++ b/lib/src/manage/manage_page.dart @@ -153,9 +153,8 @@ class _ActionButtons extends ConsumerWidget { mainAxisSize: MainAxisSize.min, children: [ PushButton.outlined( - onPressed: updatesModel.activeChangeId != null - ? null - : ref.read(updatesModelProvider).refresh, + onPressed: + updatesModel.activeChangeId != null ? null : updatesModel.refresh, child: Row( mainAxisSize: MainAxisSize.min, children: [