diff --git a/packages/firmware_updater/lib/firmware_app.dart b/packages/firmware_updater/lib/firmware_app.dart index 0d4c120f..68cfdb74 100644 --- a/packages/firmware_updater/lib/firmware_app.dart +++ b/packages/firmware_updater/lib/firmware_app.dart @@ -8,6 +8,7 @@ import 'package:firmware_updater/fwupd_mock_service.dart'; import 'package:firmware_updater/fwupd_notifier.dart'; import 'package:firmware_updater/widgets.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:fwupd/fwupd.dart'; import 'package:gtk/gtk.dart'; @@ -39,6 +40,7 @@ class FirmwareApp extends StatefulWidget { class _FirmwareAppState extends State { YaruPageController? _controller; bool _initialized = false; + bool _onBattery = false; @override void initState() { @@ -60,6 +62,36 @@ class _FirmwareAppState extends State { }); }); gtkNotifier.addCommandLineListener(_commandLineListener); + + SchedulerBinding.instance.addPostFrameCallback((_) async { + final l10n = AppLocalizations.of(context); + if (_onBattery) { + await _showAlertDialog(l10n.acPowerTitle, l10n.acPowerMustBeSupplied); + } + }); + } + + Future _showAlertDialog(String titleP, String contentP) { + return showDialog( + context: context, + builder: (context) { + final l10n = AppLocalizations.of(context); + // return object of type Dialog + return AlertDialog( + title: Text(titleP), + content: Text(contentP), + actions: [ + // usually buttons at the bottom of the dialog + TextButton( + child: Text(l10n.ok), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); } @override @@ -109,12 +141,10 @@ class _FirmwareAppState extends State { Widget build(BuildContext context) { final store = context.watch(); final l10n = AppLocalizations.of(context); + _onBattery = + context.select((notifier) => notifier.onBattery); return _initialized - ? ErrorBanner( - message: context.select( - (notifier) => notifier.onBattery) - ? l10n.batteryWarning - : null, + ? Center( child: YaruMasterDetailPage( appBar: YaruWindowTitleBar(title: Text(l10n.appTitle)), controller: _controller, diff --git a/packages/firmware_updater/lib/src/l10n/app_en.arb b/packages/firmware_updater/lib/src/l10n/app_en.arb index 038e5d7e..1f43d200 100644 --- a/packages/firmware_updater/lib/src/l10n/app_en.arb +++ b/packages/firmware_updater/lib/src/l10n/app_en.arb @@ -147,5 +147,9 @@ }, "currentVersion": "Current Version", "minVersion": "Minimum Version", - "latestVersion": "Latest Version" + "latestVersion": "Latest Version", + "acPowerTitle": "You are currently on battery power", + "acPowerMustBeSupplied": "BIOS and other updates can't commence on battery power.\nPlug into A/C power and restart this app to perform those updates if available.", + "legacyBootTitle": "Legacy Boot Mode is selected in the BIOS", + "legacyBootCantUpdateInThisMode": "BIOS and other updates can't commence in this mode.\nSwitch to UEFI Boot Mode in the BIOS to proceed.\nNote - this may require an OS reinstall." } \ No newline at end of file diff --git a/packages/firmware_updater/lib/src/widgets/error_banner.dart b/packages/firmware_updater/lib/src/widgets/error_banner.dart deleted file mode 100644 index b0a25b4a..00000000 --- a/packages/firmware_updater/lib/src/widgets/error_banner.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:flutter/material.dart'; - -class ErrorBanner extends StatefulWidget { - const ErrorBanner({ - required this.child, - this.message, - super.key, - }); - - final Widget child; - final String? message; - - @override - State createState() => _ErrorBannerState(); -} - -class _ErrorBannerState extends State { - bool _visible = true; - - @override - Widget build(BuildContext context) { - return Material( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (widget.message != null && _visible) - Container( - color: Theme.of(context).colorScheme.errorContainer, - child: Row( - children: [ - Expanded( - child: Text( - widget.message!, - style: Theme.of(context).textTheme.labelMedium!.copyWith( - color: - Theme.of(context).colorScheme.onErrorContainer, - ), - textAlign: TextAlign.center, - ), - ), - IconButton( - onPressed: () => setState(() => _visible = false), - icon: const Icon(Icons.close, size: 16), - padding: EdgeInsets.zero, - visualDensity: const VisualDensity( - horizontal: -4, - vertical: -4, - ), - color: Theme.of(context).colorScheme.onErrorContainer, - ) - ], - ), - ), - Expanded(child: widget.child), - ], - ), - ); - } -} diff --git a/packages/firmware_updater/lib/widgets.dart b/packages/firmware_updater/lib/widgets.dart index 71cddb89..3c1f3380 100644 --- a/packages/firmware_updater/lib/widgets.dart +++ b/packages/firmware_updater/lib/widgets.dart @@ -3,7 +3,6 @@ export 'src/widgets/device_header.dart'; export 'src/widgets/device_icon.dart'; export 'src/widgets/device_panel_list.dart'; export 'src/widgets/dialogs.dart'; -export 'src/widgets/error_banner.dart'; export 'src/widgets/option_card.dart'; export 'src/widgets/refresh_button.dart'; export 'src/widgets/release_card.dart'; diff --git a/packages/firmware_updater/test/firmware_app_test.dart b/packages/firmware_updater/test/firmware_app_test.dart index ca778829..50e715c9 100644 --- a/packages/firmware_updater/test/firmware_app_test.dart +++ b/packages/firmware_updater/test/firmware_app_test.dart @@ -140,12 +140,19 @@ void main() { registerMockService(mockService()); registerMockService(mockGtkApplicationNotifier()); + // Check to make sure the AC-power warning dialog is displayed final store = mockStore(devices: devices); await tester.pumpApp((_) => buildPage(store: store, notifier: mockNotifier(onBattery: true))); await tester.pumpAndSettle(); - expect(find.text(tester.lang.batteryWarning), findsOneWidget); + expect(find.text(tester.lang.acPowerMustBeSupplied), findsOneWidget); + + // Make sure the dialog is dismissed by pressing the "OK" button + // (The OK button is the only TextButton on the dialog) + await tester.tap(find.byType(TextButton)); + await tester.pumpAndSettle(); + expect(find.text(tester.lang.acPowerMustBeSupplied), findsNothing); }); testWidgets('register callbacks', (tester) async {