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/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/manage/manage_page.dart b/lib/src/manage/manage_page.dart index 2eeec7853..95b2a3a5c 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,8 @@ class _ActionButtons extends ConsumerWidget { mainAxisSize: MainAxisSize.min, children: [ PushButton.outlined( - onPressed: ref.read(updatesModelProvider).refresh, + onPressed: + updatesModel.activeChangeId != null ? null : updatesModel.refresh, child: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -170,23 +172,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, + ), + ), + ], ), - ), - ], - ), ), ], ); diff --git a/lib/src/snapd/snap_l10n.dart b/lib/src/snapd/snap_l10n.dart new file mode 100644 index 000000000..b734999c2 --- /dev/null +++ b/lib/src/snapd/snap_l10n.dart @@ -0,0 +1,21 @@ +import 'package:snapd/snapd.dart'; + +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, + }; +} + +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/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; }