refactor(diary): API methods all refactored and new nutrition charty finished

This commit is contained in:
2024-07-24 17:12:28 +03:00
parent 7535e82422
commit 0671c5d072
11 changed files with 568 additions and 443 deletions

View File

@@ -7,9 +7,8 @@ part 'photo.g.dart';
class Photo with _$Photo {
const factory Photo({
required int id,
required String originalName,
required String original_name,
required String path,
required int size,
}) = _Photo;
factory Photo.fromJson(Map<String, Object?> json) => _$PhotoFromJson(json);

View File

@@ -21,9 +21,8 @@ Photo _$PhotoFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$Photo {
int get id => throw _privateConstructorUsedError;
String get originalName => throw _privateConstructorUsedError;
String get original_name => throw _privateConstructorUsedError;
String get path => throw _privateConstructorUsedError;
int get size => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
@@ -35,7 +34,7 @@ abstract class $PhotoCopyWith<$Res> {
factory $PhotoCopyWith(Photo value, $Res Function(Photo) then) =
_$PhotoCopyWithImpl<$Res, Photo>;
@useResult
$Res call({int id, String originalName, String path, int size});
$Res call({int id, String original_name, String path});
}
/// @nodoc
@@ -52,27 +51,22 @@ class _$PhotoCopyWithImpl<$Res, $Val extends Photo>
@override
$Res call({
Object? id = null,
Object? originalName = null,
Object? original_name = null,
Object? path = null,
Object? size = null,
}) {
return _then(_value.copyWith(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as int,
originalName: null == originalName
? _value.originalName
: originalName // ignore: cast_nullable_to_non_nullable
original_name: null == original_name
? _value.original_name
: original_name // ignore: cast_nullable_to_non_nullable
as String,
path: null == path
? _value.path
: path // ignore: cast_nullable_to_non_nullable
as String,
size: null == size
? _value.size
: size // ignore: cast_nullable_to_non_nullable
as int,
) as $Val);
}
}
@@ -84,7 +78,7 @@ abstract class _$$PhotoImplCopyWith<$Res> implements $PhotoCopyWith<$Res> {
__$$PhotoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({int id, String originalName, String path, int size});
$Res call({int id, String original_name, String path});
}
/// @nodoc
@@ -99,27 +93,22 @@ class __$$PhotoImplCopyWithImpl<$Res>
@override
$Res call({
Object? id = null,
Object? originalName = null,
Object? original_name = null,
Object? path = null,
Object? size = null,
}) {
return _then(_$PhotoImpl(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as int,
originalName: null == originalName
? _value.originalName
: originalName // ignore: cast_nullable_to_non_nullable
original_name: null == original_name
? _value.original_name
: original_name // ignore: cast_nullable_to_non_nullable
as String,
path: null == path
? _value.path
: path // ignore: cast_nullable_to_non_nullable
as String,
size: null == size
? _value.size
: size // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
@@ -128,10 +117,7 @@ class __$$PhotoImplCopyWithImpl<$Res>
@JsonSerializable()
class _$PhotoImpl implements _Photo {
const _$PhotoImpl(
{required this.id,
required this.originalName,
required this.path,
required this.size});
{required this.id, required this.original_name, required this.path});
factory _$PhotoImpl.fromJson(Map<String, dynamic> json) =>
_$$PhotoImplFromJson(json);
@@ -139,15 +125,13 @@ class _$PhotoImpl implements _Photo {
@override
final int id;
@override
final String originalName;
final String original_name;
@override
final String path;
@override
final int size;
@override
String toString() {
return 'Photo(id: $id, originalName: $originalName, path: $path, size: $size)';
return 'Photo(id: $id, original_name: $original_name, path: $path)';
}
@override
@@ -156,15 +140,14 @@ class _$PhotoImpl implements _Photo {
(other.runtimeType == runtimeType &&
other is _$PhotoImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.originalName, originalName) ||
other.originalName == originalName) &&
(identical(other.path, path) || other.path == path) &&
(identical(other.size, size) || other.size == size));
(identical(other.original_name, original_name) ||
other.original_name == original_name) &&
(identical(other.path, path) || other.path == path));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(runtimeType, id, originalName, path, size);
int get hashCode => Object.hash(runtimeType, id, original_name, path);
@JsonKey(ignore: true)
@override
@@ -183,21 +166,18 @@ class _$PhotoImpl implements _Photo {
abstract class _Photo implements Photo {
const factory _Photo(
{required final int id,
required final String originalName,
required final String path,
required final int size}) = _$PhotoImpl;
required final String original_name,
required final String path}) = _$PhotoImpl;
factory _Photo.fromJson(Map<String, dynamic> json) = _$PhotoImpl.fromJson;
@override
int get id;
@override
String get originalName;
String get original_name;
@override
String get path;
@override
int get size;
@override
@JsonKey(ignore: true)
_$$PhotoImplCopyWith<_$PhotoImpl> get copyWith =>
throw _privateConstructorUsedError;

View File

@@ -8,15 +8,13 @@ part of 'photo.dart';
_$PhotoImpl _$$PhotoImplFromJson(Map<String, dynamic> json) => _$PhotoImpl(
id: (json['id'] as num).toInt(),
originalName: json['originalName'] as String,
original_name: json['original_name'] as String,
path: json['path'] as String,
size: (json['size'] as num).toInt(),
);
Map<String, dynamic> _$$PhotoImplToJson(_$PhotoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'originalName': instance.originalName,
'original_name': instance.original_name,
'path': instance.path,
'size': instance.size,
};

View File

@@ -38,7 +38,6 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
_removeImage,
); // пользователь нажимает на крестик около продукта
on<UploadImages>(_uploadImages); //пользователь нажимает "Добавить фото"
on<AddComment>(_addComment); //пользователь нажимает "Добавить комментарий"
on<ProductInput>(
_inputProduct,
);
@@ -57,13 +56,50 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
emit(const DiaryState.loading());
try {
Map<String, int> data = await diaryRepository.getDiaryID();
final int? diaryID = data['id'];
final DiaryModel diary = await diaryRepository.getDiary(diaryID ?? 45);
final Meal currentMeal = diary.meals[0];
List<SelectionPopupModel> portionList = [
SelectionPopupModel(title: "gr"),
SelectionPopupModel(title: "pcs")
];
final Map<String, dynamic> chartData =
await diaryRepository.getChartData(diaryID ?? 45);
final Map<String, dynamic> dailyNutritionIntake =
chartData['dailyNutritionIntake']!;
final Map<String, dynamic> dailyNutritionRecommendations =
chartData['dailyNutritionRecommendation']!;
final double ccal = dailyNutritionIntake['energy']! /
dailyNutritionRecommendations['energy']! *
100;
final double proteins = dailyNutritionIntake['proteins']! /
dailyNutritionRecommendations['proteins']! *
100;
final double fats = dailyNutritionIntake['fats']! /
dailyNutritionRecommendations['fats']! *
100;
final double carbs = dailyNutritionIntake['carbohydrates']! /
dailyNutritionRecommendations['carbohydrates']! *
100;
Color getColor(double value) {
if (value >= 99.1) {
return Colors.red;
} else {
return Colors.blue;
}
}
final List<NutritionData> chartDataCounted = [
NutritionData('Калории', ccal, getColor(ccal)),
NutritionData('Белки', proteins, getColor(proteins)),
NutritionData('Жиры', fats, getColor(fats)),
NutritionData('Углеводы', carbs, getColor(carbs)),
];
List<SelectionPopupModel> mealList = [
SelectionPopupModel(title: "Прием пищи 1", id: 1),
SelectionPopupModel(title: "Прием пищи 2", id: 2),
@@ -72,14 +108,17 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
SelectionPopupModel(title: "Прием пищи 5", id: 5),
SelectionPopupModel(title: "Прием пищи 6", id: 6),
];
print(dailyNutritionRecommendations);
print(dailyNutritionIntake);
emit(DiaryState.loaded(
diary: diary,
currentMeal: currentMeal,
portions: currentMeal.portions,
photos: currentMeal.photos,
portionList: portionList,
portionController: portionList[0],
mealList: mealList,
chartData: chartDataCounted,
selectedMood: currentMeal.mood,
selectedSatiety: currentMeal.satiety,
commentController: TextEditingController(),
@@ -119,7 +158,7 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
if (responseChart.statusCode == 200) {
final responseBody = jsonDecode(responseChart.body);
print(responseBody);
final recommendedChartValues =
responseBody['dailyNutritionRecommendation']
.values
@@ -131,13 +170,22 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
.map<int>((value) => convertToInt(value))
.toList();
print([recommendedChartValues, consumedChartValues]);
return [recommendedChartValues, consumedChartValues];
print([
recommendedChartValues,
consumedChartValues,
]);
return [
recommendedChartValues,
consumedChartValues,
];
} else {
emit(DiaryStateError(
errorMessage: 'Ошибка при декодировании данных КБЖУ'));
print('fail');
return [[], []]; // Return empty lists instead of -1
return [
[],
[],
];
}
}
@@ -162,10 +210,14 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
) async {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
var updatedState =
currentState.copyWith(selectedSatiety: event.selectedElement);
diaryRepository.changeSatiety(event.selectedElement,
currentState.currentMeal.id, currentState.diary.id);
var updatedState = currentState.copyWith(
selectedSatiety: event.selectedElement,
);
diaryRepository.changeSatiety(
event.selectedElement,
currentState.currentMeal.id,
currentState.diary.id,
);
emit(updatedState);
}
}
@@ -176,11 +228,15 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
) async {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
var updatedState =
currentState.copyWith(selectedMood: event.selectedElement);
var updatedState = currentState.copyWith(
selectedMood: event.selectedElement,
);
diaryRepository.changeMood(event.selectedElement,
currentState.currentMeal.id, currentState.diary.id);
diaryRepository.changeMood(
event.selectedElement,
currentState.currentMeal.id,
currentState.diary.id,
);
emit(updatedState); // Передаем обновленное состояние в emit
}
@@ -246,7 +302,6 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
DiaryStateLoaded updatedState = currentState.copyWith(
currentMeal: meal,
portions: meal.portions,
photos: meal.photos,
mealTimeController: toTime(meal.time),
selectedMood: meal.mood,
selectedSatiety: meal.satiety,
@@ -279,6 +334,76 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
}
}
FutureOr<void> _addPortion(
AddPortionEvent event,
Emitter<DiaryState> emit,
) async {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
Map<String, Portion> data = await diaryRepository.addPortion(
currentState.diary.id,
currentState.currentMeal.id,
currentState.product_nameController.text,
currentState.portionController.title,
int.parse(currentState.productQuantityController.text),
);
List<Portion> newPortions = currentState.portions;
final Portion newPortion = data['portion'] ??
new Portion(id: 1, portion: 'gr', product_name: '1', quantity: 1);
newPortions.add(newPortion);
emit(currentState.copyWith(isAdded: true, portions: newPortions));
//TODO update screen after addPortion() call
}
}
Future<void> _removePortion(
RemovePortionEvent event,
Emitter<DiaryState> emit,
) async {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
await diaryRepository.removePortion(
currentState.diary.id,
currentState.currentMeal.id,
event.portionId,
);
}
//TODO update screen after _removePortion() call
}
Future<void> _uploadImages(
UploadImages event,
Emitter<DiaryState> emit,
) async {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
emit(currentState.copyWith(isLoading: true));
await diaryRepository.uploadImage(
event.image.path,
currentState.diary.id,
currentState.currentMeal.id,
);
}
}
FutureOr<void> _sendModeration(
SendModeration event,
Emitter<DiaryState> emit,
) async {
if (state is DiaryStateLoaded) {
await diaryRepository.sendModeration(
event.name,
event.energyOn100gr,
event.proteinsOn100gr,
event.fatsOn100gr,
event.carbohydratesOn100gr,
);
}
}
FutureOr<void> _clearInput(
ClearInput event,
Emitter<DiaryState> emit,
@@ -325,48 +450,6 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
}
}
FutureOr<void> _addPortion(
AddPortionEvent event,
Emitter<DiaryState> emit,
) async {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
print(currentState.diary.id);
print(currentState.currentMeal.id);
print(currentState.product_nameController.text);
print(currentState.portionController.title);
print(currentState.productQuantityController.text);
Map<String, Portion> data = await diaryRepository.addPortion(
currentState.diary.id,
currentState.currentMeal.id,
currentState.product_nameController.text,
currentState.portionController.title,
int.parse(currentState.productQuantityController.text),
);
List<Portion> newPortions = currentState.portions;
final Portion newPortion = data['portion'] ??
new Portion(id: 1, portion: 'gr', product_name: '1', quantity: 1);
newPortions.add(newPortion);
emit(currentState.copyWith(isAdded: true, portions: newPortions));
}
}
Future<void> _removePortion(
RemovePortionEvent event,
Emitter<DiaryState> emit,
) async {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
await diaryRepository.removePortion(
currentState.diary.id,
currentState.currentMeal.id,
event.portionId,
);
}
}
FutureOr<void> _removeImage(
RemoveImageEvent event,
Emitter<DiaryState> emit,
@@ -374,244 +457,28 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
var response = await sendRemovePhoto(
event.path,
event.photoID,
currentState.currentMeal.id,
await diaryRepository.removeImage(
currentState.diary.id,
currentState.currentMeal.id,
int.parse(event.photoID),
event.path,
);
print(response.statusCode);
if (response.statusCode == 204) {
await reloadScreen(event, emit);
} else {
print(
'Failed to remove photo. Status Code: ${response.statusCode} ${response.body}',
);
}
}
}
Future<http.Response> sendRemovePhoto(
String? path,
String? photoID,
int? mealID,
int diaryID,
) async {
String url =
'${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealID/photo/delete';
final Map<String, dynamic> credentials = {
'id': photoID,
'path': path,
};
var response = await http.delete(
Uri.parse(url),
headers: {
'Content-Type': 'application/json',
},
body: json.encode(credentials),
encoding: utf8,
);
return response;
}
Future<void> _finishDay(FinishDay event, Emitter<DiaryState> emit) async {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
var response = await sendFinishDay(
await diaryRepository.finishDay(
currentState.diary.id,
currentState.wakeupController,
currentState.retireController,
currentState.commentController.text,
);
if (response.statusCode == 200) {
await reloadScreen(event, emit);
}
}
}
Future<http.Response> sendFinishDay(
int diaryID,
TimeOfDay? wakeup,
TimeOfDay? retire,
String? comment,
) async {
final formatter = DateFormat('HH:mm');
final wakeupString =
formatter.format(DateTime(2022, 1, 1, wakeup!.hour, wakeup.minute));
final retireString =
formatter.format(DateTime(2022, 1, 1, retire!.hour, retire.minute));
final Map<String, dynamic> credentials = {
'wakeup': wakeupString,
'retire': retireString,
'comment': comment ?? " ",
};
String url = '${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/finishDay';
var response = await http.post(
Uri.parse(url),
headers: {
'Content-Type': 'application/json',
},
body: json.encode(credentials),
encoding: utf8,
);
return response;
}
Future<void> _uploadImages(
UploadImages event,
Emitter<DiaryState> emit,
) async {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
emit(currentState.copyWith(isLoading: true));
await uploadImageToServer(
event.image.path,
currentState.diary.id,
currentState.currentMeal.id,
);
await reloadScreen(event, emit);
}
}
Future<String> uploadImageToServer(
String imagePath,
int diaryID,
int mealId,
) async {
String url =
'${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealId/photo/upload';
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(await http.MultipartFile.fromPath('photo', imagePath));
var client = http.Client();
var streamedResponse = await client.send(request);
if (streamedResponse.statusCode == 200) {
var response = await http.Response.fromStream(streamedResponse);
var imageUrl = response.body;
print('Image successfully uploaded');
return imageUrl;
} else {
throw Exception(
'Failed to upload image. Status code: ${streamedResponse.statusCode}}',
);
}
}
FutureOr<void> _sendModeration(
SendModeration event,
Emitter<DiaryState> emit,
) async {
if (state is DiaryStateLoaded) {
final response = await _sendModerationData(
event.name,
event.energyOn100gr,
event.proteinsOn100gr,
event.fatsOn100gr,
event.carbohydratesOn100gr,
);
if (response.statusCode == 200)
print("Moderation success");
else
print("Moderation error");
}
}
Future<http.Response> _sendModerationData(
String name,
String energy_on_100gr,
String proteins_on_100gr,
String fats_on_100gr,
String carbohydrates_on_100gr,
) async {
final Uri url = Uri.parse(
'${dotenv.env['SERVER_ROOT']!}/diary/product_nutritional_values/sendToModeration',
);
final Uri serverURL = Uri.parse('${dotenv.env['SERVER_ROOT']!}');
String host = serverURL.host;
final Map<String, String> credentials = {
'name': name,
'energy_on_100gr': energy_on_100gr,
'proteins_on_100gr': proteins_on_100gr,
'fats_on_100gr': fats_on_100gr,
'carbohydrates_on_100gr': carbohydrates_on_100gr,
};
var headers = {
//'Content-Length': bodyBytes,
'Host': host,
};
var response = await http.post(
url,
headers: headers,
body: credentials,
encoding: utf8,
);
if (response.statusCode == 200) {
return response;
} else {
throw Exception(
'Failed to send a product for moderation ${response.statusCode}',
);
}
}
FutureOr<void> _addComment(
AddComment event,
Emitter<DiaryState> emit,
) async {
if (state is DiaryStateLoaded) {
var currentState = state as DiaryStateLoaded;
var updatedState = currentState.copyWith(
commentController: TextEditingController(text: event.comment),
);
// Отправляем данные по HTTP маршруту и ждем ответ
var response = await sendCommentData(
event.comment,
currentState.diary.id,
);
if (response.statusCode == 200) {
emit(updatedState); // Передаем обновленное состояние в emit
}
}
}
Future<http.Response> sendCommentData(
String comment,
int diaryID,
) async {
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/retire/fill';
final Map<String, dynamic> credentials = {
'comment': comment,
};
var response = await http.post(
Uri.parse(url),
headers: {
'Content-Type': 'application/json',
},
body: json.encode(credentials),
encoding: utf8,
);
return response;
}
TimeOfDay toTime(String timeStr) {
List<String> timeParts = timeStr.split(":");
int hour = int.parse(timeParts[0]);
@@ -621,14 +488,6 @@ class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
return timeOfDay;
}
List<SelectionPopupModel> fillMealList(List<dynamic> meals) {
meals.sort(compareTypes);
return meals.map((meal) {
String title = "Прием пищи ${meal['type']}";
return SelectionPopupModel(id: meal['id'], title: title);
}).toList();
}
int compareTypes(a, b) {
return a['type'].compareTo(b['type']);
}

