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: 5817 Product page: tab Data #5953

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:smooth_app/pages/product/product_page/raw_data/models/product_raw_data_category.dart';
import 'package:smooth_app/resources/app_icons.dart' as icons;

extension CategoryLabelExt on ProductRawDataCategories {
String toL10nString(AppLocalizations appLocalizations) => switch (this) {
ProductRawDataCategories.labels => appLocalizations.label_refresh,
ProductRawDataCategories.category => appLocalizations.category,
ProductRawDataCategories.ingredients => appLocalizations.ingredients,
ProductRawDataCategories.countries =>
appLocalizations.country_chooser_label_from_settings,
ProductRawDataCategories.nutriment => appLocalizations.nutrition,
ProductRawDataCategories.packaging =>
appLocalizations.packaging_information,
ProductRawDataCategories.stores =>
appLocalizations.edit_product_form_item_stores_title,
};

Widget toIcon() => switch (this) {
ProductRawDataCategories.labels => const icons.Labels(),
ProductRawDataCategories.category => const icons.Categories(),
ProductRawDataCategories.ingredients => const icons.Ingredients(),
ProductRawDataCategories.countries => const icons.Countries(),
ProductRawDataCategories.nutriment => const icons.NutritionFacts(),
ProductRawDataCategories.packaging => const icons.Packaging(),
ProductRawDataCategories.stores => const icons.Stores(),
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'package:smooth_app/pages/product/product_page/raw_data/models/raw_data_element.dart';

class ProductRawDataCategory {
const ProductRawDataCategory(this.category, this.rawDatas);

final ProductRawDataCategories category;
final List<ProductRawDataSubCategory> rawDatas;
}

enum ProductRawDataCategories {
labels,
category,
ingredients,
nutriment,
packaging,
stores,
countries
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
sealed class ProductRawDataSubCategory {}

class ProductRawDataElement extends ProductRawDataSubCategory {
ProductRawDataElement(this.name);

final String name;
}

class ProductRawDataElementDoubleText extends ProductRawDataSubCategory {
ProductRawDataElementDoubleText(this.text1, this.text2);

final String text1;
final String text2;
}

class ProductRawDataSeeMoreButton extends ProductRawDataSubCategory {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import 'package:flutter/material.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/pages/product/product_page/raw_data/models/raw_data_element.dart';
import 'package:smooth_app/pages/product/product_page/raw_data/product_raw_data_element_item.dart';
import 'package:smooth_app/themes/theme_provider.dart';

class CategoryElementsListView extends StatefulWidget {
const CategoryElementsListView({
required this.elements,
this.controller,
});

final List<ProductRawDataSubCategory> elements;
final ScrollController? controller;

@override
State<StatefulWidget> createState() => _CategoryElementsListViewState();
}

class _CategoryElementsListViewState extends State<CategoryElementsListView> {
bool extended = false;

void extendList() {
setState(() {
extended = true;
});
}

@override
Widget build(BuildContext context) {
final List<ProductRawDataSubCategory> listToShow;
if (extended) {
listToShow = widget.elements;
} else {
listToShow = _shortenIfTooLong(widget.elements);
}
final Color dividerColor =
context.lightTheme() ? const Color(0xFFF9F9F9) : Colors.white;

return Padding(
padding: const EdgeInsetsDirectional.only(start: 90.0),
child: ListView.separated(
controller: widget.controller,
physics: const ClampingScrollPhysics(),
shrinkWrap: true,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ShrinkWrap is your enemy. Why do you use it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is wrong with ShrinkWrap ?

In my case, it is needed to not have a crash due to ListView inside the other list view.

padding: const EdgeInsetsDirectional.symmetric(
vertical: MEDIUM_SPACE,
),
itemBuilder: (BuildContext context, int index) {
return Container(
margin: const EdgeInsetsDirectional.only(start: 21),
child: ProductRawDataElementItem(
listToShow[index],
() => extendList(),
),
);
},
separatorBuilder: (BuildContext context, _) => Divider(
color: dividerColor,
),
itemCount: listToShow.length,
),
);
}

static const int _SUB_LIST_LENGTH = 3;

List<ProductRawDataSubCategory> _shortenIfTooLong(
List<ProductRawDataSubCategory> list) {
if (list.length > _SUB_LIST_LENGTH) {
final List<ProductRawDataSubCategory> toReturn =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A more generic way is to use the following syntax:

[
...list.sublist(0, _SUB_LIST_LENGTH),
ProductRawDataSeeMoreButton(),
]

<ProductRawDataSubCategory>[
...list.sublist(0, _SUB_LIST_LENGTH),
ProductRawDataSeeMoreButton()
];
return toReturn;
} else {
return list;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/pages/product/product_page/raw_data/category_label_ext.dart';
import 'package:smooth_app/pages/product/product_page/raw_data/models/product_raw_data_category.dart';
import 'package:smooth_app/pages/product/product_page/raw_data/product_raw_data_category_elements_item.dart';
import 'package:smooth_app/resources/app_icons.dart' as icons;
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';

class ProductRawDataCategoryItem extends StatelessWidget {
const ProductRawDataCategoryItem(this.category, {this.controller});

final ProductRawDataCategory category;
final ScrollController? controller;

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

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_ProductRawDataCategoryTile(
category.category.toIcon(),
category.category.toL10nString(appLocalizations),
),
CategoryElementsListView(
elements: category.rawDatas,
controller: controller,
),
]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing trailing comma

}
}

class _ProductRawDataCategoryTile extends StatelessWidget {
const _ProductRawDataCategoryTile(this.icon, this.label);

final Widget icon;
final String label;
@override
Widget build(BuildContext context) {
final bool lightTheme = context.lightTheme();
final Color contentColor = lightTheme
? context.extension<SmoothColorsThemeExtension>().primaryBlack
: Colors.white;

final Color dividerColor =
lightTheme ? const Color(0xFFF9F9F9) : Colors.white;

return Container(
color: const Color(0xFFFEFEFE),
child: Column(
children: <Widget>[
Container(
margin:
const EdgeInsetsDirectional.symmetric(vertical: MEDIUM_SPACE),
//This rows of rows is here to have this Layout Spaced through the lign
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
//Element icon + label
Row(
children: <Widget>[
const SizedBox(width: 31.0),
IconTheme(
data: IconThemeData(
color: contentColor,
size: 18.0,
),
child: icon,
),
const SizedBox(width: MEDIUM_SPACE),
Text(label),
],
),
//Edit button
const Row(
children: <Widget>[
IconTheme(
data: IconThemeData(
color: Colors.grey,
size: 18.0,
),
child: icons.Edit(),
),
SizedBox(width: 28.0),
],
),
],
),
),
Divider(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need a Divider of 0?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the divider default value is not 0 but 16

color: dividerColor,
height: 0,
)
],
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:smooth_app/pages/product/product_page/raw_data/models/raw_data_element.dart';

class ProductRawDataElementItem extends StatelessWidget {
const ProductRawDataElementItem(
this.element,
this.onSeeMoreTap, {
this.controller,
});

final ProductRawDataSubCategory element;
final ScrollController? controller;
final Function() onSeeMoreTap;

@override
Widget build(BuildContext context) {
switch (element.runtimeType) {
case const (ProductRawDataElement):
return Text((element as ProductRawDataElement).name);
case const (ProductRawDataElementDoubleText):
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text((element as ProductRawDataElementDoubleText).text1),
Row(
children: <Widget>[
Text((element as ProductRawDataElementDoubleText).text2),
const SizedBox(
width: 29.0,
)
],
)
],
);
case const (ProductRawDataSeeMoreButton):
{
final AppLocalizations appLocalizations =
AppLocalizations.of(context);
return InkWell(
onTap: () => onSeeMoreTap(),
child: Text(appLocalizations.tap_for_more),
);
}
default:
throw FormatException('Invalid class ${element.runtimeType}');
}
}
}
Loading
Loading