[UI craze] linted
This commit is contained in:
parent
66b88f64fe
commit
ac803d3e71
22 changed files with 380 additions and 349 deletions
|
@ -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<Map<String, dynamic>> 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<void> addMeal(
|
||||
{required String name, required int diaryId}) async {
|
||||
Future<void> addMeal({required String name, required int diaryId}) async {
|
||||
await post("/meal", {
|
||||
"name": name,
|
||||
"diary_id": diaryId,
|
||||
|
@ -292,7 +291,9 @@ class ApiClient {
|
|||
}
|
||||
|
||||
Future<void> 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,
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class FAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
final List<Widget> 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);
|
||||
}
|
21
lib/components/app_bar.dart
Normal file
21
lib/components/app_bar.dart
Normal file
|
@ -0,0 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class FAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
final List<Widget> 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);
|
||||
}
|
|
@ -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) {
|
||||
|
@ -39,14 +45,13 @@ class FButton extends StatelessWidget {
|
|||
child: Center(
|
||||
child: Text(
|
||||
labelText,
|
||||
style: theme.textTheme.button!.copyWith(
|
||||
style: theme.textTheme.labelLarge!.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: fontSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<FDatePickerWidget> createState() => _FDatePickerWidgetState();
|
||||
|
@ -106,13 +112,18 @@ class _FDatePickerWidgetState extends State<FDatePickerWidget> {
|
|||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
shrinkWrap: true,
|
||||
children: <Widget>[
|
||||
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<FDatePickerWidget> {
|
|||
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);
|
|
@ -1,64 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:blur/blur.dart';
|
||||
|
||||
class FNavBar extends StatelessWidget {
|
||||
final List<Widget> 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,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
68
lib/components/navigation_bar.dart
Normal file
68
lib/components/navigation_bar.dart
Normal file
|
@ -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<Widget> 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,
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:blur/blur.dart';
|
||||
|
||||
|
||||
class ClipShadowPath extends StatelessWidget {
|
||||
final Shadow shadow;
|
||||
final CustomClipper<Path> 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<Path> {
|
|||
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,
|
||||
)
|
||||
],
|
||||
);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<AddEntryScreen> {
|
|||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void showError(String message) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
|
@ -99,7 +98,6 @@ class _AddEntryScreen extends BasedState<AddEntryScreen> {
|
|||
popMeDaddy();
|
||||
}
|
||||
|
||||
|
||||
Future<void> _findProductByBarCode() async {
|
||||
var res = await Navigator.push(
|
||||
context,
|
||||
|
@ -110,8 +108,7 @@ class _AddEntryScreen extends BasedState<AddEntryScreen> {
|
|||
|
||||
if (res is String) {
|
||||
try {
|
||||
var productMap =
|
||||
await widget.apiClient.getProductByBarcode(res);
|
||||
var productMap = await widget.apiClient.getProductByBarcode(res);
|
||||
|
||||
var product = Product.fromJson(productMap);
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ class _AddProductScreen extends State<AddProductScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
Future<double?> _parseDouble(String text, String name, {bool silent = false}) async {
|
||||
Future<double?> _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<AddProductScreen> {
|
|||
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;
|
||||
|
|
|
@ -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<T extends BasedScreen> extends State<T> {
|
|||
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: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -106,8 +106,7 @@ class _EditEntryScreen extends State<EditEntryScreen> {
|
|||
|
||||
if (res is String) {
|
||||
try {
|
||||
var productMap =
|
||||
await widget.apiClient.getProductByBarcode(res);
|
||||
var productMap = await widget.apiClient.getProductByBarcode(res);
|
||||
|
||||
var product = Product.fromJson(productMap);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
@ -92,7 +89,7 @@ class _MainScreen extends BasedState<MainScreen> {
|
|||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
SizedBox(
|
||||
height: 64,
|
||||
width: 64,
|
||||
child: FloatingActionButton(
|
||||
|
@ -116,10 +113,10 @@ class _MainScreen extends BasedState<MainScreen> {
|
|||
Widget content;
|
||||
|
||||
if (diary != null) {
|
||||
content = CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
content = CustomScrollView(slivers: <Widget>[
|
||||
SliverPersistentHeader(
|
||||
delegate: FSliverAppBar(child: FDatePickerWidget(date: date, onDatePicked: _pickDate)),
|
||||
delegate: FSliverAppBar(
|
||||
child: FDatePickerWidget(date: date, onDatePicked: _pickDate)),
|
||||
pinned: true,
|
||||
),
|
||||
SliverList(
|
||||
|
@ -140,13 +137,11 @@ class _MainScreen extends BasedState<MainScreen> {
|
|||
],
|
||||
),
|
||||
),
|
||||
]
|
||||
);
|
||||
]);
|
||||
} else {
|
||||
content = const Center(child: const CircularProgressIndicator());
|
||||
content = const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
|
||||
return Scaffold(
|
||||
body: content,
|
||||
extendBodyBehindAppBar: true,
|
||||
|
|
|
@ -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<MealScreen> createState() => _AddMealScreen();
|
||||
|
|
|
@ -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) {
|
||||
|
@ -25,12 +22,12 @@ class EntryHeader extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
const Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Text(
|
||||
entry.grams.toStringAsFixed(0) + " g",
|
||||
style: Theme.of(context).textTheme.bodyText2!.copyWith(
|
||||
"${entry.grams.toStringAsFixed(0)} g",
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(
|
||||
{
|
||||
const MacroHeaderWidget({
|
||||
super.key,
|
||||
this.fiber = false,
|
||||
this.calories = false,
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -43,14 +39,14 @@ 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(
|
||||
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(
|
||||
{
|
||||
const MacroEntryWidget({
|
||||
super.key,
|
||||
required this.protein,
|
||||
required this.carb,
|
||||
required this.fat,
|
||||
this.fiber,
|
||||
this.calories,
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var elements = <String>[
|
||||
"${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,14 +115,14 @@ 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(
|
||||
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,
|
||||
),
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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(
|
||||
{
|
||||
const MealWidget({
|
||||
super.key,
|
||||
required this.meal,
|
||||
required this.apiClient,
|
||||
required this.refreshParent,
|
||||
required this.initiallyExpanded,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
Future<void> _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: <Widget>[
|
||||
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),
|
||||
)
|
||||
],
|
||||
|
|
|
@ -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) {
|
||||
|
@ -29,11 +25,11 @@ class SummaryHeader extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
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: <Widget>[
|
||||
SummaryHeader(diary: diary, addMeal: _addMeal),
|
||||
MacroHeaderWidget(
|
||||
const MacroHeaderWidget(
|
||||
calories: true,
|
||||
),
|
||||
MacroEntryWidget(
|
||||
|
|
36
pubspec.lock
36
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:
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue