Skip to content

Commit

Permalink
Product loading card with a real UI
Browse files Browse the repository at this point in the history
  • Loading branch information
g123k committed Jul 15, 2023
1 parent 00f42ae commit 8e999f6
Show file tree
Hide file tree
Showing 11 changed files with 240 additions and 25 deletions.
1 change: 1 addition & 0 deletions packages/smooth_app/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 33
ndkVersion "25.1.8937393"

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand Down
Binary file added packages/smooth_app/assets/animations/off.riv
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,39 +1,176 @@
import 'dart:async';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import 'package:rive/rive.dart';
import 'package:smooth_app/data_models/continuous_scan_model.dart';
import 'package:smooth_app/generic_lib/buttons/smooth_simple_button.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/duration_constants.dart';

class SmoothProductCardLoading extends StatelessWidget {
class SmoothProductCardLoading extends StatefulWidget {
const SmoothProductCardLoading({required this.barcode});

final String barcode;

@override
State<SmoothProductCardLoading> createState() =>
_SmoothProductCardLoadingState();
}

class _SmoothProductCardLoadingState extends State<SmoothProductCardLoading> {
late Timer _timer;
_SmoothProductCardLoadingProgress _progress =
_SmoothProductCardLoadingProgress.initial;

@override
void initState() {
super.initState();
_timer = Timer(const Duration(seconds: 7), _onLongRequest);
}

@override
Widget build(BuildContext context) {
final AppLocalizations appLocalizations = AppLocalizations.of(context);
final ThemeData themeData = Theme.of(context);

return Container(
decoration: BoxDecoration(
color: themeData.brightness == Brightness.light
? Colors.white
: Colors.black,
borderRadius: ROUNDED_BORDER_RADIUS,
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(barcode, style: Theme.of(context).textTheme.titleMedium),
],
),
const SizedBox(
height: 12.0,
),
const CircularProgressIndicator.adaptive()
],
return DefaultTextStyle.merge(
textAlign: TextAlign.center,
style: const TextStyle(height: 1.4),
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(
vertical: SMALL_SPACE,
horizontal: MEDIUM_SPACE,
),
decoration: BoxDecoration(
color: themeData.brightness == Brightness.light
? Colors.white
: Colors.black,
borderRadius: ROUNDED_BORDER_RADIUS,
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
const Spacer(),
Text(
appLocalizations.scan_product_loading,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
const Spacer(flex: 2),
Container(
padding: const EdgeInsets.symmetric(
horizontal: SMALL_SPACE,
vertical: SMALL_SPACE,
),
color: Colors.grey.withOpacity(0.2),
child: Text(
'<${widget.barcode}>',
style: const TextStyle(
letterSpacing: 6.0,
fontFeatures: <FontFeature>[
FontFeature.tabularFigures(),
],
),
),
),
const Spacer(flex: 2),
AnimatedSwitcher(
duration: SmoothAnimationsDuration.long,
child: Text(_description(appLocalizations)),
transitionBuilder: (Widget child, Animation<double> animation) {
return FadeTransition(
opacity: Tween<double>(
begin: 0.0,
end: 1.0,
).animate(animation),
child: child,
);
},
),
const Spacer(),
if (_progress == _SmoothProductCardLoadingProgress.unresponsive)
SmoothSimpleButton(
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Icon(Icons.restart_alt),
const SizedBox(
width: SMALL_SPACE,
),
Text(appLocalizations.scan_product_loading_restart_button)
],
),
onPressed: () {
final ContinuousScanModel model =
context.read<ContinuousScanModel>();

model.retryBarcodeFetch(widget.barcode);
},
),
const Spacer(),
Expanded(
flex: 10,
child: ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 300,
),
child: const RiveAnimation.asset(
'assets/animations/off.riv',
artboard: 'Loading',
alignment: Alignment.topCenter,
fit: BoxFit.fitHeight,
),
),
),
const Spacer(),
],
),
),
);
}

String _description(AppLocalizations appLocalizations) {
return switch (_progress) {
_SmoothProductCardLoadingProgress.longRequest =>
appLocalizations.scan_product_loading_long_request,
_SmoothProductCardLoadingProgress.unresponsive =>
appLocalizations.scan_product_loading_unresponsive,
_ => appLocalizations.scan_product_loading_initial,
};
}

void _onLongRequest() {
if (!mounted) {
return;
}
setState(() => _progress = _SmoothProductCardLoadingProgress.longRequest);
_timer = Timer(const Duration(seconds: 5), _onUnresponsiveRequest);
}

void _onUnresponsiveRequest() {
if (!mounted) {
return;
}
setState(() => _progress = _SmoothProductCardLoadingProgress.unresponsive);
}

@override
void dispose() {
_timer.cancel();
super.dispose();
}
}