View File

@@ -1,6 +1,5 @@
import 'package:eatvio_app/features/diary/models/diary_model.dart';
import 'package:eatvio_app/features/diary/models/meal.dart';
import 'package:eatvio_app/features/diary/models/photo.dart';
import 'package:eatvio_app/features/diary/models/portion.dart';
import 'package:eatvio_app/features/diary/models/product.dart';
import 'package:flutter/material.dart';
@@ -22,7 +21,6 @@ abstract class DiaryState with _$DiaryState {
required List<int> recommendedChartValues,
required List<int> consumedChartValues,
required List<Portion> portions,
required List<Photo> photos,
required List<SelectionPopupModel> mealList,
required List<SelectionPopupModel> portionList,
required List<Product> autocompleteList,
@@ -45,9 +43,18 @@ abstract class DiaryState with _$DiaryState {
required bool moodExpanded,
required bool isLoading,
required bool isAdded,
List<NutritionData>? chartData,
}) = DiaryStateLoaded;
const factory DiaryState.error({
required String errorMessage,
}) = DiaryStateError;
}
class NutritionData {
NutritionData(this.category, this.nutrition, this.color);
final String category;
final double nutrition;
final Color color;
}

View File

@@ -26,7 +26,6 @@ mixin _$DiaryState {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -48,7 +47,8 @@ mixin _$DiaryState {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)
bool isAdded,
List<NutritionData>? chartData)
loaded,
required TResult Function(String errorMessage) error,
}) =>
@@ -63,7 +63,6 @@ mixin _$DiaryState {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -85,7 +84,8 @@ mixin _$DiaryState {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)?
bool isAdded,
List<NutritionData>? chartData)?
loaded,
TResult? Function(String errorMessage)? error,
}) =>
@@ -100,7 +100,6 @@ mixin _$DiaryState {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -122,7 +121,8 @@ mixin _$DiaryState {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)?
bool isAdded,
List<NutritionData>? chartData)?
loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
@@ -219,7 +219,6 @@ class _$DiaryStateImpl implements _DiaryState {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -241,7 +240,8 @@ class _$DiaryStateImpl implements _DiaryState {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)
bool isAdded,
List<NutritionData>? chartData)
loaded,
required TResult Function(String errorMessage) error,
}) {
@@ -259,7 +259,6 @@ class _$DiaryStateImpl implements _DiaryState {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -281,7 +280,8 @@ class _$DiaryStateImpl implements _DiaryState {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)?
bool isAdded,
List<NutritionData>? chartData)?
loaded,
TResult? Function(String errorMessage)? error,
}) {
@@ -299,7 +299,6 @@ class _$DiaryStateImpl implements _DiaryState {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -321,7 +320,8 @@ class _$DiaryStateImpl implements _DiaryState {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)?
bool isAdded,
List<NutritionData>? chartData)?
loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
@@ -420,7 +420,6 @@ class _$DiaryStateLoadingImpl implements DiaryStateLoading {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -442,7 +441,8 @@ class _$DiaryStateLoadingImpl implements DiaryStateLoading {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)
bool isAdded,
List<NutritionData>? chartData)
loaded,
required TResult Function(String errorMessage) error,
}) {
@@ -460,7 +460,6 @@ class _$DiaryStateLoadingImpl implements DiaryStateLoading {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -482,7 +481,8 @@ class _$DiaryStateLoadingImpl implements DiaryStateLoading {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)?
bool isAdded,
List<NutritionData>? chartData)?
loaded,
TResult? Function(String errorMessage)? error,
}) {
@@ -500,7 +500,6 @@ class _$DiaryStateLoadingImpl implements DiaryStateLoading {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -522,7 +521,8 @@ class _$DiaryStateLoadingImpl implements DiaryStateLoading {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)?
bool isAdded,
List<NutritionData>? chartData)?
loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
@@ -587,7 +587,6 @@ abstract class _$$DiaryStateLoadedImplCopyWith<$Res> {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -609,7 +608,8 @@ abstract class _$$DiaryStateLoadedImplCopyWith<$Res> {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded});
bool isAdded,
List<NutritionData>? chartData});
$DiaryModelCopyWith<$Res> get diary;
$MealCopyWith<$Res> get currentMeal;
@@ -631,7 +631,6 @@ class __$$DiaryStateLoadedImplCopyWithImpl<$Res>
Object? recommendedChartValues = null,
Object? consumedChartValues = null,
Object? portions = null,
Object? photos = null,
Object? mealList = null,
Object? portionList = null,
Object? autocompleteList = null,
@@ -654,6 +653,7 @@ class __$$DiaryStateLoadedImplCopyWithImpl<$Res>
Object? moodExpanded = null,
Object? isLoading = null,
Object? isAdded = null,
Object? chartData = freezed,
}) {
return _then(_$DiaryStateLoadedImpl(
diary: null == diary
@@ -676,10 +676,6 @@ class __$$DiaryStateLoadedImplCopyWithImpl<$Res>
? _value._portions
: portions // ignore: cast_nullable_to_non_nullable
as List<Portion>,
photos: null == photos
? _value._photos
: photos // ignore: cast_nullable_to_non_nullable
as List<Photo>,
mealList: null == mealList
? _value._mealList
: mealList // ignore: cast_nullable_to_non_nullable
@@ -768,6 +764,10 @@ class __$$DiaryStateLoadedImplCopyWithImpl<$Res>
? _value.isAdded
: isAdded // ignore: cast_nullable_to_non_nullable
as bool,
chartData: freezed == chartData
? _value._chartData
: chartData // ignore: cast_nullable_to_non_nullable
as List<NutritionData>?,
));
}
@@ -797,7 +797,6 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
required final List<int> recommendedChartValues,
required final List<int> consumedChartValues,
required final List<Portion> portions,
required final List<Photo> photos,
required final List<SelectionPopupModel> mealList,
required final List<SelectionPopupModel> portionList,
required final List<Product> autocompleteList,
@@ -819,14 +818,15 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
required this.moderationExpanded,
required this.moodExpanded,
required this.isLoading,
required this.isAdded})
required this.isAdded,
final List<NutritionData>? chartData})
: _recommendedChartValues = recommendedChartValues,
_consumedChartValues = consumedChartValues,
_portions = portions,
_photos = photos,
_mealList = mealList,
_portionList = portionList,
_autocompleteList = autocompleteList;
_autocompleteList = autocompleteList,
_chartData = chartData;
@override
final DiaryModel diary;
@@ -858,14 +858,6 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
return EqualUnmodifiableListView(_portions);
}
final List<Photo> _photos;
@override
List<Photo> get photos {
if (_photos is EqualUnmodifiableListView) return _photos;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_photos);
}
final List<SelectionPopupModel> _mealList;
@override
List<SelectionPopupModel> get mealList {
@@ -929,10 +921,19 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
final bool isLoading;
@override
final bool isAdded;
final List<NutritionData>? _chartData;
@override
List<NutritionData>? get chartData {
final value = _chartData;
if (value == null) return null;
if (_chartData is EqualUnmodifiableListView) return _chartData;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(value);
}
@override
String toString() {
return 'DiaryState.loaded(diary: $diary, diaryDate: $diaryDate, recommendedChartValues: $recommendedChartValues, consumedChartValues: $consumedChartValues, portions: $portions, photos: $photos, mealList: $mealList, portionList: $portionList, autocompleteList: $autocompleteList, currentMeal: $currentMeal, portionController: $portionController, wakeupController: $wakeupController, retireController: $retireController, mealTimeController: $mealTimeController, commentController: $commentController, product_nameController: $product_nameController, productQuantityController: $productQuantityController, caloriesController: $caloriesController, fatsController: $fatsController, proteinsController: $proteinsController, carbsController: $carbsController, selectedMood: $selectedMood, selectedSatiety: $selectedSatiety, wakeupExpanded: $wakeupExpanded, moderationExpanded: $moderationExpanded, moodExpanded: $moodExpanded, isLoading: $isLoading, isAdded: $isAdded)';
return 'DiaryState.loaded(diary: $diary, diaryDate: $diaryDate, recommendedChartValues: $recommendedChartValues, consumedChartValues: $consumedChartValues, portions: $portions, mealList: $mealList, portionList: $portionList, autocompleteList: $autocompleteList, currentMeal: $currentMeal, portionController: $portionController, wakeupController: $wakeupController, retireController: $retireController, mealTimeController: $mealTimeController, commentController: $commentController, product_nameController: $product_nameController, productQuantityController: $productQuantityController, caloriesController: $caloriesController, fatsController: $fatsController, proteinsController: $proteinsController, carbsController: $carbsController, selectedMood: $selectedMood, selectedSatiety: $selectedSatiety, wakeupExpanded: $wakeupExpanded, moderationExpanded: $moderationExpanded, moodExpanded: $moodExpanded, isLoading: $isLoading, isAdded: $isAdded, chartData: $chartData)';
}
@override
@@ -948,7 +949,6 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
const DeepCollectionEquality()
.equals(other._consumedChartValues, _consumedChartValues) &&
const DeepCollectionEquality().equals(other._portions, _portions) &&
const DeepCollectionEquality().equals(other._photos, _photos) &&
const DeepCollectionEquality().equals(other._mealList, _mealList) &&
const DeepCollectionEquality()
.equals(other._portionList, _portionList) &&
@@ -991,7 +991,9 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
other.moodExpanded == moodExpanded) &&
(identical(other.isLoading, isLoading) ||
other.isLoading == isLoading) &&
(identical(other.isAdded, isAdded) || other.isAdded == isAdded));
(identical(other.isAdded, isAdded) || other.isAdded == isAdded) &&
const DeepCollectionEquality()
.equals(other._chartData, _chartData));
}
@override
@@ -1002,7 +1004,6 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
const DeepCollectionEquality().hash(_recommendedChartValues),
const DeepCollectionEquality().hash(_consumedChartValues),
const DeepCollectionEquality().hash(_portions),
const DeepCollectionEquality().hash(_photos),
const DeepCollectionEquality().hash(_mealList),
const DeepCollectionEquality().hash(_portionList),
const DeepCollectionEquality().hash(_autocompleteList),
@@ -1024,7 +1025,8 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
moderationExpanded,
moodExpanded,
isLoading,
isAdded
isAdded,
const DeepCollectionEquality().hash(_chartData)
]);
@JsonKey(ignore: true)
@@ -1045,7 +1047,6 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -1067,7 +1068,8 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)
bool isAdded,
List<NutritionData>? chartData)
loaded,
required TResult Function(String errorMessage) error,
}) {
@@ -1077,7 +1079,6 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
recommendedChartValues,
consumedChartValues,
portions,
photos,
mealList,
portionList,
autocompleteList,
@@ -1099,7 +1100,8 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
moderationExpanded,
moodExpanded,
isLoading,
isAdded);
isAdded,
chartData);
}
@override
@@ -1113,7 +1115,6 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -1135,7 +1136,8 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)?
bool isAdded,
List<NutritionData>? chartData)?
loaded,
TResult? Function(String errorMessage)? error,
}) {
@@ -1145,7 +1147,6 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
recommendedChartValues,
consumedChartValues,
portions,
photos,
mealList,
portionList,
autocompleteList,
@@ -1167,7 +1168,8 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
moderationExpanded,
moodExpanded,
isLoading,
isAdded);
isAdded,
chartData);
}
@override
@@ -1181,7 +1183,6 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -1203,7 +1204,8 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)?
bool isAdded,
List<NutritionData>? chartData)?
loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
@@ -1215,7 +1217,6 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
recommendedChartValues,
consumedChartValues,
portions,
photos,
mealList,
portionList,
autocompleteList,
@@ -1237,7 +1238,8 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
moderationExpanded,
moodExpanded,
isLoading,
isAdded);
isAdded,
chartData);
}
return orElse();
}
@@ -1287,7 +1289,6 @@ abstract class DiaryStateLoaded implements DiaryState {
required final List<int> recommendedChartValues,
required final List<int> consumedChartValues,
required final List<Portion> portions,
required final List<Photo> photos,
required final List<SelectionPopupModel> mealList,
required final List<SelectionPopupModel> portionList,
required final List<Product> autocompleteList,
@@ -1309,14 +1310,14 @@ abstract class DiaryStateLoaded implements DiaryState {
required final bool moderationExpanded,
required final bool moodExpanded,
required final bool isLoading,
required final bool isAdded}) = _$DiaryStateLoadedImpl;
required final bool isAdded,
final List<NutritionData>? chartData}) = _$DiaryStateLoadedImpl;
DiaryModel get diary;
String? get diaryDate;
List<int> get recommendedChartValues;
List<int> get consumedChartValues;
List<Portion> get portions;
List<Photo> get photos;
List<SelectionPopupModel> get mealList;
List<SelectionPopupModel> get portionList;
List<Product> get autocompleteList;
@@ -1339,6 +1340,7 @@ abstract class DiaryStateLoaded implements DiaryState {
bool get moodExpanded;
bool get isLoading;
bool get isAdded;
List<NutritionData>? get chartData;
@JsonKey(ignore: true)
_$$DiaryStateLoadedImplCopyWith<_$DiaryStateLoadedImpl> get copyWith =>
throw _privateConstructorUsedError;
@@ -1418,7 +1420,6 @@ class _$DiaryStateErrorImpl implements DiaryStateError {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -1440,7 +1441,8 @@ class _$DiaryStateErrorImpl implements DiaryStateError {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)
bool isAdded,
List<NutritionData>? chartData)
loaded,
required TResult Function(String errorMessage) error,
}) {
@@ -1458,7 +1460,6 @@ class _$DiaryStateErrorImpl implements DiaryStateError {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -1480,7 +1481,8 @@ class _$DiaryStateErrorImpl implements DiaryStateError {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)?
bool isAdded,
List<NutritionData>? chartData)?
loaded,
TResult? Function(String errorMessage)? error,
}) {
@@ -1498,7 +1500,6 @@ class _$DiaryStateErrorImpl implements DiaryStateError {
List<int> recommendedChartValues,
List<int> consumedChartValues,
List<Portion> portions,
List<Photo> photos,
List<SelectionPopupModel> mealList,
List<SelectionPopupModel> portionList,
List<Product> autocompleteList,
@@ -1520,7 +1521,8 @@ class _$DiaryStateErrorImpl implements DiaryStateError {
bool moderationExpanded,
bool moodExpanded,
bool isLoading,
bool isAdded)?
bool isAdded,
List<NutritionData>? chartData)?
loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),

