Skip to content

Commit

Permalink
feat: openfoodfacts#960 - changed the attribute/importance preference…
Browse files Browse the repository at this point in the history
… display.

Impacted files:
* `attribute_button.dart`: changed the whole display.
* `design_constants.dart`: added a constant for the default icon size.
* `product_preferences.dart`: added the downgrading of "very important" to "important".
* `pubspec.lock`: wtf
  • Loading branch information
monsieurtanuki committed Apr 17, 2022
1 parent aad0f2a commit b4046c0
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 59 deletions.
13 changes: 1 addition & 12 deletions packages/smooth_app/lib/data_models/product_preferences.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:openfoodfacts/model/AttributeGroup.dart';
import 'package:openfoodfacts/personalized_search/available_attribute_groups.dart';
import 'package:openfoodfacts/personalized_search/available_preference_importances.dart';
import 'package:openfoodfacts/personalized_search/available_product_preferences.dart';
import 'package:openfoodfacts/personalized_search/preference_importance.dart';
import 'package:openfoodfacts/personalized_search/product_preferences_manager.dart';
import 'package:openfoodfacts/personalized_search/product_preferences_selection.dart';
import 'package:smooth_app/data_models/downloadable_string.dart';
Expand Down Expand Up @@ -182,16 +181,6 @@ class ProductPreferences extends ProductPreferencesManager with ChangeNotifier {
availableProductPreferences = myAvailableProductPreferences;
}

@override
String getImportanceIdForAttributeId(String attributeId) =>
_getRefinedImportanceId(super.getImportanceIdForAttributeId(attributeId));

/// Downgrades "very important" to "important" (from 4 to 3 choices, simpler).
static String _getRefinedImportanceId(final String importanceId) =>
importanceId == PreferenceImportance.ID_VERY_IMPORTANT
? PreferenceImportance.ID_IMPORTANT
: importanceId;

Future<void> resetImportances() async {
await clearImportances(notifyListeners: false);
if (attributeGroups != null) {
Expand All @@ -202,7 +191,7 @@ class ProductPreferences extends ProductPreferencesManager with ChangeNotifier {
if (attribute.id != null && defaultF != null) {
await setImportance(
attribute.id!,
_getRefinedImportanceId(defaultF),
defaultF,
notifyListeners: false,
);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/smooth_app/lib/generic_lib/design_constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const double MEDIUM_SPACE = 12.0;
const double LARGE_SPACE = 16.0;
const double VERY_LARGE_SPACE = 20.0;

/// Default icon size, cf. [Icon]
const double DEFAULT_ICON_SIZE = 24.0;

/// Background, e.g SmoothCard
const Radius ROUNDED_RADIUS = Radius.circular(20.0);
//ignore: non_constant_identifier_names
Expand Down
164 changes: 123 additions & 41 deletions packages/smooth_app/lib/widgets/attribute_button.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/model/Attribute.dart';
import 'package:openfoodfacts/personalized_search/preference_importance.dart';
import 'package:smooth_app/data_models/product_preferences.dart';
import 'package:smooth_app/generic_lib/buttons/smooth_action_button.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/dialogs/smooth_alert_dialog.dart';

/// Colored button for attribute importance, with corresponding action
class AttributeButton extends StatelessWidget {
Expand All @@ -15,58 +18,137 @@ class AttributeButton extends StatelessWidget {
final Attribute attribute;
final ProductPreferences productPreferences;

static const Map<String, String> _nextValues = <String, String>{
PreferenceImportance.ID_NOT_IMPORTANT: PreferenceImportance.ID_IMPORTANT,
PreferenceImportance.ID_IMPORTANT: PreferenceImportance.ID_MANDATORY,
PreferenceImportance.ID_MANDATORY: PreferenceImportance.ID_NOT_IMPORTANT,
};

static const Map<String, Color> _colors = <String, Color>{
PreferenceImportance.ID_NOT_IMPORTANT: PRIMARY_GREY_COLOR,
PreferenceImportance.ID_IMPORTANT: PRIMARY_BLUE_COLOR,
PreferenceImportance.ID_MANDATORY: RED_COLOR,
};
static const List<String> _importanceIds = <String>[
PreferenceImportance.ID_NOT_IMPORTANT,
PreferenceImportance.ID_IMPORTANT,
PreferenceImportance.ID_VERY_IMPORTANT,
PreferenceImportance.ID_MANDATORY,
];

@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
String importanceId =
final IconThemeData iconThemeData = IconTheme.of(context);
final String currentImportanceId =
productPreferences.getImportanceIdForAttributeId(attribute.id!);
// We switch from 4 to 3 choices: very important is downgraded to important
if (importanceId == PreferenceImportance.ID_VERY_IMPORTANT) {
importanceId = PreferenceImportance.ID_IMPORTANT;
}
const double horizontalPadding = LARGE_SPACE;
final double screenWidth =
final double widgetWidth =
MediaQuery.of(context).size.width - 2 * horizontalPadding;
final double importanceWidth = widgetWidth / 4;
final TextStyle style = themeData.textTheme.headline3!;
final String? info = attribute.settingNote;
final List<Widget> labelChildren = <Widget>[];
final List<Widget> importanceChildren = <Widget>[];
for (final String importanceId in _importanceIds) {
Future<void> selectImportance() async {
await productPreferences.setImportance(attribute.id!, importanceId);
await showDialog<void>(
context: context,
builder: (BuildContext context) {
final AppLocalizations? appLocalizations =
AppLocalizations.of(context);
return SmoothAlertDialog(
body: Text(
'blah blah blah importance "$importanceId"'), // TODO(monsieurtanuki): find translations
actions: <SmoothActionButton>[
SmoothActionButton(
text: appLocalizations!.close,
onPressed: () => Navigator.pop(context),
),
],
);
},
);
}

labelChildren.add(
GestureDetector(
onTap: () async => selectImportance(),
child: SizedBox(
width: importanceWidth,
child: AutoSizeText(
productPreferences
.getPreferenceImportanceFromImportanceId(importanceId)!
.name!,
maxLines: 2,
textAlign: TextAlign.center,
),
),
),
);
importanceChildren.add(
SizedBox(
width: importanceWidth,
child: Center(
child: Radio<String>(
groupValue: currentImportanceId,
value: importanceId,
onChanged: (final String? value) async => selectImportance(),
),
),
),
);
}
return Padding(
padding: const EdgeInsets.symmetric(horizontal: horizontalPadding),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
padding: const EdgeInsets.symmetric(
vertical: SMALL_SPACE,
horizontal: horizontalPadding,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
width: screenWidth * .45,
child: Text(attribute.name!, style: style),
),
SizedBox(
width: screenWidth * .45,
child: ElevatedButton(
child: AutoSizeText(
productPreferences
.getPreferenceImportanceFromImportanceId(importanceId)!
.name!,
style: style.copyWith(color: Colors.white),
maxLines: 1,
),
style: ElevatedButton.styleFrom(
primary: _colors[importanceId],
onPrimary: Colors.white,
),
onPressed: () async => productPreferences.setImportance(
attribute.id!, _nextValues[importanceId]!),
GestureDetector(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
if (info != null) const Icon(Icons.info_outline),
Container(
padding: info == null
? null
: const EdgeInsets.only(left: SMALL_SPACE),
child: SizedBox(
width: widgetWidth -
SMALL_SPACE -
(iconThemeData.size ?? DEFAULT_ICON_SIZE),
child: AutoSizeText(
attribute.settingName ?? attribute.name!,
maxLines: 2,
style: style,
),
),
),
],
),
onTap: info == null
? null
: () async => showDialog<void>(
context: context,
builder: (BuildContext context) {
final AppLocalizations? appLocalizations =
AppLocalizations.of(context);
return SmoothAlertDialog(
body: Text(info),
actions: <SmoothActionButton>[
SmoothActionButton(
text: appLocalizations!.close,
onPressed: () => Navigator.pop(context),
),
],
);
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: labelChildren,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: importanceChildren,
),
],
),
Expand Down
12 changes: 6 additions & 6 deletions packages/smooth_app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ packages:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.4"
version: "0.6.3"
json_annotation:
dependency: transitive
description:
Expand Down Expand Up @@ -555,7 +555,7 @@ packages:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
version: "0.1.3"
matomo_forever:
dependency: "direct main"
description:
Expand Down Expand Up @@ -660,7 +660,7 @@ packages:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
version: "1.8.0"
path_drawing:
dependency: transitive
description:
Expand Down Expand Up @@ -938,7 +938,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.2"
version: "1.8.1"
stack_trace:
dependency: transitive
description:
Expand Down Expand Up @@ -987,7 +987,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.9"
version: "0.4.8"
transparent_image:
dependency: transitive
description:
Expand Down Expand Up @@ -1092,7 +1092,7 @@ packages:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
version: "2.1.1"
visibility_detector:
dependency: "direct main"
description:
Expand Down

0 comments on commit b4046c0

Please sign in to comment.