enum _SmoothProductCardLoadingProgress {
initial,
longRequest,
unresponsive,
}
20 changes: 20 additions & 0 deletions packages/smooth_app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1939,6 +1939,26 @@
"@scan_header_compare_button_valid_state_tooltip": {
"description": "Tooltip (message visible with a long-press) on the Compare button on top of the scanner, when there is at least two prodiucts"
},
"scan_product_loading": "You have scanned\nthe barcode:",
"@scan_product_loading": {
"description": "Title when a product is loading (carousel card). Please ensure to keep the line break."
},
"scan_product_loading_initial": "We're looking for this product!\nPlease wait a few seconds…",
"@scan_product_loading_initial": {
"description": "Message when a product is loading (carousel card). Please ensure to keep the line break."
},
"scan_product_loading_long_request": "We're still looking for this product!\nDo you find it takes a long time to load? So are we…",
"@scan_product_loading_long_request": {
"description": "Message when a product is long to load (carousel card). Please ensure to keep the line break."
},
"scan_product_loading_unresponsive": "We're still looking for this product.\nWould you like to restart the search?",
"@scan_product_loading_unresponsive": {
"description": "Message when a product is too long to load (carousel card). Please ensure to keep the line break."
},
"scan_product_loading_restart_button": "Restart search",
"@scan_product_loading_restart_button": {
"description": "Button to force restart a product search"
},
"portion_calculator_description": "Calculate nutrition facts for a specific quantity",
"@portion_calculator_description": {
"description": "Sort of title that describes the portion calculator."
Expand Down
20 changes: 20 additions & 0 deletions packages/smooth_app/lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1927,6 +1927,26 @@
"@scan_header_compare_button_valid_state_tooltip": {
"description": "Tooltip (message visible with a long-press) on the Compare button on top of the scanner, when there is at least two prodiucts"
},
"scan_product_loading": "Vous avez scanné\nle code-barres :",
"@scan_product_loading": {
"description": "Title when a product is loading (carousel card). Please ensure to keep the line break."
},
"scan_product_loading_initial": "Nous cherchons ce produit !\nMerci de patienter quelques instants…",
"@scan_product_loading_initial": {
"description": "Message when a product is loading (carousel card). Please ensure to keep the line break."
},
"scan_product_loading_long_request": "Nous cherchons toujours ce produit !\nLe chargement vous paraît long ? Nous aussi…",
"@scan_product_loading_long_request": {
"description": "Message when a product is long to load (carousel card). Please ensure to keep the line break."
},
"scan_product_loading_unresponsive": "Nous cherchons toujours ce produit !\nVoulez-vous relancer la recherche ?",
"@scan_product_loading_unresponsive": {
"description": "Message when a product is too long to load (carousel card). Please ensure to keep the line break."
},
"scan_product_loading_restart_button": "Relancer la recherche",
"@scan_product_loading_restart_button": {
"description": "Button to force restart a product search"
},
"portion_calculator_description": "Calculer les valeurs nutritionnelles pour une quantité spécifique",
"@portion_calculator_description": {
"description": "Sort of title that describes the portion calculator."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import in_app_review
import mobile_scanner
import package_info_plus
import path_provider_foundation
import rive_common
import sentry_flutter
import share_plus
import shared_preferences_foundation
Expand All @@ -28,6 +29,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
RivePlugin.register(with: registry.registrar(forPlugin: "RivePlugin"))
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
Expand Down
6 changes: 6 additions & 0 deletions packages/smooth_app/macos/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- rive_common (0.0.1):
- FlutterMacOS
- Sentry/HybridSDK (7.31.5)
- sentry_flutter (0.0.1):
- Flutter
Expand All @@ -46,6 +48,7 @@ DEPENDENCIES:
- mobile_scanner (from `Flutter/ephemeral/.symlinks/plugins/mobile_scanner/macos`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- rive_common (from `Flutter/ephemeral/.symlinks/plugins/rive_common/macos`)
- sentry_flutter (from `Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos`)
- share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
Expand Down Expand Up @@ -76,6 +79,8 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
rive_common:
:path: Flutter/ephemeral/.symlinks/plugins/rive_common/macos
sentry_flutter:
:path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos
share_plus:
Expand All @@ -98,6 +103,7 @@ SPEC CHECKSUMS:
mobile_scanner: ed7618fb749adc6574563e053f3b8e5002c13994
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
rive_common: acedcab7802c0ece4b0d838b71d7deb637e1309a
Sentry: 4c9babff9034785067c896fd580b1f7de44da020
sentry_flutter: 1346a880b24c0240807b53b10cf50ddad40f504e
share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7
Expand Down
26 changes: 25 additions & 1 deletion packages/smooth_app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ packages:
source: hosted
version: "7.0.0"
async:
dependency: "direct main"
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
Expand Down Expand Up @@ -689,6 +689,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.0.2"
graphs:
dependency: transitive
description:
name: graphs
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
url: "https://pub.dev"
source: hosted
version: "2.3.1"
hive:
dependency: "direct main"
description:
Expand Down Expand Up @@ -1232,6 +1240,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.2.1"
rive:
dependency: "direct main"
description:
name: rive
sha256: f3b8af0898c987d68019e91d92257edd902c28c816e49de033a7272e86bd5425
url: "https://pub.dev"
source: hosted
version: "0.11.4"
rive_common:
dependency: transitive
description:
name: rive_common
sha256: f6687f9d70e6fd3888a9b0e9c0b307966d2ce74cf00cfb01dce906c3bbada52f
url: "https://pub.dev"
source: hosted
version: "0.1.0"
scanner_ml_kit:
dependency: "direct main"
description:
Expand Down
1 change: 1 addition & 0 deletions packages/smooth_app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ dependencies:
fimber: 0.6.6
shimmer: ^3.0.0
lottie: 2.2.0
rive: 0.11.4
webview_flutter: 3.0.4
flutter_custom_tabs: ^1.0.4
flutter_image_compress: 1.1.3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <file_selector_windows/file_selector_windows.h>
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <rive_common/rive_plugin.h>
#include <sentry_flutter/sentry_flutter_plugin.h>
#include <share_plus/share_plus_windows_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h>
Expand All @@ -23,6 +24,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
RivePluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("RivePlugin"));
SentryFlutterPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SentryFlutterPlugin"));
SharePlusWindowsPluginCApiRegisterWithRegistrar(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
file_selector_windows
flutter_secure_storage_windows
permission_handler_windows
rive_common
sentry_flutter
share_plus
url_launcher_windows
Expand Down

0 comments on commit 8e999f6

Please sign in to comment.