[format]
This commit is contained in:
		
							parent
							
								
									6d7613c5ff
								
							
						
					
					
						commit
						072ef2f963
					
				
					 19 changed files with 285 additions and 283 deletions
				
			
		| 
						 | 
					@ -3,7 +3,6 @@ import 'dart:convert';
 | 
				
			||||||
import 'dart:html';
 | 
					import 'dart:html';
 | 
				
			||||||
import 'package:intl/intl.dart';
 | 
					import 'package:intl/intl.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class ApiClient {
 | 
					class ApiClient {
 | 
				
			||||||
  final String baseUrl;
 | 
					  final String baseUrl;
 | 
				
			||||||
  String? token;
 | 
					  String? token;
 | 
				
			||||||
| 
						 | 
					@ -67,7 +66,8 @@ class ApiClient {
 | 
				
			||||||
    return _jsonDecode(response);
 | 
					    return _jsonDecode(response);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<Map<String, dynamic>> post(String path, Map<String, dynamic> body, {bool forLogin = false}) async {
 | 
					  Future<Map<String, dynamic>> post(String path, Map<String, dynamic> body,
 | 
				
			||||||
 | 
					      {bool forLogin = false}) async {
 | 
				
			||||||
    final response = await httpClient.post(
 | 
					    final response = await httpClient.post(
 | 
				
			||||||
      Uri.parse('$baseUrl$path'),
 | 
					      Uri.parse('$baseUrl$path'),
 | 
				
			||||||
      body: jsonEncode(body),
 | 
					      body: jsonEncode(body),
 | 
				
			||||||
| 
						 | 
					@ -86,7 +86,6 @@ class ApiClient {
 | 
				
			||||||
    return _jsonDecode(response);
 | 
					    return _jsonDecode(response);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  Future<void> delete(String path) async {
 | 
					  Future<void> delete(String path) async {
 | 
				
			||||||
    final response = await httpClient.delete(
 | 
					    final response = await httpClient.delete(
 | 
				
			||||||
      Uri.parse('$baseUrl$path'),
 | 
					      Uri.parse('$baseUrl$path'),
 | 
				
			||||||
| 
						 | 
					@ -103,7 +102,8 @@ class ApiClient {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<Map<String, dynamic>> patch(String path, Map<String, dynamic> body) async {
 | 
					  Future<Map<String, dynamic>> patch(
 | 
				
			||||||
 | 
					      String path, Map<String, dynamic> body) async {
 | 
				
			||||||
    final response = await httpClient.patch(
 | 
					    final response = await httpClient.patch(
 | 
				
			||||||
      Uri.parse('$baseUrl$path'),
 | 
					      Uri.parse('$baseUrl$path'),
 | 
				
			||||||
      body: jsonEncode(body),
 | 
					      body: jsonEncode(body),
 | 
				
			||||||
| 
						 | 
					@ -155,12 +155,9 @@ class ApiClient {
 | 
				
			||||||
      throw Exception("No valid refresh token found");
 | 
					      throw Exception("No valid refresh token found");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final response = await post(
 | 
					    final response = await post("/token/refresh", {
 | 
				
			||||||
      "/token/refresh",
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
      "refresh_token": refreshToken,
 | 
					      "refresh_token": refreshToken,
 | 
				
			||||||
      }
 | 
					    });
 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    token = response['access_token'] as String;
 | 
					    token = response['access_token'] as String;
 | 
				
			||||||
    window.localStorage['token'] = token!;
 | 
					    window.localStorage['token'] = token!;
 | 
				
			||||||
| 
						 | 
					@ -185,7 +182,8 @@ class ApiClient {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<Map<String, dynamic>> getProducts(String q) async {
 | 
					  Future<Map<String, dynamic>> getProducts(String q) async {
 | 
				
			||||||
    var response = await get("/product?${Uri(queryParameters: {"q": q}).query}");
 | 
					    var response =
 | 
				
			||||||
 | 
					        await get("/product?${Uri(queryParameters: {"q": q}).query}");
 | 
				
			||||||
    return response;
 | 
					    return response;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -193,8 +191,7 @@ class ApiClient {
 | 
				
			||||||
    required double grams,
 | 
					    required double grams,
 | 
				
			||||||
    required int productId,
 | 
					    required int productId,
 | 
				
			||||||
    required int mealId,
 | 
					    required int mealId,
 | 
				
			||||||
  }
 | 
					  }) async {
 | 
				
			||||||
  ) async {
 | 
					 | 
				
			||||||
    var entry = {
 | 
					    var entry = {
 | 
				
			||||||
      "grams": grams,
 | 
					      "grams": grams,
 | 
				
			||||||
      "product_id": productId,
 | 
					      "product_id": productId,
 | 
				
			||||||
| 
						 | 
					@ -207,12 +204,12 @@ class ApiClient {
 | 
				
			||||||
    await delete("/entry/$id");
 | 
					    await delete("/entry/$id");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> updateEntry(int id, {
 | 
					  Future<void> updateEntry(
 | 
				
			||||||
 | 
					    int id, {
 | 
				
			||||||
    required double grams,
 | 
					    required double grams,
 | 
				
			||||||
    required int productId,
 | 
					    required int productId,
 | 
				
			||||||
    required int mealId,
 | 
					    required int mealId,
 | 
				
			||||||
  }
 | 
					  }) async {
 | 
				
			||||||
  ) async {
 | 
					 | 
				
			||||||
    var entry = {
 | 
					    var entry = {
 | 
				
			||||||
      "grams": grams,
 | 
					      "grams": grams,
 | 
				
			||||||
      "product_id": productId,
 | 
					      "product_id": productId,
 | 
				
			||||||
| 
						 | 
					@ -223,7 +220,9 @@ class ApiClient {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> register(String username, String password) async {
 | 
					  Future<void> register(String username, String password) async {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      await post("/user", {
 | 
					      await post(
 | 
				
			||||||
 | 
					        "/user",
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
          "username": username,
 | 
					          "username": username,
 | 
				
			||||||
          "password": password,
 | 
					          "password": password,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
| 
						 | 
					@ -234,7 +233,8 @@ class ApiClient {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> addMeal({required String name, required int diaryId, required int order}) async {
 | 
					  Future<void> addMeal(
 | 
				
			||||||
 | 
					      {required String name, required int diaryId, required int order}) async {
 | 
				
			||||||
    await post("/meal", {
 | 
					    await post("/meal", {
 | 
				
			||||||
      "name": name,
 | 
					      "name": name,
 | 
				
			||||||
      "diary_id": diaryId,
 | 
					      "diary_id": diaryId,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:fooder/screens/login.dart';
 | 
					import 'package:fooder/screens/login.dart';
 | 
				
			||||||
import 'package:fooder/client.dart';
 | 
					import 'package:fooder/client.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class MyApp extends StatelessWidget {
 | 
					class MyApp extends StatelessWidget {
 | 
				
			||||||
  const MyApp({super.key});
 | 
					  const MyApp({super.key});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +25,6 @@ class MyApp extends StatelessWidget {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void main() {
 | 
					void main() {
 | 
				
			||||||
  runApp(const MyApp());
 | 
					  runApp(const MyApp());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import 'package:fooder/models/meal.dart';
 | 
					import 'package:fooder/models/meal.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class Diary {
 | 
					class Diary {
 | 
				
			||||||
  final int id;
 | 
					  final int id;
 | 
				
			||||||
  final DateTime date;
 | 
					  final DateTime date;
 | 
				
			||||||
| 
						 | 
					@ -22,10 +21,12 @@ class Diary {
 | 
				
			||||||
    required this.fiber,
 | 
					    required this.fiber,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Diary.fromJson(Map<String, dynamic> map):
 | 
					  Diary.fromJson(Map<String, dynamic> map)
 | 
				
			||||||
    id = map['id'] as int,
 | 
					      : id = map['id'] as int,
 | 
				
			||||||
        date = DateTime.parse(map['date']),
 | 
					        date = DateTime.parse(map['date']),
 | 
				
			||||||
    meals = (map['meals'] as List<dynamic>).map((e) => Meal.fromJson(e as Map<String, dynamic>)).toList(),
 | 
					        meals = (map['meals'] as List<dynamic>)
 | 
				
			||||||
 | 
					            .map((e) => Meal.fromJson(e as Map<String, dynamic>))
 | 
				
			||||||
 | 
					            .toList(),
 | 
				
			||||||
        calories = map['calories'] as double,
 | 
					        calories = map['calories'] as double,
 | 
				
			||||||
        protein = map['protein'] as double,
 | 
					        protein = map['protein'] as double,
 | 
				
			||||||
        carb = map['carb'] as double,
 | 
					        carb = map['carb'] as double,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,6 @@ class Entry {
 | 
				
			||||||
  final double fiber;
 | 
					  final double fiber;
 | 
				
			||||||
  final double carb;
 | 
					  final double carb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  Entry({
 | 
					  Entry({
 | 
				
			||||||
    required this.id,
 | 
					    required this.id,
 | 
				
			||||||
    required this.grams,
 | 
					    required this.grams,
 | 
				
			||||||
| 
						 | 
					@ -24,8 +23,8 @@ class Entry {
 | 
				
			||||||
    required this.carb,
 | 
					    required this.carb,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Entry.fromJson(Map<String, dynamic> map):
 | 
					  Entry.fromJson(Map<String, dynamic> map)
 | 
				
			||||||
    id = map['id'] as int,
 | 
					      : id = map['id'] as int,
 | 
				
			||||||
        grams = map['grams'] as double,
 | 
					        grams = map['grams'] as double,
 | 
				
			||||||
        product = Product.fromJson(map['product'] as Map<String, dynamic>),
 | 
					        product = Product.fromJson(map['product'] as Map<String, dynamic>),
 | 
				
			||||||
        mealId = map['meal_id'] as int,
 | 
					        mealId = map['meal_id'] as int,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import 'package:fooder/models/entry.dart';
 | 
					import 'package:fooder/models/entry.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class Meal {
 | 
					class Meal {
 | 
				
			||||||
  final List<Entry> entries;
 | 
					  final List<Entry> entries;
 | 
				
			||||||
  final int id;
 | 
					  final int id;
 | 
				
			||||||
| 
						 | 
					@ -26,8 +25,10 @@ class Meal {
 | 
				
			||||||
    required this.diaryId,
 | 
					    required this.diaryId,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Meal.fromJson(Map<String, dynamic> map):
 | 
					  Meal.fromJson(Map<String, dynamic> map)
 | 
				
			||||||
    entries = (map['entries'] as List<dynamic>).map((e) => Entry.fromJson(e as Map<String, dynamic>)).toList(),
 | 
					      : entries = (map['entries'] as List<dynamic>)
 | 
				
			||||||
 | 
					            .map((e) => Entry.fromJson(e as Map<String, dynamic>))
 | 
				
			||||||
 | 
					            .toList(),
 | 
				
			||||||
        id = map['id'] as int,
 | 
					        id = map['id'] as int,
 | 
				
			||||||
        name = map['name'] as String,
 | 
					        name = map['name'] as String,
 | 
				
			||||||
        order = map['order'] as int,
 | 
					        order = map['order'] as int,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,8 +17,8 @@ class Product {
 | 
				
			||||||
    required this.fiber,
 | 
					    required this.fiber,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Product.fromJson(Map<String, dynamic> map):
 | 
					  Product.fromJson(Map<String, dynamic> map)
 | 
				
			||||||
    id = map['id'] as int,
 | 
					      : id = map['id'] as int,
 | 
				
			||||||
        name = map['name'] as String,
 | 
					        name = map['name'] as String,
 | 
				
			||||||
        calories = map['calories'] as double,
 | 
					        calories = map['calories'] as double,
 | 
				
			||||||
        protein = map['protein'] as double,
 | 
					        protein = map['protein'] as double,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,17 +7,16 @@ import 'package:fooder/models/meal.dart';
 | 
				
			||||||
import 'package:fooder/widgets/product.dart';
 | 
					import 'package:fooder/widgets/product.dart';
 | 
				
			||||||
import 'package:fooder/screens/add_product.dart';
 | 
					import 'package:fooder/screens/add_product.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class AddEntryScreen extends BasedScreen {
 | 
					class AddEntryScreen extends BasedScreen {
 | 
				
			||||||
  final Diary diary;
 | 
					  final Diary diary;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const AddEntryScreen({super.key, required super.apiClient, required this.diary});
 | 
					  const AddEntryScreen(
 | 
				
			||||||
 | 
					      {super.key, required super.apiClient, required this.diary});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  State<AddEntryScreen> createState() => _AddEntryScreen();
 | 
					  State<AddEntryScreen> createState() => _AddEntryScreen();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class _AddEntryScreen extends State<AddEntryScreen> {
 | 
					class _AddEntryScreen extends State<AddEntryScreen> {
 | 
				
			||||||
  final gramsController = TextEditingController();
 | 
					  final gramsController = TextEditingController();
 | 
				
			||||||
  final productNameController = TextEditingController();
 | 
					  final productNameController = TextEditingController();
 | 
				
			||||||
| 
						 | 
					@ -38,7 +37,7 @@ class _AddEntryScreen extends State<AddEntryScreen> {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState () {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
    setState(() {
 | 
					    setState(() {
 | 
				
			||||||
      meal = widget.diary.meals[0];
 | 
					      meal = widget.diary.meals[0];
 | 
				
			||||||
| 
						 | 
					@ -47,14 +46,16 @@ class _AddEntryScreen extends State<AddEntryScreen> {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> _getProducts() async {
 | 
					  Future<void> _getProducts() async {
 | 
				
			||||||
    var productsMap = await widget.apiClient.getProducts(productNameController.text);
 | 
					    var productsMap =
 | 
				
			||||||
 | 
					        await widget.apiClient.getProducts(productNameController.text);
 | 
				
			||||||
    setState(() {
 | 
					    setState(() {
 | 
				
			||||||
      products = (productsMap['products'] as List<dynamic>).map((e) => Product.fromJson(e as Map<String, dynamic>)).toList();
 | 
					      products = (productsMap['products'] as List<dynamic>)
 | 
				
			||||||
 | 
					          .map((e) => Product.fromJson(e as Map<String, dynamic>))
 | 
				
			||||||
 | 
					          .toList();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void showError(String message)
 | 
					  void showError(String message) {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    ScaffoldMessenger.of(context).showSnackBar(
 | 
					    ScaffoldMessenger.of(context).showSnackBar(
 | 
				
			||||||
      SnackBar(
 | 
					      SnackBar(
 | 
				
			||||||
        content: Text(message, textAlign: TextAlign.center),
 | 
					        content: Text(message, textAlign: TextAlign.center),
 | 
				
			||||||
| 
						 | 
					@ -106,8 +107,7 @@ class _AddEntryScreen extends State<AddEntryScreen> {
 | 
				
			||||||
        child: Container(
 | 
					        child: Container(
 | 
				
			||||||
            constraints: const BoxConstraints(maxWidth: 720),
 | 
					            constraints: const BoxConstraints(maxWidth: 720),
 | 
				
			||||||
            padding: const EdgeInsets.all(10),
 | 
					            padding: const EdgeInsets.all(10),
 | 
				
			||||||
          child: ListView(
 | 
					            child: ListView(children: <Widget>[
 | 
				
			||||||
            children: <Widget>[
 | 
					 | 
				
			||||||
              DropdownButton<Meal>(
 | 
					              DropdownButton<Meal>(
 | 
				
			||||||
                value: meal,
 | 
					                value: meal,
 | 
				
			||||||
                // Callback that sets the selected popup menu item.
 | 
					                // Callback that sets the selected popup menu item.
 | 
				
			||||||
| 
						 | 
					@ -131,9 +131,11 @@ class _AddEntryScreen extends State<AddEntryScreen> {
 | 
				
			||||||
                decoration: const InputDecoration(
 | 
					                decoration: const InputDecoration(
 | 
				
			||||||
                  labelText: 'Grams',
 | 
					                  labelText: 'Grams',
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                keyboardType:const TextInputType.numberWithOptions(decimal: true),
 | 
					                keyboardType:
 | 
				
			||||||
 | 
					                    const TextInputType.numberWithOptions(decimal: true),
 | 
				
			||||||
                inputFormatters: <TextInputFormatter>[
 | 
					                inputFormatters: <TextInputFormatter>[
 | 
				
			||||||
                  FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
					                  FilteringTextInputFormatter.allow(
 | 
				
			||||||
 | 
					                      RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                controller: gramsController,
 | 
					                controller: gramsController,
 | 
				
			||||||
                onFieldSubmitted: (_) => _addEntry(),
 | 
					                onFieldSubmitted: (_) => _addEntry(),
 | 
				
			||||||
| 
						 | 
					@ -181,9 +183,7 @@ class _AddEntryScreen extends State<AddEntryScreen> {
 | 
				
			||||||
                    product: product,
 | 
					                    product: product,
 | 
				
			||||||
                  ),
 | 
					                  ),
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
            ]
 | 
					            ])),
 | 
				
			||||||
          )
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      floatingActionButton: FloatingActionButton(
 | 
					      floatingActionButton: FloatingActionButton(
 | 
				
			||||||
        onPressed: _addEntry,
 | 
					        onPressed: _addEntry,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,22 +2,21 @@ import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:fooder/screens/based.dart';
 | 
					import 'package:fooder/screens/based.dart';
 | 
				
			||||||
import 'package:fooder/models/diary.dart';
 | 
					import 'package:fooder/models/diary.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class AddMealScreen extends BasedScreen {
 | 
					class AddMealScreen extends BasedScreen {
 | 
				
			||||||
  final Diary diary;
 | 
					  final Diary diary;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const AddMealScreen({super.key, required super.apiClient, required this.diary});
 | 
					  const AddMealScreen(
 | 
				
			||||||
 | 
					      {super.key, required super.apiClient, required this.diary});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  State<AddMealScreen> createState() => _AddMealScreen();
 | 
					  State<AddMealScreen> createState() => _AddMealScreen();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class _AddMealScreen extends State<AddMealScreen> {
 | 
					class _AddMealScreen extends State<AddMealScreen> {
 | 
				
			||||||
  final nameController = TextEditingController();
 | 
					  final nameController = TextEditingController();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState () {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
    setState(() {
 | 
					    setState(() {
 | 
				
			||||||
      nameController.text = "Meal ${widget.diary.meals.length}";
 | 
					      nameController.text = "Meal ${widget.diary.meals.length}";
 | 
				
			||||||
| 
						 | 
					@ -36,8 +35,7 @@ class _AddMealScreen extends State<AddMealScreen> {
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void showError(String message)
 | 
					  void showError(String message) {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    ScaffoldMessenger.of(context).showSnackBar(
 | 
					    ScaffoldMessenger.of(context).showSnackBar(
 | 
				
			||||||
      SnackBar(
 | 
					      SnackBar(
 | 
				
			||||||
        content: Text(message, textAlign: TextAlign.center),
 | 
					        content: Text(message, textAlign: TextAlign.center),
 | 
				
			||||||
| 
						 | 
					@ -72,8 +70,7 @@ class _AddMealScreen extends State<AddMealScreen> {
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
          controller: nameController,
 | 
					          controller: nameController,
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
          )
 | 
					      )),
 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      floatingActionButton: FloatingActionButton(
 | 
					      floatingActionButton: FloatingActionButton(
 | 
				
			||||||
        onPressed: _addMeal,
 | 
					        onPressed: _addMeal,
 | 
				
			||||||
        child: const Icon(Icons.add),
 | 
					        child: const Icon(Icons.add),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@ import 'package:flutter/services.dart';
 | 
				
			||||||
import 'package:fooder/screens/based.dart';
 | 
					import 'package:fooder/screens/based.dart';
 | 
				
			||||||
import 'package:fooder/models/product.dart';
 | 
					import 'package:fooder/models/product.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class AddProductScreen extends BasedScreen {
 | 
					class AddProductScreen extends BasedScreen {
 | 
				
			||||||
  const AddProductScreen({super.key, required super.apiClient});
 | 
					  const AddProductScreen({super.key, required super.apiClient});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +10,6 @@ class AddProductScreen extends BasedScreen {
 | 
				
			||||||
  State<AddProductScreen> createState() => _AddProductScreen();
 | 
					  State<AddProductScreen> createState() => _AddProductScreen();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class _AddProductScreen extends State<AddProductScreen> {
 | 
					class _AddProductScreen extends State<AddProductScreen> {
 | 
				
			||||||
  final nameController = TextEditingController();
 | 
					  final nameController = TextEditingController();
 | 
				
			||||||
  final carbController = TextEditingController();
 | 
					  final carbController = TextEditingController();
 | 
				
			||||||
| 
						 | 
					@ -36,8 +34,7 @@ class _AddProductScreen extends State<AddProductScreen> {
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void showError(String message)
 | 
					  void showError(String message) {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    ScaffoldMessenger.of(context).showSnackBar(
 | 
					    ScaffoldMessenger.of(context).showSnackBar(
 | 
				
			||||||
      SnackBar(
 | 
					      SnackBar(
 | 
				
			||||||
        content: Text(message, textAlign: TextAlign.center),
 | 
					        content: Text(message, textAlign: TextAlign.center),
 | 
				
			||||||
| 
						 | 
					@ -76,7 +73,8 @@ class _AddProductScreen extends State<AddProductScreen> {
 | 
				
			||||||
      var product = Product.fromJson(productJson);
 | 
					      var product = Product.fromJson(productJson);
 | 
				
			||||||
      popMeDaddy(product);
 | 
					      popMeDaddy(product);
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
      showError("Error adding product, make sure there is no product with the same name");
 | 
					      showError(
 | 
				
			||||||
 | 
					          "Error adding product, make sure there is no product with the same name");
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -119,8 +117,7 @@ class _AddProductScreen extends State<AddProductScreen> {
 | 
				
			||||||
        child: Container(
 | 
					        child: Container(
 | 
				
			||||||
            constraints: const BoxConstraints(maxWidth: 720),
 | 
					            constraints: const BoxConstraints(maxWidth: 720),
 | 
				
			||||||
            padding: const EdgeInsets.all(10),
 | 
					            padding: const EdgeInsets.all(10),
 | 
				
			||||||
          child: Column(
 | 
					            child: Column(children: <Widget>[
 | 
				
			||||||
            children: <Widget>[
 | 
					 | 
				
			||||||
              TextFormField(
 | 
					              TextFormField(
 | 
				
			||||||
                decoration: const InputDecoration(
 | 
					                decoration: const InputDecoration(
 | 
				
			||||||
                  labelText: 'Product name',
 | 
					                  labelText: 'Product name',
 | 
				
			||||||
| 
						 | 
					@ -131,9 +128,11 @@ class _AddProductScreen extends State<AddProductScreen> {
 | 
				
			||||||
                decoration: const InputDecoration(
 | 
					                decoration: const InputDecoration(
 | 
				
			||||||
                  labelText: 'Carbs',
 | 
					                  labelText: 'Carbs',
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                keyboardType:const TextInputType.numberWithOptions(decimal: true),
 | 
					                keyboardType:
 | 
				
			||||||
 | 
					                    const TextInputType.numberWithOptions(decimal: true),
 | 
				
			||||||
                inputFormatters: <TextInputFormatter>[
 | 
					                inputFormatters: <TextInputFormatter>[
 | 
				
			||||||
                  FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
					                  FilteringTextInputFormatter.allow(
 | 
				
			||||||
 | 
					                      RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                controller: carbController,
 | 
					                controller: carbController,
 | 
				
			||||||
                onChanged: (String value) {
 | 
					                onChanged: (String value) {
 | 
				
			||||||
| 
						 | 
					@ -144,9 +143,11 @@ class _AddProductScreen extends State<AddProductScreen> {
 | 
				
			||||||
                decoration: const InputDecoration(
 | 
					                decoration: const InputDecoration(
 | 
				
			||||||
                  labelText: 'Fat',
 | 
					                  labelText: 'Fat',
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                keyboardType:const TextInputType.numberWithOptions(decimal: true),
 | 
					                keyboardType:
 | 
				
			||||||
 | 
					                    const TextInputType.numberWithOptions(decimal: true),
 | 
				
			||||||
                inputFormatters: <TextInputFormatter>[
 | 
					                inputFormatters: <TextInputFormatter>[
 | 
				
			||||||
                  FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
					                  FilteringTextInputFormatter.allow(
 | 
				
			||||||
 | 
					                      RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                controller: fatController,
 | 
					                controller: fatController,
 | 
				
			||||||
                onChanged: (String value) {
 | 
					                onChanged: (String value) {
 | 
				
			||||||
| 
						 | 
					@ -157,9 +158,11 @@ class _AddProductScreen extends State<AddProductScreen> {
 | 
				
			||||||
                decoration: const InputDecoration(
 | 
					                decoration: const InputDecoration(
 | 
				
			||||||
                  labelText: 'Protein',
 | 
					                  labelText: 'Protein',
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                keyboardType:const TextInputType.numberWithOptions(decimal: true),
 | 
					                keyboardType:
 | 
				
			||||||
 | 
					                    const TextInputType.numberWithOptions(decimal: true),
 | 
				
			||||||
                inputFormatters: <TextInputFormatter>[
 | 
					                inputFormatters: <TextInputFormatter>[
 | 
				
			||||||
                  FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
					                  FilteringTextInputFormatter.allow(
 | 
				
			||||||
 | 
					                      RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                controller: proteinController,
 | 
					                controller: proteinController,
 | 
				
			||||||
                onChanged: (String value) {
 | 
					                onChanged: (String value) {
 | 
				
			||||||
| 
						 | 
					@ -170,9 +173,11 @@ class _AddProductScreen extends State<AddProductScreen> {
 | 
				
			||||||
                decoration: const InputDecoration(
 | 
					                decoration: const InputDecoration(
 | 
				
			||||||
                  labelText: 'Fiber',
 | 
					                  labelText: 'Fiber',
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                keyboardType:const TextInputType.numberWithOptions(decimal: true),
 | 
					                keyboardType:
 | 
				
			||||||
 | 
					                    const TextInputType.numberWithOptions(decimal: true),
 | 
				
			||||||
                inputFormatters: <TextInputFormatter>[
 | 
					                inputFormatters: <TextInputFormatter>[
 | 
				
			||||||
                  FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
					                  FilteringTextInputFormatter.allow(
 | 
				
			||||||
 | 
					                      RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                controller: fiberController,
 | 
					                controller: fiberController,
 | 
				
			||||||
                onChanged: (String value) {
 | 
					                onChanged: (String value) {
 | 
				
			||||||
| 
						 | 
					@ -183,9 +188,7 @@ class _AddProductScreen extends State<AddProductScreen> {
 | 
				
			||||||
                "${calculateCalories().toStringAsFixed(2)} kcal",
 | 
					                "${calculateCalories().toStringAsFixed(2)} kcal",
 | 
				
			||||||
                textAlign: TextAlign.right,
 | 
					                textAlign: TextAlign.right,
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
            ]
 | 
					            ])),
 | 
				
			||||||
          )
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      floatingActionButton: FloatingActionButton(
 | 
					      floatingActionButton: FloatingActionButton(
 | 
				
			||||||
        onPressed: _addProduct,
 | 
					        onPressed: _addProduct,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,6 @@
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:fooder/client.dart';
 | 
					import 'package:fooder/client.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class BasedScreen extends StatefulWidget {
 | 
					abstract class BasedScreen extends StatefulWidget {
 | 
				
			||||||
  final ApiClient apiClient;
 | 
					  final ApiClient apiClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,23 +6,21 @@ import 'package:fooder/models/entry.dart';
 | 
				
			||||||
import 'package:fooder/widgets/product.dart';
 | 
					import 'package:fooder/widgets/product.dart';
 | 
				
			||||||
import 'package:fooder/screens/add_product.dart';
 | 
					import 'package:fooder/screens/add_product.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class EditEntryScreen extends BasedScreen {
 | 
					class EditEntryScreen extends BasedScreen {
 | 
				
			||||||
  final Entry entry;
 | 
					  final Entry entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const EditEntryScreen({super.key, required super.apiClient, required this.entry});
 | 
					  const EditEntryScreen(
 | 
				
			||||||
 | 
					      {super.key, required super.apiClient, required this.entry});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  State<EditEntryScreen> createState() => _EditEntryScreen();
 | 
					  State<EditEntryScreen> createState() => _EditEntryScreen();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class _EditEntryScreen extends State<EditEntryScreen> {
 | 
					class _EditEntryScreen extends State<EditEntryScreen> {
 | 
				
			||||||
  final gramsController = TextEditingController();
 | 
					  final gramsController = TextEditingController();
 | 
				
			||||||
  final productNameController = TextEditingController();
 | 
					  final productNameController = TextEditingController();
 | 
				
			||||||
  List<Product> products = [];
 | 
					  List<Product> products = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void dispose() {
 | 
					  void dispose() {
 | 
				
			||||||
    gramsController.dispose();
 | 
					    gramsController.dispose();
 | 
				
			||||||
| 
						 | 
					@ -35,7 +33,7 @@ class _EditEntryScreen extends State<EditEntryScreen> {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState () {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
    setState(() {
 | 
					    setState(() {
 | 
				
			||||||
      gramsController.text = widget.entry.grams.toString();
 | 
					      gramsController.text = widget.entry.grams.toString();
 | 
				
			||||||
| 
						 | 
					@ -45,14 +43,16 @@ class _EditEntryScreen extends State<EditEntryScreen> {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> _getProducts() async {
 | 
					  Future<void> _getProducts() async {
 | 
				
			||||||
    var productsMap = await widget.apiClient.getProducts(productNameController.text);
 | 
					    var productsMap =
 | 
				
			||||||
 | 
					        await widget.apiClient.getProducts(productNameController.text);
 | 
				
			||||||
    setState(() {
 | 
					    setState(() {
 | 
				
			||||||
      products = (productsMap['products'] as List<dynamic>).map((e) => Product.fromJson(e as Map<String, dynamic>)).toList();
 | 
					      products = (productsMap['products'] as List<dynamic>)
 | 
				
			||||||
 | 
					          .map((e) => Product.fromJson(e as Map<String, dynamic>))
 | 
				
			||||||
 | 
					          .toList();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void showError(String message)
 | 
					  void showError(String message) {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    ScaffoldMessenger.of(context).showSnackBar(
 | 
					    ScaffoldMessenger.of(context).showSnackBar(
 | 
				
			||||||
      SnackBar(
 | 
					      SnackBar(
 | 
				
			||||||
        content: Text(message, textAlign: TextAlign.center),
 | 
					        content: Text(message, textAlign: TextAlign.center),
 | 
				
			||||||
| 
						 | 
					@ -106,15 +106,16 @@ class _EditEntryScreen extends State<EditEntryScreen> {
 | 
				
			||||||
        child: Container(
 | 
					        child: Container(
 | 
				
			||||||
            constraints: const BoxConstraints(maxWidth: 720),
 | 
					            constraints: const BoxConstraints(maxWidth: 720),
 | 
				
			||||||
            padding: const EdgeInsets.all(10),
 | 
					            padding: const EdgeInsets.all(10),
 | 
				
			||||||
          child: ListView(
 | 
					            child: ListView(children: <Widget>[
 | 
				
			||||||
            children: <Widget>[
 | 
					 | 
				
			||||||
              TextFormField(
 | 
					              TextFormField(
 | 
				
			||||||
                decoration: const InputDecoration(
 | 
					                decoration: const InputDecoration(
 | 
				
			||||||
                  labelText: 'Grams',
 | 
					                  labelText: 'Grams',
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                keyboardType:const TextInputType.numberWithOptions(decimal: true),
 | 
					                keyboardType:
 | 
				
			||||||
 | 
					                    const TextInputType.numberWithOptions(decimal: true),
 | 
				
			||||||
                inputFormatters: <TextInputFormatter>[
 | 
					                inputFormatters: <TextInputFormatter>[
 | 
				
			||||||
                  FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
					                  FilteringTextInputFormatter.allow(
 | 
				
			||||||
 | 
					                      RegExp(r'^(\d+)?[\.,]?\d{0,2}')),
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                controller: gramsController,
 | 
					                controller: gramsController,
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
| 
						 | 
					@ -158,9 +159,7 @@ class _EditEntryScreen extends State<EditEntryScreen> {
 | 
				
			||||||
                    product: product,
 | 
					                    product: product,
 | 
				
			||||||
                  ),
 | 
					                  ),
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
            ]
 | 
					            ])),
 | 
				
			||||||
          )
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      floatingActionButton: Row(
 | 
					      floatingActionButton: Row(
 | 
				
			||||||
        mainAxisAlignment: MainAxisAlignment.end,
 | 
					        mainAxisAlignment: MainAxisAlignment.end,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,6 @@ import 'package:fooder/screens/based.dart';
 | 
				
			||||||
import 'package:fooder/screens/main.dart';
 | 
					import 'package:fooder/screens/main.dart';
 | 
				
			||||||
import 'package:fooder/screens/register.dart';
 | 
					import 'package:fooder/screens/register.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class LoginScreen extends BasedScreen {
 | 
					class LoginScreen extends BasedScreen {
 | 
				
			||||||
  const LoginScreen({super.key, required super.apiClient});
 | 
					  const LoginScreen({super.key, required super.apiClient});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +11,6 @@ class LoginScreen extends BasedScreen {
 | 
				
			||||||
  State<LoginScreen> createState() => _LoginScreen();
 | 
					  State<LoginScreen> createState() => _LoginScreen();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class _LoginScreen extends State<LoginScreen> {
 | 
					class _LoginScreen extends State<LoginScreen> {
 | 
				
			||||||
  final usernameController = TextEditingController();
 | 
					  final usernameController = TextEditingController();
 | 
				
			||||||
  final passwordController = TextEditingController();
 | 
					  final passwordController = TextEditingController();
 | 
				
			||||||
| 
						 | 
					@ -24,8 +22,7 @@ class _LoginScreen extends State<LoginScreen> {
 | 
				
			||||||
    super.dispose();
 | 
					    super.dispose();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void showError(String message)
 | 
					  void showError(String message) {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    ScaffoldMessenger.of(context).showSnackBar(
 | 
					    ScaffoldMessenger.of(context).showSnackBar(
 | 
				
			||||||
      SnackBar(
 | 
					      SnackBar(
 | 
				
			||||||
        content: Text(message, textAlign: TextAlign.center),
 | 
					        content: Text(message, textAlign: TextAlign.center),
 | 
				
			||||||
| 
						 | 
					@ -34,8 +31,7 @@ class _LoginScreen extends State<LoginScreen> {
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void showText(String text)
 | 
					  void showText(String text) {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    ScaffoldMessenger.of(context).showSnackBar(
 | 
					    ScaffoldMessenger.of(context).showSnackBar(
 | 
				
			||||||
      SnackBar(
 | 
					      SnackBar(
 | 
				
			||||||
        content: Text(text, textAlign: TextAlign.center),
 | 
					        content: Text(text, textAlign: TextAlign.center),
 | 
				
			||||||
| 
						 | 
					@ -68,9 +64,10 @@ class _LoginScreen extends State<LoginScreen> {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState () {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
    SystemChannels.textInput.invokeMethod('TextInput.setClientFeatures', <String, dynamic>{
 | 
					    SystemChannels.textInput
 | 
				
			||||||
 | 
					        .invokeMethod('TextInput.setClientFeatures', <String, dynamic>{
 | 
				
			||||||
      'setAuthenticationConfiguration': true,
 | 
					      'setAuthenticationConfiguration': true,
 | 
				
			||||||
      'setAutofillHints': <String>[
 | 
					      'setAutofillHints': <String>[
 | 
				
			||||||
        AutofillHints.username,
 | 
					        AutofillHints.username,
 | 
				
			||||||
| 
						 | 
					@ -140,7 +137,8 @@ class _LoginScreen extends State<LoginScreen> {
 | 
				
			||||||
                      Navigator.push(
 | 
					                      Navigator.push(
 | 
				
			||||||
                        context,
 | 
					                        context,
 | 
				
			||||||
                        MaterialPageRoute(
 | 
					                        MaterialPageRoute(
 | 
				
			||||||
                          builder: (context) => RegisterScreen(apiClient: widget.apiClient),
 | 
					                          builder: (context) =>
 | 
				
			||||||
 | 
					                              RegisterScreen(apiClient: widget.apiClient),
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
                      );
 | 
					                      );
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,6 @@ import 'package:fooder/screens/add_entry.dart';
 | 
				
			||||||
import 'package:fooder/models/diary.dart';
 | 
					import 'package:fooder/models/diary.dart';
 | 
				
			||||||
import 'package:fooder/widgets/diary.dart';
 | 
					import 'package:fooder/widgets/diary.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class MainScreen extends BasedScreen {
 | 
					class MainScreen extends BasedScreen {
 | 
				
			||||||
  const MainScreen({super.key, required super.apiClient});
 | 
					  const MainScreen({super.key, required super.apiClient});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +17,7 @@ class _MainScreen extends State<MainScreen> {
 | 
				
			||||||
  DateTime date = DateTime.now();
 | 
					  DateTime date = DateTime.now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState () {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
    _asyncInitState().then((value) => null);
 | 
					    _asyncInitState().then((value) => null);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -55,7 +54,8 @@ class _MainScreen extends State<MainScreen> {
 | 
				
			||||||
    await Navigator.push(
 | 
					    await Navigator.push(
 | 
				
			||||||
      context,
 | 
					      context,
 | 
				
			||||||
      MaterialPageRoute(
 | 
					      MaterialPageRoute(
 | 
				
			||||||
        builder: (context) => AddEntryScreen(apiClient: widget.apiClient, diary: diary!),
 | 
					        builder: (context) =>
 | 
				
			||||||
 | 
					            AddEntryScreen(apiClient: widget.apiClient, diary: diary!),
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
    ).then((_) => _asyncInitState());
 | 
					    ).then((_) => _asyncInitState());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -69,17 +69,23 @@ class _MainScreen extends State<MainScreen> {
 | 
				
			||||||
      content = Container(
 | 
					      content = Container(
 | 
				
			||||||
        constraints: const BoxConstraints(maxWidth: 720),
 | 
					        constraints: const BoxConstraints(maxWidth: 720),
 | 
				
			||||||
        padding: const EdgeInsets.all(10),
 | 
					        padding: const EdgeInsets.all(10),
 | 
				
			||||||
        child: DiaryWidget(diary: diary!, apiClient: widget.apiClient, refreshParent: _asyncInitState),
 | 
					        child: DiaryWidget(
 | 
				
			||||||
 | 
					            diary: diary!,
 | 
				
			||||||
 | 
					            apiClient: widget.apiClient,
 | 
				
			||||||
 | 
					            refreshParent: _asyncInitState),
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
      title = Row(
 | 
					      title = Row(
 | 
				
			||||||
        mainAxisAlignment: MainAxisAlignment.center,
 | 
					        mainAxisAlignment: MainAxisAlignment.center,
 | 
				
			||||||
        children: <Widget>[
 | 
					        children: <Widget>[
 | 
				
			||||||
          TextButton(
 | 
					          TextButton(
 | 
				
			||||||
            child: const Text("🅵🅾🅾🅳🅴🆁", style: const TextStyle(fontSize: 20, color: Colors.white)),
 | 
					            child: const Text("🅵🅾🅾🅳🅴🆁",
 | 
				
			||||||
 | 
					                style: const TextStyle(fontSize: 20, color: Colors.white)),
 | 
				
			||||||
            onPressed: () {
 | 
					            onPressed: () {
 | 
				
			||||||
              Navigator.pushReplacement(
 | 
					              Navigator.pushReplacement(
 | 
				
			||||||
                context,
 | 
					                context,
 | 
				
			||||||
                MaterialPageRoute(builder: (context) => MainScreen(apiClient: widget.apiClient)),
 | 
					                MaterialPageRoute(
 | 
				
			||||||
 | 
					                    builder: (context) =>
 | 
				
			||||||
 | 
					                        MainScreen(apiClient: widget.apiClient)),
 | 
				
			||||||
              ).then((_) => _asyncInitState());
 | 
					              ).then((_) => _asyncInitState());
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:flutter/services.dart';
 | 
					import 'package:flutter/services.dart';
 | 
				
			||||||
import 'package:fooder/screens/based.dart';
 | 
					import 'package:fooder/screens/based.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class RegisterScreen extends BasedScreen {
 | 
					class RegisterScreen extends BasedScreen {
 | 
				
			||||||
  const RegisterScreen({super.key, required super.apiClient});
 | 
					  const RegisterScreen({super.key, required super.apiClient});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +9,6 @@ class RegisterScreen extends BasedScreen {
 | 
				
			||||||
  State<RegisterScreen> createState() => _RegisterScreen();
 | 
					  State<RegisterScreen> createState() => _RegisterScreen();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class _RegisterScreen extends State<RegisterScreen> {
 | 
					class _RegisterScreen extends State<RegisterScreen> {
 | 
				
			||||||
  final usernameController = TextEditingController();
 | 
					  final usernameController = TextEditingController();
 | 
				
			||||||
  final passwordController = TextEditingController();
 | 
					  final passwordController = TextEditingController();
 | 
				
			||||||
| 
						 | 
					@ -27,7 +25,8 @@ class _RegisterScreen extends State<RegisterScreen> {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState() {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
    SystemChannels.textInput.invokeMethod('TextInput.setClientFeatures', <String, dynamic>{
 | 
					    SystemChannels.textInput
 | 
				
			||||||
 | 
					        .invokeMethod('TextInput.setClientFeatures', <String, dynamic>{
 | 
				
			||||||
      'setAuthenticationConfiguration': true,
 | 
					      'setAuthenticationConfiguration': true,
 | 
				
			||||||
      'setAutofillHints': <String>[
 | 
					      'setAutofillHints': <String>[
 | 
				
			||||||
        AutofillHints.username,
 | 
					        AutofillHints.username,
 | 
				
			||||||
| 
						 | 
					@ -36,8 +35,7 @@ class _RegisterScreen extends State<RegisterScreen> {
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void showError(String message)
 | 
					  void showError(String message) {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    ScaffoldMessenger.of(context).showSnackBar(
 | 
					    ScaffoldMessenger.of(context).showSnackBar(
 | 
				
			||||||
      SnackBar(
 | 
					      SnackBar(
 | 
				
			||||||
        content: Text(message, textAlign: TextAlign.center),
 | 
					        content: Text(message, textAlign: TextAlign.center),
 | 
				
			||||||
| 
						 | 
					@ -46,8 +44,7 @@ class _RegisterScreen extends State<RegisterScreen> {
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void showText(String text)
 | 
					  void showText(String text) {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    ScaffoldMessenger.of(context).showSnackBar(
 | 
					    ScaffoldMessenger.of(context).showSnackBar(
 | 
				
			||||||
      SnackBar(
 | 
					      SnackBar(
 | 
				
			||||||
        content: Text(text, textAlign: TextAlign.center),
 | 
					        content: Text(text, textAlign: TextAlign.center),
 | 
				
			||||||
| 
						 | 
					@ -116,15 +113,13 @@ class _RegisterScreen extends State<RegisterScreen> {
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    controller: passwordConfirmController,
 | 
					                    controller: passwordConfirmController,
 | 
				
			||||||
                    autofillHints: const [AutofillHints.password],
 | 
					                    autofillHints: const [AutofillHints.password],
 | 
				
			||||||
                  onFieldSubmitted: (_) => _register()
 | 
					                    onFieldSubmitted: (_) => _register()),
 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                Padding(
 | 
					                Padding(
 | 
				
			||||||
                    padding: const EdgeInsets.symmetric(vertical: 10),
 | 
					                    padding: const EdgeInsets.symmetric(vertical: 10),
 | 
				
			||||||
                    child: FilledButton(
 | 
					                    child: FilledButton(
 | 
				
			||||||
                      onPressed: _register,
 | 
					                      onPressed: _register,
 | 
				
			||||||
                      child: const Text('Register'),
 | 
					                      child: const Text('Register'),
 | 
				
			||||||
                  )
 | 
					                    )),
 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ],
 | 
					              ],
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,13 +6,16 @@ import 'package:fooder/client.dart';
 | 
				
			||||||
import 'package:fooder/screens/add_meal.dart';
 | 
					import 'package:fooder/screens/add_meal.dart';
 | 
				
			||||||
import 'dart:core';
 | 
					import 'dart:core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class DiaryWidget extends StatelessWidget {
 | 
					class DiaryWidget extends StatelessWidget {
 | 
				
			||||||
  final Diary diary;
 | 
					  final Diary diary;
 | 
				
			||||||
  final ApiClient apiClient;
 | 
					  final ApiClient apiClient;
 | 
				
			||||||
  final Function() refreshParent;
 | 
					  final Function() refreshParent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const DiaryWidget({super.key, required this.diary, required this.apiClient, required this.refreshParent});
 | 
					  const DiaryWidget(
 | 
				
			||||||
 | 
					      {super.key,
 | 
				
			||||||
 | 
					      required this.diary,
 | 
				
			||||||
 | 
					      required this.apiClient,
 | 
				
			||||||
 | 
					      required this.refreshParent});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
| 
						 | 
					@ -27,13 +30,15 @@ class DiaryWidget extends StatelessWidget {
 | 
				
			||||||
                    const Spacer(),
 | 
					                    const Spacer(),
 | 
				
			||||||
                    Text(
 | 
					                    Text(
 | 
				
			||||||
                      "${diary.calories.toStringAsFixed(1)} kcal",
 | 
					                      "${diary.calories.toStringAsFixed(1)} kcal",
 | 
				
			||||||
                  style: Theme.of(context).textTheme.headlineLarge!.copyWith(
 | 
					                      style: Theme.of(context)
 | 
				
			||||||
 | 
					                          .textTheme
 | 
				
			||||||
 | 
					                          .headlineLarge!
 | 
				
			||||||
 | 
					                          .copyWith(
 | 
				
			||||||
                            color: Theme.of(context).colorScheme.onSecondary,
 | 
					                            color: Theme.of(context).colorScheme.onSecondary,
 | 
				
			||||||
                            fontWeight: FontWeight.bold,
 | 
					                            fontWeight: FontWeight.bold,
 | 
				
			||||||
                          ),
 | 
					                          ),
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
              ]
 | 
					                  ]),
 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
              expandedHeight: 150,
 | 
					              expandedHeight: 150,
 | 
				
			||||||
              backgroundColor: Theme.of(context).colorScheme.secondary,
 | 
					              backgroundColor: Theme.of(context).colorScheme.secondary,
 | 
				
			||||||
              shape: RoundedRectangleBorder(
 | 
					              shape: RoundedRectangleBorder(
 | 
				
			||||||
| 
						 | 
					@ -65,13 +70,14 @@ class DiaryWidget extends StatelessWidget {
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    icon: const Icon(Icons.add),
 | 
					                    icon: const Icon(Icons.add),
 | 
				
			||||||
                    style: ButtonStyle(
 | 
					                    style: ButtonStyle(
 | 
				
			||||||
                    backgroundColor: MaterialStateProperty.all<Color>(Theme.of(context).colorScheme.secondary),
 | 
					                      backgroundColor: MaterialStateProperty.all<Color>(
 | 
				
			||||||
                    foregroundColor: MaterialStateProperty.all<Color>(Theme.of(context).colorScheme.onSecondary),
 | 
					                          Theme.of(context).colorScheme.secondary),
 | 
				
			||||||
 | 
					                      foregroundColor: MaterialStateProperty.all<Color>(
 | 
				
			||||||
 | 
					                          Theme.of(context).colorScheme.onSecondary),
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                  ),
 | 
					                  ),
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
              )
 | 
					              )),
 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
          SliverList(
 | 
					          SliverList(
 | 
				
			||||||
            delegate: SliverChildListDelegate(
 | 
					            delegate: SliverChildListDelegate(
 | 
				
			||||||
              [
 | 
					              [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@ import 'package:fooder/models/entry.dart';
 | 
				
			||||||
import 'package:fooder/widgets/macro.dart';
 | 
					import 'package:fooder/widgets/macro.dart';
 | 
				
			||||||
import 'dart:core';
 | 
					import 'dart:core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class EntryWidget extends StatelessWidget {
 | 
					class EntryWidget extends StatelessWidget {
 | 
				
			||||||
  final Entry entry;
 | 
					  final Entry entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class MacroWidget extends StatelessWidget {
 | 
					class MacroWidget extends StatelessWidget {
 | 
				
			||||||
  final double? amount;
 | 
					  final double? amount;
 | 
				
			||||||
  final double? calories;
 | 
					  final double? calories;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,13 +6,16 @@ import 'package:fooder/screens/edit_entry.dart';
 | 
				
			||||||
import 'package:fooder/client.dart';
 | 
					import 'package:fooder/client.dart';
 | 
				
			||||||
import 'dart:core';
 | 
					import 'dart:core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class MealWidget extends StatelessWidget {
 | 
					class MealWidget extends StatelessWidget {
 | 
				
			||||||
  final Meal meal;
 | 
					  final Meal meal;
 | 
				
			||||||
  final ApiClient apiClient;
 | 
					  final ApiClient apiClient;
 | 
				
			||||||
  final Function() refreshParent;
 | 
					  final Function() refreshParent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const MealWidget({super.key, required this.meal, required this.apiClient, required this.refreshParent});
 | 
					  const MealWidget(
 | 
				
			||||||
 | 
					      {super.key,
 | 
				
			||||||
 | 
					      required this.meal,
 | 
				
			||||||
 | 
					      required this.apiClient,
 | 
				
			||||||
 | 
					      required this.refreshParent});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@ import 'package:fooder/models/product.dart';
 | 
				
			||||||
import 'package:fooder/widgets/macro.dart';
 | 
					import 'package:fooder/widgets/macro.dart';
 | 
				
			||||||
import 'dart:core';
 | 
					import 'dart:core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class ProductWidget extends StatelessWidget {
 | 
					class ProductWidget extends StatelessWidget {
 | 
				
			||||||
  final Product product;
 | 
					  final Product product;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue