Skip to content

Commit

Permalink
feat: Fully working lifecycle for the Robotoff question in the Produc…
Browse files Browse the repository at this point in the history
…t page (#4198)

* Fully working lifecycle for the Robotoff question

* And obviously, let's improve a11n

* Improve a bit the animation for the question page

* Prefer constants for durations
  • Loading branch information
g123k authored Jun 18, 2023
1 parent e87143e commit 9e232c6
Show file tree
Hide file tree
Showing 4 changed files with 267 additions and 86 deletions.
8 changes: 8 additions & 0 deletions packages/smooth_app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,14 @@
"@tap_to_answer": {
"description": "Button label shown on a product, clicking the button opens a card with unanswered product questions, users can answer these to contribute to Open food facts and gain rewards."
},
"tap_to_answer_hint": "Tap here to answer questions about this product",
"@tap_to_answer_hint": {
"description": "Hint for accessibility readers to answer Robotoff questions."
},
"robotoff_questions_loading_hint": "Please wait while questions about this product are loaded",
"@robotoff_questions_loading_hint": {
"description": "Hint for accessibility readers while Robotoff questions are loaded"
},
"saving_answer": "Saving your answer",
"@saving_answer": {
"description": "Dialog shown to users after they have answered a question, while the answer is being saved in the BE."
Expand Down
74 changes: 51 additions & 23 deletions packages/smooth_app/lib/pages/hunger_games/question_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,58 @@ Future<void> openQuestionPage(
List<RobotoffQuestion>? questions,
Function()? updateProductUponAnswers,
}) =>
showDialog<void>(
showGeneralDialog<void>(
context: context,
barrierColor: Colors.black.withOpacity(0.7),
builder: (_) => BackdropFilter(
filter: ImageFilter.blur(sigmaX: 1.0, sigmaY: 1.0),
child: _QuestionPage(
product: product,
questions: questions,
updateProductUponAnswers: updateProductUponAnswers,
),
),
pageBuilder: (_, __, ___) => EMPTY_WIDGET,
transitionBuilder: (
BuildContext context,
Animation<double> a1,
Animation<double> a2,
Widget child,
) {
return SafeArea(
child: Stack(
children: <Widget>[
Positioned.fill(
child: GestureDetector(
excludeFromSemantics: true,
onTap: () => Navigator.of(context).maybePop(),
),
),
Align(
alignment: Alignment.center,
child: Transform.scale(
scale: a1.value,
child: Opacity(
opacity: a1.value,
child: SafeArea(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 1.0, sigmaY: 1.0),
child: _QuestionPage(
product: product,
questions: questions,
updateProductUponAnswers: updateProductUponAnswers,
),
),
),
),
),
),
Positioned.directional(
textDirection: Directionality.of(context),
top: 0.0,
start: SMALL_SPACE,
child: Opacity(
opacity: a1.value,
child: const _CloseButton(),
),
),
],
),
);
},
transitionDuration: SmoothAnimationsDuration.medium,
);

class _QuestionPage extends StatefulWidget {
Expand Down Expand Up @@ -112,20 +153,7 @@ class _QuestionPageState extends State<_QuestionPage>
}
return true;
},
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: _buildAnimationSwitcher(),
),
Positioned.directional(
textDirection: Directionality.of(context),
top: 0.0,
start: SMALL_SPACE,
child: const _CloseButton(),
),
],
),
child: Center(child: _buildAnimationSwitcher()),
);

AnimatedSwitcher _buildAnimationSwitcher() => AnimatedSwitcher(
Expand Down
21 changes: 16 additions & 5 deletions packages/smooth_app/lib/pages/product/new_product_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import 'package:smooth_app/pages/inherited_data_manager.dart';
import 'package:smooth_app/pages/product/common/product_list_page.dart';
import 'package:smooth_app/pages/product/common/product_refresher.dart';
import 'package:smooth_app/pages/product/edit_product_page.dart';
import 'package:smooth_app/pages/product/product_questions_widget.dart';
import 'package:smooth_app/pages/product/summary_card.dart';
import 'package:smooth_app/pages/product_list_user_dialog_helper.dart';
import 'package:smooth_app/query/product_query.dart';
Expand Down Expand Up @@ -57,6 +58,7 @@ class _ProductPageState extends State<ProductPage> with TraceableClientMixin {
late final Product _initialProduct;
late final LocalDatabase _localDatabase;
late ProductPreferences _productPreferences;
bool _keepRobotoffQuestionsAlive = true;

bool scrollingUp = true;

Expand Down Expand Up @@ -202,11 +204,14 @@ class _ProductPageState extends State<ProductPage> with TraceableClientMixin {
widget.heroTag?.isNotEmpty == true,
child: Hero(
tag: widget.heroTag ?? '',
child: SummaryCard(
_product,
_productPreferences,
isFullVersion: true,
showUnansweredQuestions: true,
child: KeepQuestionWidgetAlive(
keepWidgetAlive: _keepRobotoffQuestionsAlive,
child: SummaryCard(
_product,
_productPreferences,
isFullVersion: true,
showUnansweredQuestions: true,
),
),
),
),
Expand Down Expand Up @@ -343,17 +348,23 @@ class _ProductPageState extends State<ProductPage> with TraceableClientMixin {
Icons.edit,
appLocalizations.edit_product_label,
() async {
setState(() => _keepRobotoffQuestionsAlive = false);

AnalyticsHelper.trackEvent(
AnalyticsEvent.openProductEditPage,
barcode: _barcode,
);

await Navigator.push<void>(
context,
MaterialPageRoute<void>(
builder: (BuildContext context) =>
EditProductPage(_product),
),
);

// Force Robotoff questions to be reloaded
setState(() => _keepRobotoffQuestionsAlive = true);
},
),
_buildActionBarItem(
Expand Down
Loading

0 comments on commit 9e232c6

Please sign in to comment.