Skip to content

Commit

Permalink
feat: Robotoff question as a banner or a button (#4280)
Browse files Browse the repository at this point in the history
* Robotoff question in a product, visible as a banner (at the bottom of the screen) or in a button (current implementation)
We split the users into two cohorts and we will have some Analytics to understand if one is better than the other.
The CongratsWidget is also improved by some animations and accessibility

* Now with a better animation
  • Loading branch information
g123k authored Jul 29, 2023
1 parent 8d0ae6a commit a699773
Show file tree
Hide file tree
Showing 13 changed files with 937 additions and 287 deletions.
1 change: 1 addition & 0 deletions packages/smooth_app/assets/animations/stars.json

Large diffs are not rendered by default.

243 changes: 243 additions & 0 deletions packages/smooth_app/assets/icons/medal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 21 additions & 2 deletions packages/smooth_app/lib/data_models/user_preferences.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:shared_preferences/shared_preferences.dart';
Expand Down Expand Up @@ -57,7 +59,7 @@ class UserPreferences extends ChangeNotifier {

/// The current version of preferences (1)
static const String _TAG_VERSION = 'prefs_version';
static const int _PREFS_CURRENT_VERSION = 1;
static const int _PREFS_CURRENT_VERSION = 2;
static const String _TAG_PREFIX_IMPORTANCE = 'IMPORTANCE_AS_STRING';
static const String _TAG_CURRENT_THEME_MODE = 'currentThemeMode';
static const String _TAG_CURRENT_COLOR_SCHEME = 'currentColorScheme';
Expand All @@ -70,6 +72,7 @@ class UserPreferences extends ChangeNotifier {
static const String _TAG_USER_TRACKING = 'user_tracking';
static const String _TAG_CRASH_REPORTS = 'crash_reports';
static const String _TAG_EXCLUDED_ATTRIBUTE_IDS = 'excluded_attributes';
static const String _TAG_USER_GROUP = '_user_group';

/// Camera preferences
// Detect if a first successful scan was achieved (condition to show the
Expand Down Expand Up @@ -108,6 +111,9 @@ class UserPreferences extends ChangeNotifier {
/// Allow to migrate between versions
Future<void> _onMigrate() async {
final int? currentVersion = _sharedPreferences.getInt(_TAG_VERSION);
if (currentVersion == _PREFS_CURRENT_VERSION) {
return;
}

/// With version == null (or 0), [_TAG_USER_TRACKING] didn't exist
if (currentVersion == null) {
Expand All @@ -116,10 +122,20 @@ class UserPreferences extends ChangeNotifier {
if (crashReporting != null) {
await setUserTracking(crashReporting);
}
}

/// With version == null and 1, [_TAG_USER_GROUP] is missing
if (_sharedPreferences.getInt(_TAG_USER_GROUP) == null) {
await _sharedPreferences.setInt(
_TAG_VERSION, UserPreferences._PREFS_CURRENT_VERSION);
_TAG_USER_GROUP,
Random().nextInt(10),
);
}

await _sharedPreferences.setInt(
_TAG_VERSION,
UserPreferences._PREFS_CURRENT_VERSION,
);
}

String _getImportanceTag(final String variable) =>
Expand Down Expand Up @@ -163,6 +179,9 @@ class UserPreferences extends ChangeNotifier {
bool get userTracking =>
_sharedPreferences.getBool(_TAG_USER_TRACKING) ?? false;

/// A random int between 0 and 10 (a naive implementation to allow A/B testing)
int get userGroup => _sharedPreferences.getInt(_TAG_USER_GROUP)!;

Future<void> setCrashReports(final bool state) async {
await _sharedPreferences.setBool(_TAG_CRASH_REPORTS, state);
onCrashReportingChanged.value = state;
Expand Down
25 changes: 20 additions & 5 deletions packages/smooth_app/lib/generic_lib/widgets/smooth_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class SmoothCard extends StatelessWidget {
this.padding = const EdgeInsets.all(5.0),
this.elevation = 8,
this.borderRadius,
this.ignoreDefaultSemantics = false,
});

const SmoothCard.angular({
Expand All @@ -30,6 +31,7 @@ class SmoothCard extends StatelessWidget {
),
this.padding = const EdgeInsets.all(5.0),
this.elevation = 8,
this.ignoreDefaultSemantics = false,
}) : borderRadius = ANGULAR_BORDER_RADIUS;

const SmoothCard.flat({
Expand All @@ -44,6 +46,7 @@ class SmoothCard extends StatelessWidget {
this.padding = const EdgeInsets.all(5.0),
this.elevation = 0,
this.borderRadius,
this.ignoreDefaultSemantics = false,
});

final Widget child;
Expand All @@ -52,22 +55,34 @@ class SmoothCard extends StatelessWidget {
final EdgeInsetsGeometry? padding;
final BorderRadiusGeometry? borderRadius;
final double elevation;
final bool ignoreDefaultSemantics;

@override
Widget build(BuildContext context) {
final Widget result = Material(
Widget result = Container(
padding: padding,
child: child,
);

if (ignoreDefaultSemantics) {
result = Semantics(
container: false,
explicitChildNodes: true,
child: child,
);
}

result = Material(
elevation: elevation,
shadowColor: const Color.fromARGB(25, 0, 0, 0),
borderRadius: borderRadius ?? ROUNDED_BORDER_RADIUS,
color: color ??
(Theme.of(context).brightness == Brightness.light
? Colors.white
: Colors.black),
child: Container(
padding: padding,
child: child,
),
child: result,
);

return margin == null
? result
: Padding(
Expand Down
27 changes: 23 additions & 4 deletions packages/smooth_app/lib/helpers/analytics_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum AnalyticsCategory {
productEdit(tag: 'product edit'),
productFastTrackEdit(tag: 'product fast track edit'),
newProduct(tag: 'new product'),
robotoff(tag: 'robotoff'),
list(tag: 'list'),
deepLink(tag: 'deep link');

Expand Down Expand Up @@ -105,12 +106,30 @@ enum AnalyticsEvent {
tag: 'closed new product page without any input',
category: AnalyticsCategory.newProduct,
),
shareList(tag: 'shared a list', category: AnalyticsCategory.list),
openListWeb(tag: 'open a list in wbe', category: AnalyticsCategory.list),
shareList(
tag: 'shared a list',
category: AnalyticsCategory.list,
),
openListWeb(
tag: 'open a list in wbe',
category: AnalyticsCategory.list,
),
productDeepLink(
tag: 'open a product from an URL', category: AnalyticsCategory.deepLink),
tag: 'open a product from an URL',
category: AnalyticsCategory.deepLink,
),
genericDeepLink(
tag: 'generic deep link', category: AnalyticsCategory.deepLink);
tag: 'generic deep link',
category: AnalyticsCategory.deepLink,
),
questionVisible(
tag: 'question visible',
category: AnalyticsCategory.robotoff,
),
questionClicked(
tag: 'question clicked',
category: AnalyticsCategory.robotoff,
);

const AnalyticsEvent({required this.tag, required this.category});

Expand Down
Loading

0 comments on commit a699773

Please sign in to comment.