diff --git a/lib/client.dart b/lib/client.dart index 6e96060..93d79e8 100644 --- a/lib/client.dart +++ b/lib/client.dart @@ -5,13 +5,12 @@ import 'package:fooder/models/meal.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; - class ApiClient { final String baseUrl; String? token; String? refreshToken; http.Client httpClient = http.Client(); - final FlutterSecureStorage storage = FlutterSecureStorage(); + final FlutterSecureStorage storage = const FlutterSecureStorage(); ApiClient({ required this.baseUrl, @@ -219,8 +218,9 @@ class ApiClient { } Future> getProductByBarcode(String barcode) async { - var response = - await get("/product/by_barcode?${Uri(queryParameters: {"barcode": barcode}).query}"); + var response = await get("/product/by_barcode?${Uri(queryParameters: { + "barcode": barcode + }).query}"); return response; } @@ -283,8 +283,7 @@ class ApiClient { } } - Future addMeal( - {required String name, required int diaryId}) async { + Future addMeal({required String name, required int diaryId}) async { await post("/meal", { "name": name, "diary_id": diaryId, @@ -292,7 +291,9 @@ class ApiClient { } Future addMealFromPreset( - {required String name, required int diaryId, required int presetId}) async { + {required String name, + required int diaryId, + required int presetId}) async { await post("/meal/from_preset", { "name": name, "diary_id": diaryId, diff --git a/lib/components/appBar.dart b/lib/components/appBar.dart deleted file mode 100644 index 1fafb18..0000000 --- a/lib/components/appBar.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; - -class FAppBar extends StatelessWidget implements PreferredSizeWidget { - final List actions; - - const FAppBar({super.key, required this.actions}); - - @override - Widget build(BuildContext context) { - var theme = Theme.of(context); - var colorScheme = theme.colorScheme; - - return Padding( - padding: EdgeInsets.symmetric(horizontal: 8), - child: AppBar( - backgroundColor: Colors.transparent, - elevation: 0, - actions: actions, - ) - ); - } - - @override - Size get preferredSize => Size.fromHeight(56); -} diff --git a/lib/components/app_bar.dart b/lib/components/app_bar.dart new file mode 100644 index 0000000..1023be7 --- /dev/null +++ b/lib/components/app_bar.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + +class FAppBar extends StatelessWidget implements PreferredSizeWidget { + final List actions; + + const FAppBar({super.key, required this.actions}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + actions: actions, + )); + } + + @override + Size get preferredSize => const Size.fromHeight(56); +} diff --git a/lib/components/button.dart b/lib/components/button.dart index 93ce07a..e66a97b 100644 --- a/lib/components/button.dart +++ b/lib/components/button.dart @@ -7,7 +7,13 @@ class FButton extends StatelessWidget { final double fontSize; final Function()? onPressed; - const FButton({super.key, required this.labelText, this.padding = 8, this.insidePadding = 24, this.fontSize = 20, this.onPressed}); + const FButton( + {super.key, + required this.labelText, + this.padding = 8, + this.insidePadding = 24, + this.fontSize = 20, + this.onPressed}); @override Widget build(BuildContext context) { @@ -15,38 +21,37 @@ class FButton extends StatelessWidget { var colorScheme = theme.colorScheme; return GestureDetector( - onTap: onPressed, - child: Padding( - padding: EdgeInsets.symmetric(vertical: padding, horizontal: padding), - child: Container( - padding: EdgeInsets.symmetric(vertical: insidePadding), - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - colorScheme.primary.withOpacity(0.5), - colorScheme.secondary.withOpacity(0.5), + onTap: onPressed, + child: Padding( + padding: EdgeInsets.symmetric(vertical: padding, horizontal: padding), + child: Container( + padding: EdgeInsets.symmetric(vertical: insidePadding), + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + colorScheme.primary.withOpacity(0.5), + colorScheme.secondary.withOpacity(0.5), + ], + ), + borderRadius: BorderRadius.circular(4), + boxShadow: [ + BoxShadow( + color: colorScheme.primary.withOpacity(0.3), + blurRadius: 5, + offset: const Offset(0, 5), + ) ], ), - borderRadius: BorderRadius.circular(4), - boxShadow: [ - BoxShadow( - color: colorScheme.primary.withOpacity(0.3), - blurRadius: 5, - offset: const Offset(0, 5), - ) - ], - ), - child: Center( - child: Text( - labelText, - style: theme.textTheme.button!.copyWith( - fontWeight: FontWeight.bold, - fontSize: fontSize, + child: Center( + child: Text( + labelText, + style: theme.textTheme.labelLarge!.copyWith( + fontWeight: FontWeight.bold, + fontSize: fontSize, + ), ), ), ), - ), - ) - ); + )); } } diff --git a/lib/components/datePicker.dart b/lib/components/date_picker.dart similarity index 73% rename from lib/components/datePicker.dart rename to lib/components/date_picker.dart index 4992c46..43b0180 100644 --- a/lib/components/datePicker.dart +++ b/lib/components/date_picker.dart @@ -1,12 +1,15 @@ import 'package:flutter/material.dart'; - class FDateItemWidget extends StatelessWidget { final DateTime date; final bool picked; final Function(DateTime) onDatePicked; - const FDateItemWidget({super.key, required this.date, required this.onDatePicked, this.picked = false}); + const FDateItemWidget( + {super.key, + required this.date, + required this.onDatePicked, + this.picked = false}); @override Widget build(BuildContext context) { @@ -28,7 +31,7 @@ class FDateItemWidget extends StatelessWidget { onDatePicked(date); }, child: Container( - width: picked? 100: 50, + width: picked ? 100 : 50, decoration: BoxDecoration( borderRadius: BorderRadius.circular(50), border: Border.all( @@ -36,7 +39,9 @@ class FDateItemWidget extends StatelessWidget { color: Colors.transparent, width: 2, ), - color: picked ? colorScheme.onPrimary.withOpacity(0.25) : Colors.transparent, + color: picked + ? colorScheme.onPrimary.withOpacity(0.25) + : Colors.transparent, ), child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -45,7 +50,7 @@ class FDateItemWidget extends StatelessWidget { dayOfTheWeekMap[date.weekday]!, style: TextStyle( color: colorScheme.onPrimary, - fontSize: picked ? 24: 12, + fontSize: picked ? 24 : 12, fontWeight: FontWeight.bold, ), ), @@ -53,7 +58,7 @@ class FDateItemWidget extends StatelessWidget { '${date.day}.${date.month}', style: TextStyle( color: colorScheme.onPrimary, - fontSize: picked ? 24: 12, + fontSize: picked ? 24 : 12, fontWeight: FontWeight.bold, ), ), @@ -68,7 +73,8 @@ class FDatePickerWidget extends StatefulWidget { final DateTime date; final Function(DateTime) onDatePicked; - const FDatePickerWidget({super.key, required this.date, required this.onDatePicked}); + const FDatePickerWidget( + {super.key, required this.date, required this.onDatePicked}); @override State createState() => _FDatePickerWidgetState(); @@ -106,13 +112,18 @@ class _FDatePickerWidgetState extends State { padding: const EdgeInsets.symmetric(horizontal: 20), shrinkWrap: true, children: [ - FDateItemWidget(date: date.add(Duration(days: -3)), onDatePicked: onDatePicked), - FDateItemWidget(date: date.add(Duration(days: -2)), onDatePicked: onDatePicked), - FDateItemWidget(date: date.add(Duration(days: -1)), onDatePicked: onDatePicked), - FDateItemWidget(date: date, onDatePicked: onDatePicked, picked: true), - FDateItemWidget(date: date.add(Duration(days: 1)), onDatePicked: onDatePicked), - FDateItemWidget(date: date.add(Duration(days: 2)), onDatePicked: onDatePicked), - Container( + FDateItemWidget( + date: date.add(const Duration(days: -2)), + onDatePicked: onDatePicked), + FDateItemWidget( + date: date.add(const Duration(days: -1)), + onDatePicked: onDatePicked), + FDateItemWidget( + date: date, onDatePicked: onDatePicked, picked: true), + FDateItemWidget( + date: date.add(const Duration(days: 1)), + onDatePicked: onDatePicked), + SizedBox( width: 50, child: IconButton( icon: Icon( @@ -125,8 +136,8 @@ class _FDatePickerWidgetState extends State { showDatePicker( context: context, initialDate: date, - firstDate: date.add(Duration(days: -365)), - lastDate: date.add(Duration(days: 365)), + firstDate: date.add(const Duration(days: -365)), + lastDate: date.add(const Duration(days: 365)), ).then((value) { if (value != null) { onDatePicked(value); diff --git a/lib/components/navigationBar.dart b/lib/components/navigationBar.dart deleted file mode 100644 index f31ab6b..0000000 --- a/lib/components/navigationBar.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:blur/blur.dart'; - -class FNavBar extends StatelessWidget { - final List children; - final double height; - - const FNavBar ({super.key, required this.children, this.height = 56}); - - @override - Widget build(BuildContext context) { - var theme = Theme.of(context); - var colorScheme = theme.colorScheme; - - return SafeArea( - child: Padding( - padding: EdgeInsets.all(12), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(24), - boxShadow: [ - BoxShadow( - color: colorScheme.primary.withOpacity(0.3), - blurRadius: 5, - offset: const Offset(0, 5), - ) - ], - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(24), - child: Stack( - children: [ - Blur( - blur: 10, - blurColor: colorScheme.primary.withOpacity(0.1), - child: Container( - width: MediaQuery.of(context).size.width, - height: height * children.length, - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - colorScheme.primary.withOpacity(0.1), - colorScheme.secondary.withOpacity(0.1), - ], - ), - ), - ), - ), - Container( - width: MediaQuery.of(context).size.width, - height: height * children.length, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: children, - ), - ), - ], - ) - ), - ), - ), - ); - } -} diff --git a/lib/components/navigation_bar.dart b/lib/components/navigation_bar.dart new file mode 100644 index 0000000..8e7a05b --- /dev/null +++ b/lib/components/navigation_bar.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import 'package:blur/blur.dart'; + +class FNavBar extends StatelessWidget { + static const maxWidth = 920.0; + + final List children; + final double height; + + const FNavBar({super.key, required this.children, this.height = 56}); + + @override + Widget build(BuildContext context) { + var theme = Theme.of(context); + var colorScheme = theme.colorScheme; + + var widthAvail = MediaQuery.of(context).size.width; + // var width = widthAvail > maxWidth ? maxWidth : widthAvail; + + return SafeArea( + child: Padding( + padding: const EdgeInsets.all(12), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + boxShadow: [ + BoxShadow( + color: colorScheme.primary.withOpacity(0.3), + blurRadius: 5, + offset: const Offset(0, 5), + ) + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(24), + child: Stack( + children: [ + Blur( + blur: 10, + blurColor: colorScheme.primary.withOpacity(0.1), + child: Container( + width: widthAvail, + height: height * children.length, + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + colorScheme.primary.withOpacity(0.1), + colorScheme.secondary.withOpacity(0.1), + ], + ), + ), + ), + ), + SizedBox( + width: widthAvail, + height: height * children.length, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: children, + ), + ), + ], + )), + ), + ), + ); + } +} diff --git a/lib/components/sliver.dart b/lib/components/sliver.dart index 5c52625..16d52dd 100644 --- a/lib/components/sliver.dart +++ b/lib/components/sliver.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:blur/blur.dart'; - class ClipShadowPath extends StatelessWidget { final Shadow shadow; final CustomClipper clipper; final Widget child; - ClipShadowPath({ + const ClipShadowPath({ + super.key, required this.shadow, required this.clipper, required this.child, @@ -17,10 +17,10 @@ class ClipShadowPath extends StatelessWidget { Widget build(BuildContext context) { return CustomPaint( painter: _ClipShadowShadowPainter( - clipper: this.clipper, - shadow: this.shadow, + clipper: clipper, + shadow: shadow, ), - child: ClipPath(child: child, clipper: this.clipper), + child: ClipPath(clipper: clipper, child: child), ); } } @@ -47,7 +47,7 @@ class _ClipShadowShadowPainter extends CustomPainter { class BackgroundWave extends StatelessWidget { final double height; - const BackgroundWave({Key? key, required this.height}) : super(key: key); + const BackgroundWave({super.key, required this.height}); @override Widget build(BuildContext context) { @@ -94,21 +94,30 @@ class BackgroundWaveClipper extends CustomClipper { var lastCurve = Offset(40, size.height - 20); path.quadraticBezierTo( - firstCurve.dx, firstCurve.dy, lastCurve.dx, lastCurve.dy, + firstCurve.dx, + firstCurve.dy, + lastCurve.dx, + lastCurve.dy, ); firstCurve = Offset(0, size.height - 20); lastCurve = Offset(size.width - 40, size.height - 20); path.quadraticBezierTo( - firstCurve.dx, firstCurve.dy, lastCurve.dx, lastCurve.dy, + firstCurve.dx, + firstCurve.dy, + lastCurve.dx, + lastCurve.dy, ); firstCurve = Offset(size.width, size.height - 20); lastCurve = Offset(size.width, size.height); path.quadraticBezierTo( - firstCurve.dx, firstCurve.dy, lastCurve.dx, lastCurve.dy, + firstCurve.dx, + firstCurve.dy, + lastCurve.dx, + lastCurve.dy, ); path.lineTo(size.width, 0.0); @@ -126,8 +135,10 @@ class FSliverAppBar extends SliverPersistentHeaderDelegate { const FSliverAppBar({required this.child}); @override - Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - var adjustedShrinkOffset = shrinkOffset > minExtent ? minExtent : shrinkOffset; + Widget build( + BuildContext context, double shrinkOffset, bool overlapsContent) { + var adjustedShrinkOffset = + shrinkOffset > minExtent ? minExtent : shrinkOffset; double offset = (minExtent - adjustedShrinkOffset); if (offset < 4) { @@ -141,9 +152,9 @@ class FSliverAppBar extends SliverPersistentHeaderDelegate { ), Positioned( top: offset, - child: child, left: 16, right: 16, + child: child, ) ], ); diff --git a/lib/components/text.dart b/lib/components/text.dart index 10dc877..7044f8e 100644 --- a/lib/components/text.dart +++ b/lib/components/text.dart @@ -9,7 +9,15 @@ class FTextInput extends StatelessWidget { final bool obscureText; final Function(String)? onFieldSubmitted; - const FTextInput({super.key, required this.labelText, this.padding = 8, required this.controller, this.autofillHints, this.autofocus = false, this.onFieldSubmitted, this.obscureText = false}); + const FTextInput( + {super.key, + required this.labelText, + this.padding = 8, + required this.controller, + this.autofillHints, + this.autofocus = false, + this.onFieldSubmitted, + this.obscureText = false}); @override Widget build(BuildContext context) { diff --git a/lib/screens/add_entry.dart b/lib/screens/add_entry.dart index 8a46752..a996fae 100644 --- a/lib/screens/add_entry.dart +++ b/lib/screens/add_entry.dart @@ -7,8 +7,6 @@ import 'package:fooder/models/meal.dart'; import 'package:fooder/widgets/product.dart'; import 'package:fooder/screens/add_product.dart'; import 'package:simple_barcode_scanner/simple_barcode_scanner.dart'; -import 'package:fooder/components/appBar.dart'; - class AddEntryScreen extends BasedScreen { final Diary diary; @@ -58,6 +56,7 @@ class _AddEntryScreen extends BasedState { }); } + @override void showError(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( @@ -99,7 +98,6 @@ class _AddEntryScreen extends BasedState { popMeDaddy(); } - Future _findProductByBarCode() async { var res = await Navigator.push( context, @@ -110,8 +108,7 @@ class _AddEntryScreen extends BasedState { if (res is String) { try { - var productMap = - await widget.apiClient.getProductByBarcode(res); + var productMap = await widget.apiClient.getProductByBarcode(res); var product = Product.fromJson(productMap); diff --git a/lib/screens/add_product.dart b/lib/screens/add_product.dart index 2468615..9eb46fa 100644 --- a/lib/screens/add_product.dart +++ b/lib/screens/add_product.dart @@ -43,7 +43,8 @@ class _AddProductScreen extends State { ); } - Future _parseDouble(String text, String name, {bool silent = false}) async { + Future _parseDouble(String text, String name, + {bool silent = false}) async { try { return double.parse(text.replaceAll(",", ".")); } catch (e) { @@ -58,7 +59,8 @@ class _AddProductScreen extends State { var carb = await _parseDouble(carbController.text, "Carbs"); var fat = await _parseDouble(fatController.text, "Fat"); var protein = await _parseDouble(proteinController.text, "Protein"); - var fiber = await _parseDouble(fiberController.text, "Fiber", silent: true) ?? 0; + var fiber = + await _parseDouble(fiberController.text, "Fiber", silent: true) ?? 0; if (carb == null || fat == null || protein == null) { return; diff --git a/lib/screens/based.dart b/lib/screens/based.dart index 4aaf874..205a958 100644 --- a/lib/screens/based.dart +++ b/lib/screens/based.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:fooder/client.dart'; -import 'package:fooder/components/appBar.dart'; -import 'package:fooder/components/navigationBar.dart'; +import 'package:fooder/components/app_bar.dart'; +import 'package:fooder/components/navigation_bar.dart'; import 'package:fooder/screens/login.dart'; import 'package:fooder/screens/main.dart'; @@ -69,21 +69,21 @@ abstract class BasedState extends State { Icons.dinner_dining, color: Theme.of(context).colorScheme.onPrimary, ), - onPressed: () => null, + onPressed: () {}, ), IconButton( icon: Icon( Icons.lunch_dining, color: Theme.of(context).colorScheme.onPrimary, ), - onPressed: () => null, + onPressed: () {}, ), IconButton( icon: Icon( Icons.person, color: Theme.of(context).colorScheme.onPrimary, ), - onPressed: () => null, + onPressed: () {}, ), ], ), @@ -98,9 +98,9 @@ abstract class BasedState extends State { message, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyLarge!.copyWith( - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onError, - ), + fontWeight: FontWeight.bold, + color: Theme.of(context).colorScheme.onError, + ), ), backgroundColor: Theme.of(context).colorScheme.error.withOpacity(0.8), ), @@ -114,9 +114,9 @@ abstract class BasedState extends State { text, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyLarge!.copyWith( - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onPrimary, - ), + fontWeight: FontWeight.bold, + color: Theme.of(context).colorScheme.onPrimary, + ), ), backgroundColor: Theme.of(context).colorScheme.primary.withOpacity(0.8), ), diff --git a/lib/screens/edit_entry.dart b/lib/screens/edit_entry.dart index 65c8e51..d35ec74 100644 --- a/lib/screens/edit_entry.dart +++ b/lib/screens/edit_entry.dart @@ -106,8 +106,7 @@ class _EditEntryScreen extends State { if (res is String) { try { - var productMap = - await widget.apiClient.getProductByBarcode(res); + var productMap = await widget.apiClient.getProductByBarcode(res); var product = Product.fromJson(productMap); diff --git a/lib/screens/main.dart b/lib/screens/main.dart index f169034..ffbf32e 100644 --- a/lib/screens/main.dart +++ b/lib/screens/main.dart @@ -1,14 +1,11 @@ import 'package:flutter/material.dart'; import 'package:fooder/screens/based.dart'; import 'package:fooder/screens/add_entry.dart'; -import 'package:fooder/screens/add_meal.dart'; import 'package:fooder/models/diary.dart'; -import 'package:fooder/widgets/diary.dart'; import 'package:fooder/widgets/summary.dart'; import 'package:fooder/widgets/meal.dart'; -import 'package:fooder/widgets/macroEntry.dart'; import 'package:fooder/components/sliver.dart'; -import 'package:fooder/components/datePicker.dart'; +import 'package:fooder/components/date_picker.dart'; import 'package:blur/blur.dart'; class MainScreen extends BasedScreen { @@ -60,54 +57,54 @@ class _MainScreen extends BasedState { var colorScheme = theme.colorScheme; return Container( - height: 64, - width: 64, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(32), - boxShadow: [ - BoxShadow( - color: colorScheme.primary.withOpacity(0.3), - blurRadius: 5, - offset: const Offset(0, 5), - ) - ], - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(32), - child: Stack( - children: [ - Blur( - blur: 10, - blurColor: colorScheme.primary.withOpacity(0.1), - child: Container( - height: 64, - width: 64, - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - colorScheme.primary.withOpacity(0.1), - colorScheme.secondary.withOpacity(0.1), - ], - ), - ), - ), - ), - Container( + height: 64, + width: 64, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(32), + boxShadow: [ + BoxShadow( + color: colorScheme.primary.withOpacity(0.3), + blurRadius: 5, + offset: const Offset(0, 5), + ) + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(32), + child: Stack( + children: [ + Blur( + blur: 10, + blurColor: colorScheme.primary.withOpacity(0.1), + child: Container( height: 64, width: 64, - child: FloatingActionButton( - elevation: 0, - onPressed: _addEntry, - backgroundColor: Colors.transparent, - child: Icon( - Icons.library_add, - color: colorScheme.onPrimary, + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + colorScheme.primary.withOpacity(0.1), + colorScheme.secondary.withOpacity(0.1), + ], ), ), ), - ], - ), + ), + SizedBox( + height: 64, + width: 64, + child: FloatingActionButton( + elevation: 0, + onPressed: _addEntry, + backgroundColor: Colors.transparent, + child: Icon( + Icons.library_add, + color: colorScheme.onPrimary, + ), + ), + ), + ], ), + ), ); } @@ -116,37 +113,35 @@ class _MainScreen extends BasedState { Widget content; if (diary != null) { - content = CustomScrollView( - slivers: [ - SliverPersistentHeader( - delegate: FSliverAppBar(child: FDatePickerWidget(date: date, onDatePicked: _pickDate)), - pinned: true, - ), - SliverList( - delegate: SliverChildListDelegate( - [ - SummaryWidget( - diary: diary!, + content = CustomScrollView(slivers: [ + SliverPersistentHeader( + delegate: FSliverAppBar( + child: FDatePickerWidget(date: date, onDatePicked: _pickDate)), + pinned: true, + ), + SliverList( + delegate: SliverChildListDelegate( + [ + SummaryWidget( + diary: diary!, + apiClient: widget.apiClient, + refreshParent: _asyncInitState, + ), + for (var (i, meal) in diary!.meals.indexed) + MealWidget( + meal: meal, apiClient: widget.apiClient, refreshParent: _asyncInitState, + initiallyExpanded: i == 0, ), - for (var (i, meal) in diary!.meals.indexed) - MealWidget( - meal: meal, - apiClient: widget.apiClient, - refreshParent: _asyncInitState, - initiallyExpanded: i == 0, - ), - ], - ), + ], ), - ] - ); + ), + ]); } else { - content = const Center(child: const CircularProgressIndicator()); + content = const Center(child: CircularProgressIndicator()); } - return Scaffold( body: content, extendBodyBehindAppBar: true, diff --git a/lib/screens/meal.dart b/lib/screens/meal.dart index 76a58ca..48defcb 100644 --- a/lib/screens/meal.dart +++ b/lib/screens/meal.dart @@ -7,7 +7,11 @@ class MealScreen extends BasedScreen { final Meal meal; final Function() refresh; - const MealScreen({super.key, required super.apiClient, required this.refresh, required this.meal}); + const MealScreen( + {super.key, + required super.apiClient, + required this.refresh, + required this.meal}); @override State createState() => _AddMealScreen(); diff --git a/lib/widgets/entry.dart b/lib/widgets/entry.dart index 89fed66..c73552e 100644 --- a/lib/widgets/entry.dart +++ b/lib/widgets/entry.dart @@ -3,13 +3,10 @@ import 'package:fooder/models/entry.dart'; import 'package:fooder/widgets/macroEntry.dart'; import 'dart:core'; - class EntryHeader extends StatelessWidget { final Entry entry; - const EntryHeader( - {super.key, - required this.entry}); + const EntryHeader({super.key, required this.entry}); @override Widget build(BuildContext context) { @@ -20,19 +17,19 @@ class EntryHeader extends StatelessWidget { child: Text( entry.product.name, style: Theme.of(context).textTheme.bodyLarge!.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - fontWeight: FontWeight.bold, - ), + color: Theme.of(context).colorScheme.onPrimary, + fontWeight: FontWeight.bold, + ), ), ), - Spacer(), + const Spacer(), Padding( padding: const EdgeInsets.all(8), child: Text( - entry.grams.toStringAsFixed(0) + " g", - style: Theme.of(context).textTheme.bodyText2!.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - ), + "${entry.grams.toStringAsFixed(0)} g", + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: Theme.of(context).colorScheme.onPrimary, + ), ), ), ], diff --git a/lib/widgets/macro.dart b/lib/widgets/macro.dart index f33a048..d4f7b2c 100644 --- a/lib/widgets/macro.dart +++ b/lib/widgets/macro.dart @@ -11,7 +11,7 @@ class MacroWidget extends StatelessWidget { final Widget? child; const MacroWidget({ - Key? key, + super.key, this.calories, this.amount, this.child, @@ -20,7 +20,7 @@ class MacroWidget extends StatelessWidget { required this.carb, required this.fat, required this.style, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/widgets/macroEntry.dart b/lib/widgets/macroEntry.dart index 2aeaadd..0838350 100644 --- a/lib/widgets/macroEntry.dart +++ b/lib/widgets/macroEntry.dart @@ -1,22 +1,18 @@ import 'package:flutter/material.dart'; import 'dart:core'; - class MacroHeaderWidget extends StatelessWidget { - static final double PAD_Y = 4; - static final double PAD_X = 8; + static const double PAD_Y = 4; + static const double PAD_X = 8; final bool? fiber; final bool? calories; - const MacroHeaderWidget( - { - super.key, - this.fiber = false, - this.calories = false, - } - ); - + const MacroHeaderWidget({ + super.key, + this.fiber = false, + this.calories = false, + }); @override Widget build(BuildContext context) { @@ -43,16 +39,16 @@ class MacroHeaderWidget extends StatelessWidget { for (var element in elements) { children.add( Padding( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( horizontal: 2, ), child: SizedBox( width: 55, child: Text( element, - style: Theme.of(context).textTheme.bodyText1!.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - ), + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + color: Theme.of(context).colorScheme.onPrimary, + ), textAlign: TextAlign.center, ), ), @@ -60,10 +56,10 @@ class MacroHeaderWidget extends StatelessWidget { ); } - children.add(Spacer()); + children.add(const Spacer()); return Padding( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( vertical: PAD_Y, horizontal: PAD_X, ), @@ -75,10 +71,9 @@ class MacroHeaderWidget extends StatelessWidget { } } - class MacroEntryWidget extends StatelessWidget { - static final double PAD_Y = 4; - static final double PAD_X = 8; + static const double PAD_Y = 4; + static const double PAD_X = 8; final double protein; final double carb; @@ -86,35 +81,32 @@ class MacroEntryWidget extends StatelessWidget { final double? fiber; final double? calories; - const MacroEntryWidget( - { - super.key, - required this.protein, - required this.carb, - required this.fat, - this.fiber, - this.calories, - } - ); - + const MacroEntryWidget({ + super.key, + required this.protein, + required this.carb, + required this.fat, + this.fiber, + this.calories, + }); @override Widget build(BuildContext context) { var elements = [ - "${carb.toStringAsFixed(1)}", - "${fat.toStringAsFixed(1)}", - "${protein.toStringAsFixed(1)}", + (carb.toStringAsFixed(1)), + (fat.toStringAsFixed(1)), + (protein.toStringAsFixed(1)), ]; if (fiber != null) { elements.add( - "${fiber!.toStringAsFixed(1)}", + fiber!.toStringAsFixed(1), ); } if (calories != null) { elements.add( - "${calories!.toStringAsFixed(0)}", + calories!.toStringAsFixed(0), ); } @@ -123,16 +115,16 @@ class MacroEntryWidget extends StatelessWidget { for (var element in elements) { children.add( Padding( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( horizontal: 2, ), child: SizedBox( width: 55, child: Text( element, - style: Theme.of(context).textTheme.bodyText1!.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - ), + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + color: Theme.of(context).colorScheme.onPrimary, + ), textAlign: TextAlign.center, ), ), @@ -140,10 +132,10 @@ class MacroEntryWidget extends StatelessWidget { ); } - children.add(Spacer()); + children.add(const Spacer()); return Padding( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( vertical: PAD_Y, horizontal: PAD_X, ), diff --git a/lib/widgets/meal.dart b/lib/widgets/meal.dart index e9156dc..09d2bde 100644 --- a/lib/widgets/meal.dart +++ b/lib/widgets/meal.dart @@ -7,13 +7,10 @@ import 'package:fooder/screens/meal.dart'; import 'package:fooder/client.dart'; import 'dart:core'; - class MealHeader extends StatelessWidget { final Meal meal; - const MealHeader( - {super.key, - required this.meal}); + const MealHeader({super.key, required this.meal}); @override Widget build(BuildContext context) { @@ -24,9 +21,9 @@ class MealHeader extends StatelessWidget { child: Text( meal.name, style: Theme.of(context).textTheme.headlineSmall!.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - fontWeight: FontWeight.bold, - ), + color: Theme.of(context).colorScheme.onPrimary, + fontWeight: FontWeight.bold, + ), ), ), ], @@ -34,24 +31,21 @@ class MealHeader extends StatelessWidget { } } - class MealWidget extends StatelessWidget { - static final MAX_WIDTH = 920.0; + static const maxWidth = 920.0; final Meal meal; final ApiClient apiClient; final Function() refreshParent; final bool initiallyExpanded; - const MealWidget( - { - super.key, - required this.meal, - required this.apiClient, - required this.refreshParent, - required this.initiallyExpanded, - } - ); + const MealWidget({ + super.key, + required this.meal, + required this.apiClient, + required this.refreshParent, + required this.initiallyExpanded, + }); Future _editMeal(context) async { await Navigator.push( @@ -83,8 +77,8 @@ class MealWidget extends StatelessWidget { var theme = Theme.of(context); var colorScheme = theme.colorScheme; - var width_avail = MediaQuery.of(context).size.width; - var width = width_avail > MAX_WIDTH ? MAX_WIDTH : width_avail; + var widthAvail = MediaQuery.of(context).size.width; + var width = widthAvail > maxWidth ? maxWidth : widthAvail; return Center( child: Padding( @@ -119,7 +113,7 @@ class MealWidget extends StatelessWidget { child: Column( children: [ MealHeader(meal: meal), - MacroHeaderWidget( + const MacroHeaderWidget( calories: true, ), MacroEntryWidget( @@ -137,7 +131,9 @@ class MealWidget extends StatelessWidget { title: EntryWidget( entry: entry, ), - tileColor: i % 2 == 0 ? colorScheme.secondary.withOpacity(0.1): Colors.transparent, + tileColor: i % 2 == 0 + ? colorScheme.secondary.withOpacity(0.1) + : Colors.transparent, onTap: () => _editEntry(context, entry), ) ], diff --git a/lib/widgets/summary.dart b/lib/widgets/summary.dart index d28bd46..a0354df 100644 --- a/lib/widgets/summary.dart +++ b/lib/widgets/summary.dart @@ -5,15 +5,11 @@ import 'package:fooder/screens/add_meal.dart'; import 'package:fooder/client.dart'; import 'dart:core'; - class SummaryHeader extends StatelessWidget { final Diary diary; final Function addMeal; - const SummaryHeader( - {super.key, - required this.addMeal, - required this.diary}); + const SummaryHeader({super.key, required this.addMeal, required this.diary}); @override Widget build(BuildContext context) { @@ -24,16 +20,16 @@ class SummaryHeader extends StatelessWidget { child: Text( "Summary", style: Theme.of(context).textTheme.headlineSmall!.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - fontWeight: FontWeight.bold, - ), + color: Theme.of(context).colorScheme.onPrimary, + fontWeight: FontWeight.bold, + ), ), ), - Spacer(), + const Spacer(), Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: IconButton( - icon: Icon(Icons.playlist_add_rounded), + icon: const Icon(Icons.playlist_add_rounded), iconSize: 32, color: Theme.of(context).colorScheme.onPrimary, onPressed: () => addMeal(context), @@ -44,9 +40,8 @@ class SummaryHeader extends StatelessWidget { } } - class SummaryWidget extends StatelessWidget { - static final MAX_WIDTH = 920.0; + static const maxWidth = 920.0; final Diary diary; final ApiClient apiClient; @@ -75,8 +70,8 @@ class SummaryWidget extends StatelessWidget { var theme = Theme.of(context); var colorScheme = theme.colorScheme; - var width_avail = MediaQuery.of(context).size.width; - var width = width_avail > MAX_WIDTH ? MAX_WIDTH : width_avail; + var widthAvail = MediaQuery.of(context).size.width; + var width = widthAvail > maxWidth ? maxWidth : widthAvail; return Center( child: Padding( @@ -100,11 +95,12 @@ class SummaryWidget extends StatelessWidget { ), ), child: Padding( - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 24), + padding: + const EdgeInsets.symmetric(vertical: 12, horizontal: 24), child: Column( children: [ SummaryHeader(diary: diary, addMeal: _addMeal), - MacroHeaderWidget( + const MacroHeaderWidget( calories: true, ), MacroEntryWidget( diff --git a/pubspec.lock b/pubspec.lock index f003e88..c5951b6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -65,6 +65,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.6" + fading_edge_scrollview: + dependency: transitive + description: + name: fading_edge_scrollview + sha256: c25c2231652ce774cc31824d0112f11f653881f43d7f5302c05af11942052031 + url: "https://pub.dev" + source: hosted + version: "3.0.0" fake_async: dependency: transitive description: @@ -114,10 +122,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7 + sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -256,6 +264,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" + marquee: + dependency: "direct main" + description: + name: marquee + sha256: "4b5243d2804373bdc25fc93d42c3b402d6ec1f4ee8d0bb72276edd04ae7addb8" + url: "https://pub.dev" + source: hosted + version: "2.2.3" matcher: dependency: transitive description: @@ -340,10 +356,10 @@ packages: dependency: transitive description: name: permission_handler - sha256: "74e962b7fad7ff75959161bb2c0ad8fe7f2568ee82621c9c2660b751146bfe44" + sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb" url: "https://pub.dev" source: hosted - version: "11.3.0" + version: "11.3.1" permission_handler_android: dependency: transitive description: @@ -356,10 +372,10 @@ packages: dependency: transitive description: name: permission_handler_apple - sha256: "92861b0f0c2443dd8898398c2baa4f1ae925109b5909ae4a17d0108a6a788932" + sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662 url: "https://pub.dev" source: hosted - version: "9.4.2" + version: "9.4.4" permission_handler_html: dependency: transitive description: @@ -372,10 +388,10 @@ packages: dependency: transitive description: name: permission_handler_platform_interface - sha256: "23dfba8447c076ab5be3dee9ceb66aad345c4a648f0cac292c77b1eb0e800b78" + sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20" url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "4.2.1" permission_handler_windows: dependency: transitive description: @@ -505,10 +521,10 @@ packages: dependency: transitive description: name: win32 - sha256: "8cb58b45c47dcb42ab3651533626161d6b67a2921917d8d429791f76972b3480" + sha256: "0a989dc7ca2bb51eac91e8fd00851297cfffd641aa7538b165c62637ca0eaa4a" url: "https://pub.dev" source: hosted - version: "5.3.0" + version: "5.4.0" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 64e6a1a..601474b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,6 +42,7 @@ dependencies: google_fonts: ^6.2.1 flex_color_scheme: ^7.3.1 blur: ^3.1.0 + marquee: ^2.2.3 dev_dependencies: flutter_test: