Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: UI improvements for the edit mode #6132

Merged
merged 7 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SmoothLargeButtonWithIcon extends StatelessWidget {
final String text;
final IconData icon;
final VoidCallback? onPressed;
final EdgeInsets? padding;
final EdgeInsetsGeometry? padding;
final IconData? trailing;
final Color? backgroundColor;
final Color? foregroundColor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class SmoothSimpleButton extends StatelessWidget {
final double minWidth;
final double height;
final BorderRadius borderRadius;
final EdgeInsets padding;
final EdgeInsetsGeometry padding;
final Color? buttonColor;

@override
Expand Down
125 changes: 125 additions & 0 deletions packages/smooth_app/lib/generic_lib/widgets/smooth_card.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'package:flutter/material.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/themes/smooth_theme.dart';
import 'package:smooth_app/themes/smooth_theme_colors.dart';
import 'package:smooth_app/themes/theme_provider.dart';

/// Renders a Material card with elevation, shadow, Border radius etc...
/// Note: If the caller updates BoxDecoration of the [header] or [child] widget,
Expand Down Expand Up @@ -100,3 +103,125 @@ class SmoothCard extends StatelessWidget {
);
}
}

class SmoothCardWithRoundedHeader extends StatelessWidget {
const SmoothCardWithRoundedHeader({
required this.title,
required this.child,
this.iconTitle,
this.contentPadding,
});

final String title;
final Widget? iconTitle;
final Widget child;
final EdgeInsetsGeometry? contentPadding;

@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final SmoothColorsThemeExtension extension =
context.extension<SmoothColorsThemeExtension>();

final Color color =
context.lightTheme() ? extension.primaryBlack : Colors.black;

return Column(
children: <Widget>[
Semantics(
label: title,
excludeSemantics: true,
child: CustomPaint(
painter: _SmoothCardWithRoundedHeaderBackgroundPainter(
color: color,
radius: ROUNDED_RADIUS,
),
child: Padding(
padding: const EdgeInsetsDirectional.symmetric(
vertical: MEDIUM_SPACE,
horizontal: LARGE_SPACE,
),
child: Row(
children: <Widget>[
if (iconTitle != null)
DecoratedBox(
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Padding(
padding: const EdgeInsetsDirectional.all(SMALL_SPACE),
child: IconTheme(
data: IconThemeData(
color: color,
size: 18.0,
),
child: iconTitle!,
),
),
),
const SizedBox(width: MEDIUM_SPACE),
Text(
title,
style: themeData.textTheme.displaySmall?.copyWith(
color: Colors.white,
),
),
],
),
),
),
),
SmoothCard(
margin: EdgeInsets.zero,
padding: contentPadding ??
const EdgeInsetsDirectional.only(
top: MEDIUM_SPACE,
),
color: context.darkTheme() ? extension.primaryUltraBlack : null,
child: child,
),
],
);
}
}

/// We need this [CustomPainter] to draw the background below the other card
class _SmoothCardWithRoundedHeaderBackgroundPainter extends CustomPainter {
_SmoothCardWithRoundedHeaderBackgroundPainter({
required Color color,
required this.radius,
}) : _paint = Paint()..color = color;

final Radius radius;
final Paint _paint;

@override
void paint(Canvas canvas, Size size) {
canvas.drawRRect(
RRect.fromRectAndCorners(
Rect.fromLTWH(
0.0,
0.0,
size.width,
size.height + ROUNDED_RADIUS.y,
),
topLeft: radius,
topRight: radius,
),
_paint,
);
}

@override
bool shouldRepaint(
_SmoothCardWithRoundedHeaderBackgroundPainter oldDelegate,
) =>
false;

@override
bool shouldRebuildSemantics(
_SmoothCardWithRoundedHeaderBackgroundPainter oldDelegate,
) =>
false;
}
2 changes: 2 additions & 0 deletions packages/smooth_app/lib/helpers/product_cards_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ Widget addPanelButton(
final String label, {
final IconData? iconData,
final String? textAlign,
final EdgeInsetsGeometry? padding,
required final Function() onPressed,
}) =>
Padding(
Expand All @@ -319,6 +320,7 @@ Widget addPanelButton(
icon: iconData ?? Icons.add,
onPressed: onPressed,
textAlign: iconData == null ? TextAlign.center : null,
padding: padding,
),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class SmoothAutocompleteTextField extends StatefulWidget {
this.minLengthForSuggestions = 1,
this.allowEmojis = true,
this.suffixIcon,
this.borderRadius,
this.padding,
});