View File

@@ -7,20 +7,20 @@ import 'package:eatvio_app/features/diary/models/portion.dart';
import 'package:eatvio_app/features/diary/models/product.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_bloc.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart';
import 'package:eatvio_app/widgets/custom_edit_drop_down.dart';
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
import 'package:eatvio_app/widgets/custom_scale_element.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:image_picker/image_picker.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
// ignore: must_be_immutable
class DiaryScreen extends StatelessWidget {
@@ -89,7 +89,7 @@ class DiaryScreen extends StatelessWidget {
_buildMeal(context, state),
SizedBox(height: 20.v),
_buildMood(context, state),
SizedBox(height: 30.v),
SizedBox(height: 20.v),
_buildNutritionChart(context, state),
SizedBox(height: 30.v),
_buildComment(context, state),
@@ -109,6 +109,39 @@ class DiaryScreen extends StatelessWidget {
);
}
_buildNutritionChart(BuildContext context, DiaryStateLoaded state) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 16.h, vertical: 16.h),
padding: EdgeInsets.symmetric(
horizontal: 24.h,
vertical: 12.v,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(12)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3),
),
],
),
child: SfCircularChart(
title: ChartTitle(text: 'График КБЖУ'),
legend: Legend(isVisible: true),
series: <CircularSeries>[
RadialBarSeries<NutritionData, String>(
dataSource: state.chartData,
xValueMapper: (NutritionData data, _) => data.category,
yValueMapper: (NutritionData data, _) => data.nutrition,
pointColorMapper: (NutritionData data, _) => data.color,
)
],
));
}
_buildEndDay(BuildContext context) {
return CustomOutlinedButton(
text: "Закончить день",
@@ -122,7 +155,6 @@ class DiaryScreen extends StatelessWidget {
color: Colors.transparent,
),
onPressed: onFinishDayPressed(context),
// Установите прозрачный фон
);
}
@@ -217,8 +249,6 @@ class DiaryScreen extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: [
// Показывайте прелоадер, если загрузка активна
Padding(
padding: EdgeInsets.only(
left: 7.h,
@@ -461,13 +491,6 @@ class DiaryScreen extends StatelessWidget {
.map((portion) => _buildProduct(context, portion))
.toList(),
SizedBox(height: 30.v),
/*...state.photos != null
? state.photos!.isEmpty
? [Text('Фото пока нет')]
: state.photos!
.map((photo) => _buildPhoto(context, photo))
.toList()
: [Text('Фото нет')],*/
_buildCarousel(context, state),
SizedBox(height: 20.v),
_buildAddPhoto(context, state),
@@ -600,7 +623,6 @@ class DiaryScreen extends StatelessWidget {
BuildContext dialogContext,
) {
return () {
// Call function to send moderation with the entered values
context.read<DiaryBloc>().add(
SendModeration(
name: name,
@@ -610,7 +632,7 @@ class DiaryScreen extends StatelessWidget {
carbohydratesOn100gr: carbohydratesOn100gr,
),
);
Navigator.of(dialogContext).pop(); // Dismiss the dialog
Navigator.of(dialogContext).pop();
};
}
@@ -670,8 +692,7 @@ class DiaryScreen extends StatelessWidget {
return CarouselSlider(
options: CarouselOptions(height: 340.0),
items: state.currentMeal.photos.map<Widget>((photo) {
return _buildPhoto(
context, photo); // Assuming photos are stored as strings
return _buildPhoto(context, photo);
}).toList(),
);
}
@@ -777,7 +798,7 @@ class DiaryScreen extends StatelessWidget {
};
}
_buildNutritionChart(BuildContext context, DiaryStateLoaded state) {
/*_buildNutritionChart(BuildContext context, DiaryStateLoaded state) {
final List<int> recommendedValues = state
.recommendedChartValues; // Рекомендуемые значения: калории, жиры, белки, углеводы
final List<int> consumedValues = state.consumedChartValues; //
@@ -996,7 +1017,7 @@ class DiaryScreen extends StatelessWidget {
],
),
);
}
}*/
/// Section Widget
_buildComment(BuildContext context, DiaryStateLoaded state) {

View File

@@ -1,3 +1,7 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:eatvio_app/features/diary/models/diary_model.dart';
import 'package:eatvio_app/features/diary/models/portion.dart';
import 'package:eatvio_app/features/diary/models/product.dart';
@@ -24,6 +28,14 @@ class DiaryRepository {
}
}
Future<Map<String, dynamic>> getChartData(int diaryID) async {
try {
return (await diaryService.getChart(diaryID));
} catch (e) {
rethrow;
}
}
Future<Map<String, List<Product>>> inputProduct(String name) async {
try {
return await diaryService.getInputProduct(name);
@@ -92,7 +104,6 @@ class DiaryRepository {
int quantity,
) async {
try {
print(name);
return await diaryService.sendPortionData(
diaryID,
mealID,
@@ -105,15 +116,32 @@ class DiaryRepository {
}
}
Future<Map<String, String>> sendModeration(
String name,
String energy_on_100gr,
String proteins_on_100gr,
String fats_on_100gr,
String carbohydrates_on_100gr,
) async {
try {
return await diaryService.sendModerationData(
name,
double.parse(energy_on_100gr + ".0"),
double.parse(proteins_on_100gr + ".0"),
double.parse(fats_on_100gr + ".0"),
double.parse(carbohydrates_on_100gr + ".0"),
);
} catch (e) {
rethrow;
}
}
Future<void> removePortion(
int diaryID,
int mealID,
int portionID,
) async {
try {
print(diaryID);
print(mealID);
print(portionID);
await diaryService.sendRemovePortionData(
diaryID,
mealID,
@@ -123,4 +151,62 @@ class DiaryRepository {
rethrow;
}
}
Future<void> uploadImage(
String path,
int diaryID,
int mealID,
) async {
try {
File file = File(path);
await diaryService.uploadImage(
diaryID,
mealID,
file,
);
} catch (e) {
rethrow;
}
}
Future<void> removeImage(
int diaryID,
int mealID,
int photoID,
String path,
) async {
try {
await diaryService.sendRemovePhotoData(
diaryID,
mealID,
path,
photoID,
);
} catch (e) {
rethrow;
}
}
Future<void> finishDay(
int diaryID,
TimeOfDay? wakeup,
TimeOfDay? retire,
String? comment,
) async {
try {
final formatter = DateFormat('HH:mm');
final wakeupString =
formatter.format(DateTime(2022, 1, 1, wakeup!.hour, wakeup.minute));
final retireString =
formatter.format(DateTime(2022, 1, 1, retire!.hour, retire.minute));
await diaryService.sendFinishDay(
diaryID,
wakeupString,
retireString,
comment ?? " ",
);
} catch (e) {
rethrow;
}
}
}

View File

@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/diary/models/diary_model.dart';
import 'package:eatvio_app/features/diary/models/portion.dart';
@@ -17,7 +19,7 @@ abstract class DiaryService {
Future<Map<String, DiaryModel>> getDiary(@Path() int id);
@GET('/diary/{id}/dailyNutritionData/')
Future<DiaryModel> getChart(@Path() String id);
Future<dynamic> getChart(@Path() int id);
@GET('/diary/product_nutritional_values/filter')
Future<Map<String, List<Product>>> getInputProduct(
@@ -58,10 +60,42 @@ abstract class DiaryService {
@Query('quantity') int quantity,
);
@POST('/diary/{diary_id}/meal/{meal_id}/photo/upload')
Future<void> uploadImage(
@Path() int diary_id,
@Path() int meal_id,
@Part() File photo,
);
@POST('/diary/product_nutritional_values/sendToModeration')
Future<Map<String, String>> sendModerationData(
@Query('name') String product_name,
@Query('energy_on_100gr') double energy_on_100gr,
@Query('proteins_on_100gr') double proteins_on_100gr,
@Query('fats_on_100gr') double fats_on_100gr,
@Query('carbohydrates_on_100gr') double carbohydrates_on_100gr,
);
@POST('/diary/{diary_id}/finishDay')
Future<void> sendFinishDay(
@Path() int diary_id,
@Query('wakeUp') String wakeup,
@Query('retire') String retire,
@Query('comment') String comment,
);
@DELETE('/diary/{diary_id}/meal/{meal_id}/portions/{portion_id}/delete')
Future<void> sendRemovePortionData(
@Path() int diary_id,
@Path() int meal_id,
@Path() int portion_id,
);
@DELETE('/diary/{diary_id}/meal/{meal_id}/photo/delete')
Future<void> sendRemovePhotoData(
@Path() int diary_id,
@Path() int meal_id,
@Query('path') String path,
@Query('id') int photo_id,
);
}

View File

@@ -74,29 +74,28 @@ class _DiaryService implements DiaryService {
}
@override
Future<DiaryModel> getChart(String id) async {
Future<dynamic> getChart(int id) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _result = await _dio
.fetch<Map<String, dynamic>>(_setStreamType<DiaryModel>(Options(
final _result = await _dio.fetch(_setStreamType<dynamic>(Options(
method: 'GET',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/diary/${id}/dailyNutritionData/',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
))));
final _value = DiaryModel.fromJson(_result.data!);
.compose(
_dio.options,
'/diary/${id}/dailyNutritionData/',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
))));
final _value = _result.data;
return _value;
}
@@ -291,6 +290,113 @@ class _DiaryService implements DiaryService {
return _value;
}
@override
Future<void> uploadImage(
int diary_id,
int meal_id,
File photo,
) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = FormData();
_data.files.add(MapEntry(
'photo',
MultipartFile.fromFileSync(
photo.path,
filename: photo.path.split(Platform.pathSeparator).last,
),
));
await _dio.fetch<void>(_setStreamType<void>(Options(
method: 'POST',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/diary/${diary_id}/meal/${meal_id}/photo/upload',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
))));
}
@override
Future<Map<String, String>> sendModerationData(
String product_name,
double energy_on_100gr,
double proteins_on_100gr,
double fats_on_100gr,
double carbohydrates_on_100gr,
) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{
r'name': product_name,
r'energy_on_100gr': energy_on_100gr,
r'proteins_on_100gr': proteins_on_100gr,
r'fats_on_100gr': fats_on_100gr,
r'carbohydrates_on_100gr': carbohydrates_on_100gr,
};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _result = await _dio.fetch<Map<String, dynamic>>(
_setStreamType<Map<String, String>>(Options(
method: 'POST',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/diary/product_nutritional_values/sendToModeration',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
))));
final _value = _result.data!.cast<String, String>();
return _value;
}
@override
Future<void> sendFinishDay(
int diary_id,
String wakeup,
String retire,
String comment,
) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{
r'wakeUp': wakeup,
r'retire': retire,
r'comment': comment,
};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
await _dio.fetch<void>(_setStreamType<void>(Options(
method: 'POST',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/diary/${diary_id}/finishDay',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
))));
}
@override
Future<void> sendRemovePortionData(
int diary_id,
@@ -319,6 +425,38 @@ class _DiaryService implements DiaryService {
))));
}
@override
Future<void> sendRemovePhotoData(
int diary_id,
int meal_id,
String path,
int photo_id,
) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{
r'path': path,
r'id': photo_id,
};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
await _dio.fetch<void>(_setStreamType<void>(Options(
method: 'DELETE',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/diary/${diary_id}/meal/${meal_id}/photo/delete',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
))));
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||

View File

@@ -68,6 +68,7 @@ dependencies:
url_launcher: ^6.3.0
# debounce
easy_debounce: ^2.0.3
syncfusion_flutter_charts: ^26.1.42
dev_dependencies:
build_runner: ^2.4.11