From b1093c0a9fb16777cc718a790789711bd5fe0048 Mon Sep 17 00:00:00 2001 From: Codel1417 Date: Mon, 10 Jun 2024 15:05:28 -0400 Subject: [PATCH] add snackbar notice if new pair is connected or an update is available --- .../Widgets/back_button_to_close.dart | 4 +- lib/Frontend/Widgets/snack_bar_overlay.dart | 83 ++++++++++++++++++- .../translation_string_definitions.dart | 10 ++- pubspec.lock | 13 +-- pubspec.yaml | 6 +- 5 files changed, 103 insertions(+), 13 deletions(-) diff --git a/lib/Frontend/Widgets/back_button_to_close.dart b/lib/Frontend/Widgets/back_button_to_close.dart index 9190fd125..2db4896a6 100644 --- a/lib/Frontend/Widgets/back_button_to_close.dart +++ b/lib/Frontend/Widgets/back_button_to_close.dart @@ -48,8 +48,8 @@ class _BackButtonToCloseState extends ConsumerState { behavior: SnackBarBehavior.floating, backgroundColor: Colors.transparent, content: AwesomeSnackbarContent( - title: doubleBackToCloseTitle(), - message: doubleBackToClose(), + title: doubleBackToClose(), + message: '', /// change contentType to ContentType.success, ContentType.warning or ContentType.help for variants contentType: ContentType.help, diff --git a/lib/Frontend/Widgets/snack_bar_overlay.dart b/lib/Frontend/Widgets/snack_bar_overlay.dart index 48bc4ee46..aaf468aa7 100644 --- a/lib/Frontend/Widgets/snack_bar_overlay.dart +++ b/lib/Frontend/Widgets/snack_bar_overlay.dart @@ -1,8 +1,15 @@ import 'dart:async'; +import 'package:awesome_snackbar_content/awesome_snackbar_content.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:go_router/go_router.dart'; +import 'package:multi_value_listenable_builder/multi_value_listenable_builder.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:tail_app/Backend/Bluetooth/bluetooth_manager.dart'; +import 'package:tail_app/Backend/Definitions/Device/device_definition.dart'; + +import '../translation_string_definitions.dart'; part 'snack_bar_overlay.g.dart'; @@ -24,6 +31,33 @@ class SnackBarOverlay extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { AsyncValue value = ref.watch(snackbarStreamProvider); + Map knownDevices = ref.watch(knownDevicesProvider); + ref.listen( + knownDevicesProvider, + (previous, next) { + if (previous != null && previous.length < next.length) { + Future( + () => ScaffoldMessenger.of(context) + ..clearSnackBars() + ..showSnackBar( + SnackBar( + /// need to set following properties for best effect of awesome_snackbar_content + elevation: 0, + behavior: SnackBarBehavior.floating, + backgroundColor: Colors.transparent, + content: AwesomeSnackbarContent( + title: newGearConnectedSnackbarTitle(), + message: newGearConnectedSnackbarLabel(), + + /// change contentType to ContentType.success, ContentType.warning or ContentType.help for variants + contentType: ContentType.success, + ), + ), + ), + ); + } + }, + ); if (value.hasValue) { Future( () { @@ -35,6 +69,53 @@ class SnackBarOverlay extends ConsumerWidget { }, ); } - return child; + if (knownDevices.isEmpty) { + return child; + } + return MultiValueListenableBuilder( + valueListenables: knownDevices.values + .map( + (e) => e.hasUpdate, + ) + .toList(), + builder: (context, values, child) { + if (values.any((element) => element == true)) { + BaseStatefulDevice? baseStatefulDevice = knownDevices.values + .where( + (element) => element.hasUpdate.value, + ) + .firstOrNull; + if (baseStatefulDevice == null) { + return child!; + } + Future( + () => ScaffoldMessenger.of(context) + ..clearSnackBars() + ..showSnackBar( + SnackBar( + /// need to set following properties for best effect of awesome_snackbar_content + elevation: 0, + behavior: SnackBarBehavior.floating, + backgroundColor: Colors.transparent, + duration: const Duration(seconds: 30), + content: AwesomeSnackbarContent( + title: otaAvailableSnackbarTitle(), + message: otaAvailableSnackbarLabel(), + onPressed: () { + ScaffoldMessenger.of(context).clearSnackBars(); + return context.push("/ota", extra: baseStatefulDevice.baseStoredDevice.btMACAddress); + }, + + /// change contentType to ContentType.success, ContentType.warning or ContentType.help for variants + contentType: ContentType.warning, + ), + ), + ), + ); + } + return child!; + }, + child: child, + ); } } diff --git a/lib/Frontend/translation_string_definitions.dart b/lib/Frontend/translation_string_definitions.dart index f9efe8c15..50b6e78c2 100644 --- a/lib/Frontend/translation_string_definitions.dart +++ b/lib/Frontend/translation_string_definitions.dart @@ -305,8 +305,6 @@ String onboardingCompletedTitle() => Intl.message("Happy Wagging!", name: 'onboa String doubleBackToClose() => Intl.message("Press again to exit", name: 'doubleBackToClose', desc: 'Snackbar message which appears when the back button is pressed at the main screen'); -String doubleBackToCloseTitle() => Intl.message("Gear is still connected", name: 'doubleBackToCloseTitle', desc: 'Snackbar message which appears when the back button is pressed at the main screen'); - String noLongerSupported() => Intl.message("This gear is no longer supported. Some app features may not work", name: 'noLongerSupported', desc: 'Warning message which appears for unsupported gear on the manage gear page'); String mandatoryOtaRequired() => Intl.message("A firmware update is required for this app to support your gear", name: 'mandatoryOtaRequired', desc: 'Warning message which appears for gear which have old firmware on the manage gear page'); @@ -344,3 +342,11 @@ String triggerActionSelectorTutorialLabel() => Intl.message("Select as many acti String featureLimitedOtaRequiredLabel() => Intl.message("Please update your gear to use this feature.", name: 'featureLimitedOtaRequiredLabel', desc: 'Label for the warning card when a feature requires a firmware update'); String joystickWarning() => Intl.message("The Joystick feature is experimental. Use at your own risk.", name: 'joystickWarning', desc: 'Label for the warning tutorial card on the joystick page'); + +String otaAvailableSnackbarLabel() => Intl.message("Please update your gear", name: 'otaAvailableSnackbarLabel', desc: 'Label for the snackbar that appears when gear has an update'); + +String otaAvailableSnackbarTitle() => Intl.message("Update Available", name: 'otaAvailableSnackbarTitle', desc: 'Label for the snackbar that appears when gear has an update'); + +String newGearConnectedSnackbarTitle() => Intl.message("Gear Connected", name: 'newGearConnectedSnackbarTitle', desc: 'Label for the snackbar that appears when new gear is paired and connected'); + +String newGearConnectedSnackbarLabel() => Intl.message("Happy Wagging", name: 'newGearConnectedSnackbarLabel', desc: 'Label for the snackbar that appears when new gear is paired and connected'); diff --git a/pubspec.lock b/pubspec.lock index 3e32f98d6..33853ef33 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -113,10 +113,11 @@ packages: awesome_snackbar_content: dependency: "direct main" description: - name: awesome_snackbar_content - sha256: a94407ad596ac4b2f925b032c11f390cd3b3e640a9799f4983b86be0bc17f62b - url: "https://pub.dev" - source: hosted + path: "." + ref: HEAD + resolved-ref: fc96d57f02952d5fbb3b809cdecbf40794df407b + url: "https://github.com/tbro2020/awesome_snackbar_content" + source: git version: "0.1.3" back_button_interceptor: dependency: "direct main" @@ -500,10 +501,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: "29c90806ac5f5fb896547720b73b17ee9aed9bba540dc5d91fe29f8c5745b10a" + sha256: a7eed9716c82453da5c09d3a82d4644e7070dd2da81bfe5b6c6873ae4f07cf4f url: "https://pub.dev" source: hosted - version: "8.0.3" + version: "8.0.4" firebase_testlab_detector: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index daf91b929..9b215ed46 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -83,8 +83,10 @@ dependencies: url: https://github.com/davigmacode/flutter_choice feedback: ^3.1.0 accessibility_tools: ^2.1.0 - awesome_snackbar_content: ^0.1.3 - + awesome_snackbar_content: + git: + url: https://github.com/tbro2020/awesome_snackbar_content + # Dio HTTP dio: ^5.4.3+1 native_dio_adapter: ^1.3.0