final FocusNode focusNode;
Expand All @@ -31,6 +33,8 @@ class SmoothAutocompleteTextField extends StatefulWidget {
final AutocompleteManager? manager;
final bool allowEmojis;
final Widget? suffixIcon;
final BorderRadius? borderRadius;
final EdgeInsetsGeometry? padding;

@override
State<SmoothAutocompleteTextField> createState() =>
Expand Down Expand Up @@ -86,14 +90,15 @@ class _SmoothAutocompleteTextFieldState
decoration: InputDecoration(
suffixIcon: widget.suffixIcon,
filled: true,
border: const OutlineInputBorder(
borderRadius: ANGULAR_BORDER_RADIUS,
border: OutlineInputBorder(
borderRadius: widget.borderRadius ?? ANGULAR_BORDER_RADIUS,
borderSide: BorderSide.none,
),
contentPadding: const EdgeInsets.symmetric(
horizontal: SMALL_SPACE,
vertical: SMALL_SPACE,
),
contentPadding: widget.padding ??
const EdgeInsets.symmetric(
horizontal: SMALL_SPACE,
vertical: SMALL_SPACE,
),
hintText: widget.hintText,
suffix: Offstage(
offstage: !_loading,
Expand Down
53 changes: 36 additions & 17 deletions packages/smooth_app/lib/pages/product/add_other_details_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:smooth_app/background/background_task_details.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_card.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_text_form_field.dart';
import 'package:smooth_app/helpers/analytics_helper.dart';
import 'package:smooth_app/helpers/product_cards_helper.dart';
import 'package:smooth_app/pages/product/common/product_buttons.dart';
import 'package:smooth_app/pages/product/may_exit_page_helper.dart';
import 'package:smooth_app/pages/text_field_helper.dart';
import 'package:smooth_app/themes/smooth_theme_colors.dart';
import 'package:smooth_app/themes/theme_provider.dart';
import 'package:smooth_app/widgets/smooth_scaffold.dart';
import 'package:smooth_app/widgets/will_pop_scope.dart';

Expand All @@ -27,16 +30,16 @@ class AddOtherDetailsPage extends StatefulWidget {
class _AddOtherDetailsPageState extends State<AddOtherDetailsPage> {
late final TextEditingControllerWithHistory _websiteController;

final double _heightSpace = LARGE_SPACE;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
late final Product _product;

@override
void initState() {
super.initState();
_product = widget.product;
_websiteController =
TextEditingControllerWithHistory(text: _product.website ?? '');
_websiteController = TextEditingControllerWithHistory(
text: _product.website ?? '',
);
}

@override
Expand All @@ -52,8 +55,8 @@ class _AddOtherDetailsPageState extends State<AddOtherDetailsPage> {

@override
Widget build(BuildContext context) {
final Size size = MediaQuery.sizeOf(context);
final AppLocalizations appLocalizations = AppLocalizations.of(context);

return WillPopScope2(
onWillPop: () async => (await _mayExitPage(saving: false), null),
child: SmoothScaffold(
Expand All @@ -63,24 +66,40 @@ class _AddOtherDetailsPageState extends State<AddOtherDetailsPage> {
title: appLocalizations.edit_product_form_item_other_details_title,
product: widget.product,
),
backgroundColor: context.lightTheme()
? Theme.of(context)
.extension<SmoothColorsThemeExtension>()!
.primaryLight
: null,
body: Form(
key: _formKey,
child: Scrollbar(
child: ListView(
padding: const EdgeInsetsDirectional.only(
top: MEDIUM_SPACE,
start: MEDIUM_SPACE,
end: MEDIUM_SPACE,
),
children: <Widget>[
SizedBox(height: _heightSpace),
Padding(
padding: EdgeInsets.symmetric(horizontal: size.width * 0.05),
child: Column(
children: <Widget>[
SizedBox(height: _heightSpace),
SmoothTextFormField(
controller: _websiteController,
type: TextFieldTypes.PLAIN_TEXT,
hintText: appLocalizations.product_field_website_title,
),
SizedBox(height: _heightSpace),
],
SmoothCardWithRoundedHeader(
title: appLocalizations.product_field_website_title,
iconTitle: const Icon(Icons.link),
child: Padding(
padding: const EdgeInsetsDirectional.only(
bottom: MEDIUM_SPACE,
start: MEDIUM_SPACE,
end: MEDIUM_SPACE,
),
child: Column(
children: <Widget>[
SmoothTextFormField(
controller: _websiteController,
type: TextFieldTypes.PLAIN_TEXT,
hintText:
appLocalizations.product_field_website_title,
),
],
),
),
),
],
Expand Down
49 changes: 21 additions & 28 deletions packages/smooth_app/lib/pages/product/simple_input_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/background/background_task_details.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_card.dart';
import 'package:smooth_app/helpers/analytics_helper.dart';
import 'package:smooth_app/helpers/collections_helper.dart';
import 'package:smooth_app/helpers/product_cards_helper.dart';
Expand Down Expand Up @@ -77,26 +76,24 @@ class _SimpleInputPageState extends State<SimpleInputPage> {
padding: i == 0
? EdgeInsets.zero
: const EdgeInsets.only(top: LARGE_SPACE),
child: SmoothCard(
// This provider will handle the dispose() call for us
child: MultiProvider(
providers: <ChangeNotifierProvider<dynamic>>[
ChangeNotifierProvider<TextEditingController>(
create: (_) {
_controllers.replace(i, TextEditingController());
return _controllers[i];
},
),
ChangeNotifierProvider<AbstractSimpleInputPageHelper>(
create: (_) => widget.helpers[i],
),
],
child: SimpleInputWidget(
helper: widget.helpers[i],
product: widget.product,
controller: _controllers[i],
displayTitle: widget.helpers.length > 1,
// This provider will handle the dispose() call for us
child: MultiProvider(
providers: <ChangeNotifierProvider<dynamic>>[
ChangeNotifierProvider<TextEditingController>(
create: (_) {
_controllers.replace(i, TextEditingController());
return _controllers[i];
},
),
ChangeNotifierProvider<AbstractSimpleInputPageHelper>(
create: (_) => widget.helpers[i],
),
],
child: SimpleInputWidget(
helper: widget.helpers[i],
product: widget.product,
controller: _controllers[i],
displayTitle: widget.helpers.length > 1,
),
),
),
Expand All @@ -118,14 +115,10 @@ class _SimpleInputPageState extends State<SimpleInputPage> {
.extension<SmoothColorsThemeExtension>()!
.primaryLight
: null,
body: Padding(
padding: const EdgeInsetsDirectional.only(
top: SMALL_SPACE,
start: SMALL_SPACE,
end: SMALL_SPACE,
),
child: Scrollbar(
child: ListView(children: simpleInputs),
body: Scrollbar(
child: ListView(
padding: const EdgeInsetsDirectional.all(MEDIUM_SPACE),
children: simpleInputs,
),
),
bottomNavigationBar: ProductBottomButtonsBar(
Expand Down
Loading
Loading