Commit 674b1b0

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-05-13 11:43:34
finish closed bluetooth input
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 4180c71
Changed files (3)
app
app/lib/components/bluetooth_input/closed_bluetooth_input.dart
@@ -0,0 +1,74 @@
+import 'package:blood_pressure_app/bluetooth/bluetooth_cubit.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+
+/// A closed ble input that shows the adapter state and allows to start the input.
+class ClosedBluetoothInput extends StatelessWidget {
+  /// Show adapter state and allow starting inputs
+  const ClosedBluetoothInput({super.key,
+    required this.bluetoothCubit,
+    required this.onStarted,
+    this.inputInfo,
+  });
+  // TODO: test
+
+  /// State update provider and interaction with the device.
+  final BluetoothCubit bluetoothCubit;
+
+  /// Called when the user taps on an active start button.
+  final void Function() onStarted;
+
+  /// Callback called when the user wants to know more about this input.
+  ///
+  /// The info icon is not shown when this is null.
+  final void Function()? inputInfo;
+
+  Widget _buildTile({
+    required String text,
+    required IconData icon,
+    required void Function() onTap,
+  }) => ListTile(
+    title: Text(text),
+    leading: Icon(icon),
+    onTap: onTap,
+    trailing: inputInfo == null ? null : IconButton(
+      icon: const Icon(Icons.info_outline),
+      onPressed: inputInfo!,
+    ),
+  );
+  
+  @override
+  Widget build(BuildContext context) {
+    final localizations = AppLocalizations.of(context)!;
+    return BlocBuilder<BluetoothCubit, BluetoothState>(
+      bloc: bluetoothCubit,
+      builder: (context, BluetoothState state) => switch(state) {
+        BluetoothInitial() => const SizedBox.shrink(),
+        BluetoothUnfeasible() => const SizedBox.shrink(),
+        BluetoothUnauthorized() => _buildTile(
+          text: localizations.errBleNoPerms,
+          icon: Icons.bluetooth_disabled,
+          onTap: () async {
+            await bluetoothCubit.requestPermission();
+            await bluetoothCubit.forceRefresh();
+          },
+        ),
+        BluetoothDisabled() => _buildTile(
+          text: localizations.bluetoothDisabled,
+          icon: Icons.bluetooth_disabled,
+          onTap: () async {
+            await bluetoothCubit.enableBluetooth();
+            await bluetoothCubit.forceRefresh();
+          },
+        ),
+        BluetoothReady() => _buildTile(
+          text: localizations.bluetoothDisabled,
+          icon: Icons.bluetooth,
+          onTap: onStarted,
+        ),
+      },
+    );
+  }
+  
+}
app/lib/components/bluetooth_input.dart
@@ -3,6 +3,7 @@ import 'dart:async';
 import 'package:blood_pressure_app/bluetooth/ble_read_cubit.dart';
 import 'package:blood_pressure_app/bluetooth/bluetooth_cubit.dart';
 import 'package:blood_pressure_app/bluetooth/device_scan_cubit.dart';
+import 'package:blood_pressure_app/components/bluetooth_input/closed_bluetooth_input.dart';
 import 'package:blood_pressure_app/components/bluetooth_input/input_card.dart';
 import 'package:blood_pressure_app/model/storage/storage.dart';
 import 'package:flutter/material.dart';
@@ -22,6 +23,7 @@ class BluetoothInput extends StatefulWidget {
   State<BluetoothInput> createState() => _BluetoothInputState();
 }
 // TODO: more info
+// TODO: make toggleable in settings
 
 class _BluetoothInputState extends State<BluetoothInput> {
   /// Whether the user expanded bluetooth input
@@ -44,39 +46,7 @@ class _BluetoothInputState extends State<BluetoothInput> {
     }
   }
 
-  Widget _buildIdle(BuildContext context) => BlocBuilder<BluetoothCubit, BluetoothState>(
-    bloc: _bluetoothCubit,
-    builder: (context, BluetoothState state) => switch(state) {
-      BluetoothInitial() => const Align(
-        alignment: Alignment.topRight,
-        child: CircularProgressIndicator(),
-      ),
-      BluetoothUnfeasible() => const SizedBox.shrink(),
-      BluetoothUnauthorized() => ListTile(
-        title: Text(AppLocalizations.of(context)!.errBleNoPerms),
-        leading: const Icon(Icons.bluetooth_disabled),
-        onTap: () async {
-          // TODO: test
-          await _bluetoothCubit.requestPermission();
-          await _bluetoothCubit.forceRefresh();
-        },
-        // TODO: add information icon
-      ),
-      BluetoothDisabled() => ListTile(
-        title: Text(AppLocalizations.of(context)!.bluetoothDisabled),
-        leading: const Icon(Icons.bluetooth_disabled),
-        onTap: () async {
-          await _bluetoothCubit.enableBluetooth();
-          await _bluetoothCubit.forceRefresh();
-        },
-      ),
-      BluetoothReady() => ListTile(
-        leading: const Icon(Icons.bluetooth),
-        title: Text(AppLocalizations.of(context)!.bluetoothDisabled),
-        onTap: () => setState(() => _isActive = true),
-      ),
-    },
-  );
+  // TODO: bloc dispose
 
   Widget _buildActive(BuildContext context) {
     _bluetoothSubscription = _bluetoothCubit.stream.listen((state) {
@@ -149,7 +119,20 @@ class _BluetoothInputState extends State<BluetoothInput> {
   @override
   Widget build(BuildContext context) {
     if (_isActive) return _buildActive(context);
-    return _buildIdle(context);
+    return ClosedBluetoothInput(
+      bluetoothCubit: _bluetoothCubit,
+      onStarted: () => setState(() =>_isActive = true),
+      inputInfo: () async {
+        if (context.mounted) {
+          await showDialog(
+            context: context,
+            builder: (BuildContext context) => Text(
+              AppLocalizations.of(context)!.aboutBleInput,
+            )
+          );
+        }
+      },
+    );
   }
 
 
app/lib/l10n/app_en.arb
@@ -531,5 +531,7 @@
   "connect": "Connect",
   "@connect": {},
   "bluetoothInput": "Bluetooth input",
-  "@bluetoothInput": {}
+  "@bluetoothInput": {},
+  "aboutBleInput": "Some measurement devices allow automatically transmitting measurements through the BLE GATT protocol. You can pair your device here or disable this option in the settings.",
+  "@aboutBleInput": {}
 }