forked from eatvio/eatvio_app
feat(diary): add diary page, calendar, meals
This commit is contained in:
@@ -1,517 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart';
|
||||
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/product.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
|
||||
import 'package:eatvio_app/features/diary/repositories/diary_repository.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
part 'diary_event.dart';
|
||||
|
||||
/// A bloc that manages the state of a Diary according to the event that is dispatched to it.
|
||||
class DiaryBloc extends Bloc<DiaryEvent, DiaryState> {
|
||||
final DiaryRepository diaryRepository;
|
||||
|
||||
DiaryBloc({required this.diaryRepository}) : super(const DiaryState.loading()) {
|
||||
on<LoadDiary>(loadDiary);
|
||||
on<LoadDiaryById>(loadDiaryById);
|
||||
on<ChangeSatiety>(_changeSatiety); // пользователь нажимает на шкалу сытости
|
||||
on<ChangeMood>(_changeMood); // пользователь нажимает на шкалу настроения
|
||||
on<ChangeMealTime>(_changeMealTime); // пользовательяет времяа пиши
|
||||
on<ChangeMeal>(_changeMeal);
|
||||
on<ChangePortion>(_changePortion);
|
||||
on<WakeupEvent>(_changeWakeup); // пользователь выбирает время пробуждения
|
||||
on<RetireEvent>(_changeRetire); // пользователь выбирает время отхода ко сну
|
||||
on<ToggleMoodExpandedEvent>(_toggleMood);
|
||||
on<ToggleWakeupExpandedEvent>(_toggleWakeup);
|
||||
on<AddPortionEvent>(_addPortion); //пользователь нажимает "Добавить продукт"
|
||||
on<RemovePortionEvent>(_removePortion);
|
||||
on<RemoveImageEvent>(
|
||||
_removeImage,
|
||||
); // пользователь нажимает на крестик около продукта
|
||||
on<UploadImages>(_uploadImages); //пользователь нажимает "Добавить фото"
|
||||
on<ProductInput>(
|
||||
_inputProduct,
|
||||
);
|
||||
on<FinishDay>(_finishDay);
|
||||
on<SendModeration>(_sendModeration);
|
||||
on<ClearInput>(_clearInput);
|
||||
on<ConfirmPortion>(_confirmPortion);
|
||||
}
|
||||
|
||||
loadDiary(
|
||||
LoadDiary event,
|
||||
Emitter<DiaryState> emit,
|
||||
) async {
|
||||
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: "грамм", value: "gr"), SelectionPopupModel(title: "порций", value: "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']! * 50;
|
||||
final double proteins = dailyNutritionIntake['proteins']! / dailyNutritionRecommendations['proteins']! * 50;
|
||||
final double fats = dailyNutritionIntake['fats']! / dailyNutritionRecommendations['fats']! * 50;
|
||||
final double carbs = dailyNutritionIntake['carbohydrates']! / dailyNutritionRecommendations['carbohydrates']! * 50;
|
||||
|
||||
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),
|
||||
SelectionPopupModel(title: "Прием пищи 3", id: 3),
|
||||
SelectionPopupModel(title: "Прием пищи 4", id: 4),
|
||||
SelectionPopupModel(title: "Прием пищи 5", id: 5),
|
||||
SelectionPopupModel(title: "Прием пищи 6", id: 6),
|
||||
];
|
||||
|
||||
emit(DiaryState.loaded(
|
||||
diary: diary,
|
||||
currentMeal: currentMeal,
|
||||
portions: currentMeal.portions,
|
||||
portionList: portionList,
|
||||
portionController: portionList[0],
|
||||
mealList: mealList,
|
||||
chartData: chartData,
|
||||
chartDataCounted: chartDataCounted,
|
||||
selectedMood: currentMeal.mood,
|
||||
selectedSatiety: currentMeal.satiety,
|
||||
wakeupController: TimeOfDay.now(),
|
||||
retireController: TimeOfDay.now(),
|
||||
commentController: TextEditingController(),
|
||||
product_nameController: TextEditingController(),
|
||||
productQuantityController: TextEditingController(),
|
||||
caloriesController: TextEditingController(),
|
||||
fatsController: TextEditingController(),
|
||||
proteinsController: TextEditingController(),
|
||||
carbsController: TextEditingController(),
|
||||
wakeupExpanded: false,
|
||||
moderationExpanded: false,
|
||||
moodExpanded: false,
|
||||
isLoading: false,
|
||||
isAdded: false,
|
||||
autocompleteList: [],
|
||||
recommendedChartValues: [1, 1, 1, 1],
|
||||
consumedChartValues: [1, 1, 1, 1]));
|
||||
} catch (e) {
|
||||
emit(DiaryState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
loadDiaryById(
|
||||
LoadDiaryById event,
|
||||
Emitter<DiaryState> emit,
|
||||
) async {
|
||||
emit(const DiaryState.loading());
|
||||
try {
|
||||
final int diaryID = int.parse(event.id ?? "0");
|
||||
final DiaryModel diary = await diaryRepository.getDiary(diaryID);
|
||||
final Meal currentMeal = diary.meals[0];
|
||||
|
||||
List<SelectionPopupModel> portionList = [SelectionPopupModel(title: "gr"), SelectionPopupModel(title: "pcs")];
|
||||
|
||||
final Map<String, dynamic> chartData = await diaryRepository.getChartData(diaryID);
|
||||
final Map<String, dynamic> dailyNutritionIntake = chartData['dailyNutritionIntake']!;
|
||||
final Map<String, dynamic> dailyNutritionRecommendations = chartData['dailyNutritionRecommendation']!;
|
||||
final double ccal = dailyNutritionIntake['energy']! / dailyNutritionRecommendations['energy']! * 50;
|
||||
final double proteins = dailyNutritionIntake['proteins']! / dailyNutritionRecommendations['proteins']! * 50;
|
||||
final double fats = dailyNutritionIntake['fats']! / dailyNutritionRecommendations['fats']! * 50;
|
||||
final double carbs = dailyNutritionIntake['carbohydrates']! / dailyNutritionRecommendations['carbohydrates']! * 50;
|
||||
|
||||
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),
|
||||
SelectionPopupModel(title: "Прием пищи 3", id: 3),
|
||||
SelectionPopupModel(title: "Прием пищи 4", id: 4),
|
||||
SelectionPopupModel(title: "Прием пищи 5", id: 5),
|
||||
SelectionPopupModel(title: "Прием пищи 6", id: 6),
|
||||
];
|
||||
|
||||
emit(DiaryState.loaded(
|
||||
diary: diary,
|
||||
currentMeal: currentMeal,
|
||||
portions: currentMeal.portions,
|
||||
portionList: portionList,
|
||||
portionController: portionList[0],
|
||||
mealList: mealList,
|
||||
chartData: chartData,
|
||||
chartDataCounted: chartDataCounted,
|
||||
selectedMood: currentMeal.mood,
|
||||
selectedSatiety: currentMeal.satiety,
|
||||
wakeupController: TimeOfDay.now(),
|
||||
retireController: TimeOfDay.now(),
|
||||
commentController: TextEditingController(),
|
||||
product_nameController: TextEditingController(),
|
||||
productQuantityController: TextEditingController(),
|
||||
caloriesController: TextEditingController(),
|
||||
fatsController: TextEditingController(),
|
||||
proteinsController: TextEditingController(),
|
||||
carbsController: TextEditingController(),
|
||||
wakeupExpanded: false,
|
||||
moderationExpanded: false,
|
||||
moodExpanded: false,
|
||||
isLoading: false,
|
||||
isAdded: false,
|
||||
autocompleteList: [],
|
||||
recommendedChartValues: [1, 1, 1, 1],
|
||||
consumedChartValues: [1, 1, 1, 1]));
|
||||
} catch (e) {
|
||||
emit(DiaryState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _changeSatiety(
|
||||
ChangeSatiety event,
|
||||
Emitter<DiaryState> emit,
|
||||
) 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,
|
||||
);
|
||||
emit(updatedState);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _changeMood(
|
||||
ChangeMood event,
|
||||
Emitter<DiaryState> emit,
|
||||
) async {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
var updatedState = currentState.copyWith(
|
||||
selectedMood: event.selectedElement,
|
||||
);
|
||||
|
||||
diaryRepository.changeMood(
|
||||
event.selectedElement,
|
||||
currentState.currentMeal.id,
|
||||
currentState.diary.id,
|
||||
);
|
||||
|
||||
emit(updatedState); // Передаем обновленное состояние в emit
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _changeWakeup(
|
||||
WakeupEvent event,
|
||||
Emitter<DiaryState> emit,
|
||||
) async {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
var updatedState = currentState.copyWith(wakeupController: event.selectedTime);
|
||||
final DateFormat formatter = DateFormat('HH:mm');
|
||||
final String wakeupString = formatter.format(DateTime(2022, 1, 1, event.selectedTime.hour, event.selectedTime.minute));
|
||||
await diaryRepository.changeWakeup(
|
||||
currentState.diary.id,
|
||||
wakeupString,
|
||||
);
|
||||
emit(updatedState);
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _changeRetire(
|
||||
RetireEvent event,
|
||||
Emitter<DiaryState> emit,
|
||||
) async {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
var updatedState = currentState.copyWith(retireController: event.selectedTime);
|
||||
final DateFormat formatter = DateFormat('HH:mm');
|
||||
final String retireString = formatter.format(DateTime(2022, 1, 1, event.selectedTime.hour, event.selectedTime.minute));
|
||||
await diaryRepository.changeRetire(
|
||||
currentState.diary.id,
|
||||
retireString,
|
||||
);
|
||||
emit(updatedState);
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _changeMealTime(
|
||||
ChangeMealTime event,
|
||||
Emitter<DiaryState> emit,
|
||||
) async {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
var updatedState = currentState.copyWith(mealTimeController: event.time);
|
||||
emit(updatedState);
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _changeMeal(
|
||||
ChangeMeal event,
|
||||
Emitter<DiaryState> emit,
|
||||
) async {
|
||||
if (state is DiaryStateLoaded) {
|
||||
final currentState = state as DiaryStateLoaded;
|
||||
final Meal meal = currentState.diary.meals.firstWhere((meal) => meal.type == event.value.id);
|
||||
DiaryStateLoaded updatedState = currentState.copyWith(
|
||||
currentMeal: meal,
|
||||
portions: meal.portions,
|
||||
mealTimeController: toTime(meal.time),
|
||||
selectedMood: meal.mood,
|
||||
selectedSatiety: meal.satiety,
|
||||
);
|
||||
emit(updatedState);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _inputProduct(
|
||||
ProductInput event,
|
||||
Emitter<DiaryState> emit,
|
||||
) async {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
|
||||
final Map<String, List<Product>> productNutritionalValues = await diaryRepository.inputProduct(event.input);
|
||||
var updatedState = currentState.copyWith(
|
||||
product_nameController: TextEditingController(text: event.input),
|
||||
autocompleteList: productNutritionalValues['product_nutritional_value'] ?? [],
|
||||
);
|
||||
if (event.input.length > 3) {
|
||||
updatedState = updatedState.copyWith(moderationExpanded: true);
|
||||
} else {
|
||||
updatedState = updatedState.copyWith(moderationExpanded: false);
|
||||
}
|
||||
|
||||
emit(updatedState);
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _addPortion(
|
||||
AddPortionEvent event,
|
||||
Emitter<DiaryState> emit,
|
||||
) async {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
await diaryRepository.addPortion(
|
||||
currentState.diary.id,
|
||||
currentState.currentMeal.id,
|
||||
currentState.product_nameController.text,
|
||||
currentState.portionController.value,
|
||||
int.parse(currentState.productQuantityController.text),
|
||||
);
|
||||
add(LoadDiary());
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
);
|
||||
}
|
||||
add(LoadDiary());
|
||||
}
|
||||
|
||||
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,
|
||||
);
|
||||
add(LoadDiary());
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
DiaryStateLoaded updatedState = currentState.copyWith();
|
||||
emit(updatedState);
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _changePortion(
|
||||
ChangePortion event,
|
||||
Emitter<DiaryState> emit,
|
||||
) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
DiaryStateLoaded updatedState = currentState.copyWith(
|
||||
portionController: event.value,
|
||||
);
|
||||
emit(updatedState);
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _toggleMood(
|
||||
ToggleMoodExpandedEvent event,
|
||||
Emitter<DiaryState> emit,
|
||||
) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
|
||||
emit(currentState.copyWith(moodExpanded: !currentState.moodExpanded));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _toggleWakeup(
|
||||
ToggleWakeupExpandedEvent event,
|
||||
Emitter<DiaryState> emit,
|
||||
) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
|
||||
emit(currentState.copyWith(wakeupExpanded: !currentState.wakeupExpanded));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _removeImage(
|
||||
RemoveImageEvent event,
|
||||
Emitter<DiaryState> emit,
|
||||
) async {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
|
||||
await diaryRepository.removeImage(
|
||||
currentState.diary.id,
|
||||
currentState.currentMeal.id,
|
||||
int.parse(event.photoID),
|
||||
event.path,
|
||||
);
|
||||
add(LoadDiary());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _finishDay(FinishDay event, Emitter<DiaryState> emit) async {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
|
||||
await diaryRepository.finishDay(
|
||||
currentState.diary.id,
|
||||
// currentState.wakeupController,
|
||||
// currentState.retireController,
|
||||
// currentState.commentController.text,
|
||||
);
|
||||
add(LoadDiary());
|
||||
}
|
||||
}
|
||||
|
||||
TimeOfDay toTime(String timeStr) {
|
||||
List<String> timeParts = timeStr.split(":");
|
||||
int hour = int.parse(timeParts[0]);
|
||||
int minute = int.parse(timeParts[1]);
|
||||
|
||||
TimeOfDay timeOfDay = TimeOfDay(hour: hour, minute: minute);
|
||||
return timeOfDay;
|
||||
}
|
||||
|
||||
int compareTypes(a, b) {
|
||||
return a['type'].compareTo(b['type']);
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillPortion() {
|
||||
return [
|
||||
SelectionPopupModel(id: 0, title: "порций", isSelected: true),
|
||||
SelectionPopupModel(id: 1, title: "грамм"),
|
||||
];
|
||||
}
|
||||
|
||||
FutureOr<void> _confirmPortion(ConfirmPortion event, Emitter<DiaryState> emit) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
var currentState = state as DiaryStateLoaded;
|
||||
|
||||
final updatedPortions = currentState.portions.map((portion) {
|
||||
if (portion.id == event.id) {
|
||||
return portion.copyWith(from_diet: !portion.from_diet);
|
||||
}
|
||||
if (!portion.from_diet) add(RemovePortionEvent(portion.id));
|
||||
return portion;
|
||||
}).toList();
|
||||
|
||||
final updatedState = currentState.copyWith(portions: updatedPortions);
|
||||
|
||||
emit(updatedState);
|
||||
|
||||
add(LoadDiary());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int convertToInt(dynamic value) {
|
||||
if (value is int) {
|
||||
return value;
|
||||
} else if (value is double) {
|
||||
return value.toInt();
|
||||
} else {
|
||||
throw FormatException('Unexpected value type: ${value.runtimeType}');
|
||||
}
|
||||
}
|
||||
22
lib/features/diary/presentation/bloc/diary_cubit.dart
Normal file
22
lib/features/diary/presentation/bloc/diary_cubit.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
|
||||
import 'package:eatvio_app/features/diary/repositories/diary_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class DiaryCubit extends Cubit<DiaryState> {
|
||||
final DiaryRepository diaryRepository;
|
||||
|
||||
DiaryCubit({
|
||||
required this.diaryRepository,
|
||||
}) : super(const DiaryState.loading());
|
||||
|
||||
getDiaryDay(String date) async {
|
||||
print(date);
|
||||
emit(const DiaryState.loading());
|
||||
try {
|
||||
emit(DiaryState.loaded(diary: await diaryRepository.getDiaryByDate(date)));
|
||||
} catch (e) {
|
||||
emit(DiaryState.error(errorMessage: e.toString()));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'diary_bloc.dart';
|
||||
|
||||
/// Abstract class for all events that can be dispatched from the
|
||||
///Diary widget.
|
||||
///
|
||||
/// Events must be immutable and implement the [Equatable] interface.
|
||||
@immutable
|
||||
abstract class DiaryEvent extends Equatable {}
|
||||
|
||||
/// Event that is dispatched when the Diary widget is first created.
|
||||
class LoadDiary extends DiaryEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class LoadDiaryById extends DiaryEvent {
|
||||
LoadDiaryById(
|
||||
this.id,
|
||||
);
|
||||
|
||||
final String? id;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class ChangeSatiety extends DiaryEvent {
|
||||
ChangeSatiety(
|
||||
this.selectedElement,
|
||||
);
|
||||
|
||||
final int selectedElement;
|
||||
|
||||
@override
|
||||
List<Object> get props => [selectedElement];
|
||||
}
|
||||
|
||||
class ChangeMood extends DiaryEvent {
|
||||
ChangeMood(
|
||||
this.selectedElement,
|
||||
);
|
||||
|
||||
final int selectedElement;
|
||||
|
||||
@override
|
||||
List<Object> get props => [selectedElement];
|
||||
}
|
||||
|
||||
class ChangeMealTime extends DiaryEvent {
|
||||
ChangeMealTime(this.time);
|
||||
|
||||
final TimeOfDay time;
|
||||
|
||||
@override
|
||||
List<Object> get props => [time];
|
||||
}
|
||||
|
||||
class AddComment extends DiaryEvent {
|
||||
AddComment(this.diaryId, this.comment);
|
||||
|
||||
final String comment;
|
||||
final int diaryId;
|
||||
|
||||
@override
|
||||
List<Object> get props => [comment, diaryId];
|
||||
}
|
||||
|
||||
class WakeupEvent extends DiaryEvent {
|
||||
WakeupEvent(this.selectedTime);
|
||||
|
||||
final TimeOfDay selectedTime;
|
||||
|
||||
@override
|
||||
List<Object> get props => [selectedTime];
|
||||
}
|
||||
|
||||
class RetireEvent extends DiaryEvent {
|
||||
RetireEvent(this.selectedTime);
|
||||
|
||||
final TimeOfDay selectedTime;
|
||||
|
||||
@override
|
||||
List<Object> get props => [selectedTime];
|
||||
}
|
||||
|
||||
class ToggleMoodExpandedEvent extends DiaryEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class ToggleWakeupExpandedEvent extends DiaryEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class AddPortionEvent extends DiaryEvent {
|
||||
AddPortionEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class RemovePortionEvent extends DiaryEvent {
|
||||
RemovePortionEvent(this.portionId);
|
||||
|
||||
final int portionId;
|
||||
|
||||
@override
|
||||
List<Object> get props => [portionId];
|
||||
}
|
||||
|
||||
class UploadImages extends DiaryEvent {
|
||||
UploadImages(this.image);
|
||||
|
||||
final XFile image;
|
||||
|
||||
@override
|
||||
List<Object> get props => [image];
|
||||
}
|
||||
|
||||
class RemoveImageEvent extends DiaryEvent {
|
||||
RemoveImageEvent(this.photoID, this.path);
|
||||
|
||||
final String photoID;
|
||||
final String path;
|
||||
|
||||
@override
|
||||
List<Object> get props => [photoID, path];
|
||||
}
|
||||
|
||||
class ProductInput extends DiaryEvent {
|
||||
ProductInput(this.input);
|
||||
|
||||
final String input;
|
||||
|
||||
@override
|
||||
List<Object> get props => [input];
|
||||
}
|
||||
|
||||
class ChangeMeal extends DiaryEvent {
|
||||
ChangeMeal({required this.value});
|
||||
|
||||
SelectionPopupModel value;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [value];
|
||||
}
|
||||
|
||||
class ClearInput extends DiaryEvent {
|
||||
ClearInput({required this.value});
|
||||
|
||||
TextEditingController value;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [value];
|
||||
}
|
||||
|
||||
class ChangePortion extends DiaryEvent {
|
||||
ChangePortion({required this.value});
|
||||
|
||||
SelectionPopupModel value;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [value];
|
||||
}
|
||||
|
||||
class FinishDay extends DiaryEvent {
|
||||
FinishDay();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class RefreshEvent extends DiaryEvent {
|
||||
RefreshEvent();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class ConfirmPortion extends DiaryEvent {
|
||||
ConfirmPortion(this.id);
|
||||
|
||||
int id;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
class SendModeration extends DiaryEvent {
|
||||
SendModeration({
|
||||
required this.name,
|
||||
required this.energyOn100gr,
|
||||
required this.proteinsOn100gr,
|
||||
required this.fatsOn100gr,
|
||||
required this.carbohydratesOn100gr,
|
||||
});
|
||||
|
||||
String name;
|
||||
String energyOn100gr;
|
||||
String proteinsOn100gr;
|
||||
String fatsOn100gr;
|
||||
String carbohydratesOn100gr;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [name, energyOn100gr, proteinsOn100gr, fatsOn100gr, carbohydratesOn100gr];
|
||||
}
|
||||
@@ -1,63 +1,19 @@
|
||||
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/portion.dart';
|
||||
import 'package:eatvio_app/features/diary/models/product.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import '../../../../data/models/selectionPopupModel/selection_popup_model.dart';
|
||||
|
||||
part 'diary_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class DiaryState with _$DiaryState {
|
||||
class DiaryState with _$DiaryState {
|
||||
const factory DiaryState() = _DiaryState;
|
||||
|
||||
const factory DiaryState.loading({
|
||||
int? id,
|
||||
}) = DiaryStateLoading;
|
||||
|
||||
const factory DiaryState.loaded({
|
||||
required DiaryModel diary,
|
||||
String? diaryDate,
|
||||
required List<int> recommendedChartValues,
|
||||
required List<int> consumedChartValues,
|
||||
required List<Portion> portions,
|
||||
required List<SelectionPopupModel> mealList,
|
||||
required List<SelectionPopupModel> portionList,
|
||||
required List<Product> autocompleteList,
|
||||
required Map<String, dynamic> chartData,
|
||||
required Meal currentMeal,
|
||||
required SelectionPopupModel portionController,
|
||||
required TimeOfDay wakeupController,
|
||||
required TimeOfDay retireController,
|
||||
TimeOfDay? mealTimeController,
|
||||
required TextEditingController commentController,
|
||||
required TextEditingController product_nameController,
|
||||
required TextEditingController productQuantityController,
|
||||
required TextEditingController caloriesController,
|
||||
required TextEditingController fatsController,
|
||||
required TextEditingController proteinsController,
|
||||
required TextEditingController carbsController,
|
||||
required int selectedMood,
|
||||
required int selectedSatiety,
|
||||
required bool wakeupExpanded,
|
||||
required bool moderationExpanded,
|
||||
required bool moodExpanded,
|
||||
required bool isLoading,
|
||||
required bool isAdded,
|
||||
List<NutritionData>? chartDataCounted,
|
||||
}) = DiaryStateLoaded;
|
||||
const factory DiaryState.loading() = DiaryStateLoading;
|
||||
|
||||
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;
|
||||
const factory DiaryState.loaded({
|
||||
required DiaryDayModel diary,
|
||||
}) = DiaryStateLoaded;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,115 +0,0 @@
|
||||
// ignore_for_file: unused_local_variable
|
||||
|
||||
import 'package:eatvio_app/features/diary/models/portion.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/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:rive/rive.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class DiaryRecommendationsScreen extends StatelessWidget {
|
||||
final String? diary_recommendationsID;
|
||||
|
||||
const DiaryRecommendationsScreen({
|
||||
this.diary_recommendationsID,
|
||||
super.key,
|
||||
});
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
if (diary_recommendationsID != "0") {
|
||||
context.read<DiaryBloc>().add(LoadDiaryById(diary_recommendationsID));
|
||||
}
|
||||
return BlocBuilder<DiaryBloc, DiaryState>(
|
||||
builder: (context, state) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
return _buildDiaryRecommendations(context, state);
|
||||
} else if (state is DiaryStateLoading) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: SizedBox(
|
||||
height: 32,
|
||||
width: 32,
|
||||
child: RiveAnimation.asset(
|
||||
'assets/rive_animations/loading.riv',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state is DiaryStateError) {
|
||||
return Scaffold(
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else
|
||||
return Scaffold(
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text("Неопределенная ошибка"),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDiaryRecommendations(BuildContext context, DiaryStateLoaded state) {
|
||||
final Portion product = new Portion(id: 1, product_name: "", quantity: 1, portion: "", from_diet: true);
|
||||
return Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
FormBuilder(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
backgroundColor: Color.fromARGB(255, 240, 242, 245),
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(bottom: 9),
|
||||
child: Column(
|
||||
children: [
|
||||
Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(product.product_name),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Название продукта: ${product.product_name}', style: TextStyle(fontSize: 24)),
|
||||
SizedBox(height: 16),
|
||||
Text('Количество: ${product.quantity} ${product.portion}', style: TextStyle(fontSize: 18)),
|
||||
// Добавьте другие детали о продукте по необходимости
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user