forked from eatvio/eatvio_app
617 lines
22 KiB
Dart
617 lines
22 KiB
Dart
import 'dart:async';
|
||
import 'dart:developer';
|
||
import 'dart:io';
|
||
|
||
import 'package:dio/dio.dart';
|
||
import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
|
||
import 'package:eatvio_app/core/internet_connection_cubit/internet_connection_cubit.dart';
|
||
import 'package:eatvio_app/core/internet_connection_cubit/internet_connection_state.dart';
|
||
import 'package:eatvio_app/core/local_db/diary_local_data_source.dart';
|
||
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
||
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||
import 'package:eatvio_app/features/consultations/models/consultation_model.dart';
|
||
import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart';
|
||
import 'package:eatvio_app/features/diary/entities/diary_future_diet_day_entity.dart';
|
||
import 'package:eatvio_app/features/diary/models/consultant_review_model.dart';
|
||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||
import 'package:eatvio_app/features/diary/models/nutrition_model.dart';
|
||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
|
||
import 'package:eatvio_app/features/diary/repositories/diary_repository.dart';
|
||
import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
|
||
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
|
||
import 'package:eatvio_app/features/glossary/repositories/glossary_repository.dart';
|
||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||
import 'package:eatvio_app/features/settings/repositories/service_repository.dart';
|
||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||
|
||
class DiaryCubit extends Cubit<DiaryState> {
|
||
|
||
late final DateTime today;
|
||
late DateTime selectedDay;
|
||
int selectedMeal = 1;
|
||
final DiaryRepository diaryRepository;
|
||
final GlossaryRepository glossaryRepository;
|
||
final ProfileRepository profileRepository;
|
||
final DietRepository dietRepository;
|
||
final ChatRepository chatRepository;
|
||
final SettingsRepository settingsRepository;
|
||
final DiaryLocalDataSource localDataSource;
|
||
final InternetConnectionCubit connectionCubit;
|
||
int? diaryId;
|
||
|
||
// Трек офлайн-режима
|
||
bool _lastFetchWasOffline = false;
|
||
|
||
// Подписка на изменения connectivity
|
||
StreamSubscription<InternetConnectionState>? _connectivitySubscription;
|
||
|
||
DiaryCubit({
|
||
required this.chatRepository,
|
||
required this.diaryRepository,
|
||
required this.glossaryRepository,
|
||
required this.profileRepository,
|
||
required this.dietRepository,
|
||
required this.settingsRepository,
|
||
required this.localDataSource,
|
||
required this.connectionCubit,
|
||
}) : super(const DiaryState.loading()) {
|
||
today = DateTime.now();
|
||
selectedDay = today;
|
||
diaryRepository.forceFetchStream.listen((_) {
|
||
fetchDiaryV2(needLoading: true, diaryId: diaryId);
|
||
});
|
||
// При переходе offline→online перезагружаем дневник
|
||
_connectivitySubscription = connectionCubit.stream.listen((connState) {
|
||
if (connState.isInternetAvailable && _lastFetchWasOffline) {
|
||
log('[DiaryCubit] Internet restored, reloading diary...');
|
||
fetchDiaryV2(needLoading: false, diaryId: diaryId);
|
||
}
|
||
});
|
||
}
|
||
|
||
String comment = '';
|
||
bool commentNeedsToBeFilled = false;
|
||
|
||
void setInitialDate(DateTime? date) {
|
||
if (date == null) return;
|
||
selectedDay = date;
|
||
}
|
||
|
||
Future<bool> setSelectedDay(DateTime day) async {
|
||
final prevDay = selectedDay;
|
||
final prevMeal = selectedMeal;
|
||
selectedDay = day;
|
||
selectedMeal = 1;
|
||
final canSelect = await fetchDiaryV2(needLoading: true);
|
||
|
||
if (!canSelect) {
|
||
selectedDay = prevDay;
|
||
selectedMeal = prevMeal;
|
||
}
|
||
|
||
return canSelect;
|
||
}
|
||
|
||
Future<bool> fetchDiaryV2({bool needLoading = false, int? diaryId}) async {
|
||
final currentState = state;
|
||
try {
|
||
if (needLoading) {
|
||
emit(const DiaryState.loading());
|
||
}
|
||
if (diaryId != null) {
|
||
log('[fetchDiaryV2] Loading by diaryId=$diaryId');
|
||
final diaryDayById = await diaryRepository.getDiaryDay(diaryId);
|
||
final diaryEntity = diaryDayById.toEntity();
|
||
if (diaryEntity != null) {
|
||
setDiary(diaryDay: diaryEntity, diaryId: diaryId);
|
||
return true;
|
||
}
|
||
}
|
||
|
||
final diaryDay = await getDiary();
|
||
if (diaryDay == null) {
|
||
// Офлайн и нет кэша — показываем понятное сообщение
|
||
final msg = connectionCubit.state.isInternetAvailable
|
||
? 'Дневник не найден'
|
||
: 'Нет интернета. Откройте дневник онлайн хотя бы один раз, чтобы он был доступен офлайн.';
|
||
log('[fetchDiaryV2] diaryDay is null, msg=$msg');
|
||
emit(DiaryState.error(errorMessage: msg));
|
||
return true;
|
||
}
|
||
|
||
log('[fetchDiaryV2] diaryDay loaded, id=${diaryDay.id}, converting to entity...');
|
||
final diaryEntity = diaryDay.toEntity();
|
||
if (diaryEntity != null) {
|
||
log('[fetchDiaryV2] entity OK, calling setDiary...');
|
||
await setDiary(diaryDay: diaryEntity, diaryId: diaryId);
|
||
log('[fetchDiaryV2] setDiary completed');
|
||
return true;
|
||
}
|
||
if (diaryDay.typeOfDiary.hasChosenDiet == true && diaryDay.typeOfDiary.diaryState == null) {
|
||
setDiaryForDietOnly(diaryDay.toDiaryFutureDayEntity());
|
||
return true;
|
||
}
|
||
log('[fetchDiaryV2] no entity, emitting previous state');
|
||
emit(currentState);
|
||
return false;
|
||
} catch (e, st) {
|
||
log('[fetchDiaryV2] CRASH: $e', stackTrace: st);
|
||
await reportFrom(e, st, this);
|
||
emit(DiaryState.error(errorMessage: e.toString()));
|
||
return false;
|
||
}
|
||
}
|
||
|
||
Future<void> updateCurrentDiary() async {
|
||
try {
|
||
final diaryDay = await diaryRepository.getDiaryDayV2(
|
||
day: selectedDay.toISO8601WithTimeZoneOffset(),
|
||
);
|
||
final diaryEntity = diaryDay.toEntity();
|
||
if (diaryEntity != null) {
|
||
setDiary(diaryDay: diaryEntity, diaryId: diaryId);
|
||
}
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
log(e.toString());
|
||
}
|
||
}
|
||
|
||
Future<DiaryDayModel?> getDiary() async {
|
||
_lastFetchWasOffline = false;
|
||
final dayStr = selectedDay.toISO8601WithTimeZoneOffset();
|
||
final isOnline = connectionCubit.state.isInternetAvailable;
|
||
log('[getDiary] START: day=$dayStr, isOnline=$isOnline');
|
||
|
||
// Офлайн: сначала пробуем кэш
|
||
if (!isOnline) {
|
||
try {
|
||
final result = await diaryRepository.getDiaryDayV2(day: dayStr);
|
||
log('[getDiary] OFFLINE: loaded from cache OK');
|
||
_lastFetchWasOffline = true;
|
||
return result;
|
||
} catch (_) {
|
||
// Кэша нет — попробуем сеть на случай ложного "offline"
|
||
log('[getDiary] OFFLINE: no cache, trying network as fallback...');
|
||
}
|
||
}
|
||
|
||
// Онлайн (или fallback после неудачного offline): создаём день + грузим с сервера
|
||
try {
|
||
log('[getDiary] ONLINE: creating diary day...');
|
||
await diaryRepository.createDiaryDay(day: dayStr);
|
||
log('[getDiary] ONLINE: day created, loading...');
|
||
final result = await diaryRepository.getDiaryDayV2(day: dayStr);
|
||
log('[getDiary] ONLINE: loaded OK, id=${result.id}');
|
||
return result;
|
||
} catch (e, st) {
|
||
log('[getDiary] ONLINE ERROR: $e');
|
||
await reportFrom(e, st, this);
|
||
if (e is DioException && e.response?.statusCode == 422) {
|
||
// День уже существует — просто загружаем
|
||
try {
|
||
log('[getDiary] 422 fallback: loading existing day...');
|
||
return await diaryRepository.getDiaryDayV2(day: dayStr);
|
||
} catch (e2) {
|
||
log('[getDiary] 422 fallback failed: $e2');
|
||
}
|
||
}
|
||
// Другая сетевая ошибка → пробуем кэш
|
||
_lastFetchWasOffline = true;
|
||
try {
|
||
log('[getDiary] Error fallback: trying cache...');
|
||
return await diaryRepository.getDiaryDayV2(day: dayStr);
|
||
} catch (e3) {
|
||
log('[getDiary] Cache fallback failed: $e3');
|
||
return null;
|
||
}
|
||
}
|
||
}
|
||
|
||
void setSelectedMeal(int meal) {
|
||
selectedMeal = meal;
|
||
final currentState = state;
|
||
if (currentState is DiaryStateLoaded) {
|
||
emit(currentState.copyWith(selectedMeal: selectedMeal));
|
||
} else if (currentState is DiaryStateLoadedTomorrowWithDiet) {
|
||
emit(currentState.copyWith(selectedMeal: selectedMeal));
|
||
}
|
||
}
|
||
|
||
Future<bool> setDiaryForDietOnly(DiaryFutureDietDayEntity diaryDay) async {
|
||
if (!diaryDay.typeOfDiary.hasChosenDiet) {
|
||
return false;
|
||
}
|
||
emit(const DiaryState.loading());
|
||
try {
|
||
if (diaryDay.diet?.id != null && diaryDay.dayOfChosenDiet != null) {
|
||
final diet = await dietRepository.getDiet((diaryDay.diet?.id)!);
|
||
final meals = diet.dailySchedule[diaryDay.dayOfChosenDiet];
|
||
final firstMealPortions = meals?[1]?.values.map((elem) {
|
||
return PortionModel(
|
||
id: 0,
|
||
productName: elem.name,
|
||
quantity: elem.quantity,
|
||
portion: elem.portion.getValue(),
|
||
fromDiet: true,
|
||
portionState: PortionState.filledDiet,
|
||
);
|
||
}).toList();
|
||
|
||
final secondMealPortions = meals?[2]?.values.map((elem) {
|
||
return PortionModel(
|
||
id: 0,
|
||
productName: elem.name,
|
||
quantity: elem.quantity,
|
||
portion: elem.portion.getValue(),
|
||
fromDiet: true,
|
||
portionState: PortionState.filledDiet,
|
||
);
|
||
}).toList();
|
||
|
||
final thirdMealPortions = meals?[3]?.values.map((elem) {
|
||
return PortionModel(
|
||
id: 0,
|
||
productName: elem.name,
|
||
quantity: elem.quantity,
|
||
portion: elem.portion.getValue(),
|
||
fromDiet: true,
|
||
portionState: PortionState.filledDiet,
|
||
);
|
||
}).toList();
|
||
|
||
final fourthMealPortions = meals?[4]?.values.map((elem) {
|
||
return PortionModel(
|
||
id: 0,
|
||
productName: elem.name,
|
||
quantity: elem.quantity,
|
||
portion: elem.portion.getValue(),
|
||
fromDiet: true,
|
||
portionState: PortionState.filledDiet,
|
||
);
|
||
}).toList();
|
||
|
||
final fifthMealPortions = meals?[5]?.values.map((elem) {
|
||
return PortionModel(
|
||
id: 0,
|
||
productName: elem.name,
|
||
quantity: elem.quantity,
|
||
portion: elem.portion.getValue(),
|
||
fromDiet: true,
|
||
portionState: PortionState.filledDiet,
|
||
);
|
||
}).toList();
|
||
final firstMeal = MealModel(id: 0, time: '0', typeNumber: 1, satiety: 0, mood: 0, portions: firstMealPortions ?? [], photos: []);
|
||
final secondMeal = MealModel(id: 0, time: '0', typeNumber: 2, satiety: 0, mood: 0, portions: secondMealPortions ?? [], photos: []);
|
||
final thirdMeal = MealModel(id: 0, time: '0', typeNumber: 3, satiety: 0, mood: 0, portions: thirdMealPortions ?? [], photos: []);
|
||
final fourthMeal = MealModel(id: 0, time: '0', typeNumber: 4, satiety: 0, mood: 0, portions: fourthMealPortions ?? [], photos: []);
|
||
final fifthMeal = MealModel(id: 0, time: '0', typeNumber: 5, satiety: 0, mood: 0, portions: fifthMealPortions ?? [], photos: []);
|
||
emit(
|
||
DiaryState.loadedTomorrowWithDiet(
|
||
diary: diaryDay.copyWith(meals: [firstMeal, secondMeal, thirdMeal, fourthMeal, fifthMeal]),
|
||
selectedDay: selectedDay,
|
||
selectedMeal: selectedMeal,
|
||
),
|
||
);
|
||
return true;
|
||
}
|
||
return false;
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
emit(DiaryState.error(errorMessage: e.toString()));
|
||
return false;
|
||
}
|
||
}
|
||
|
||
Future<void> setDiary({int? diaryId, required DiaryDayEntity diaryDay}) async {
|
||
this.diaryId ??= diaryId;
|
||
final isConsultantView = this.diaryId != null;
|
||
try {
|
||
bool isMoodEnabled = false;
|
||
bool isWakeUpAndRetireTimeEnabled = false;
|
||
if (diaryId == null) {
|
||
try {
|
||
final profileSettings = await settingsRepository.getProfileSettings();
|
||
isMoodEnabled = profileSettings.isMoodFillable;
|
||
isWakeUpAndRetireTimeEnabled = profileSettings.isBedtimeFillable;
|
||
} catch (_) {
|
||
// Офлайн — используем значения по умолчанию
|
||
}
|
||
}
|
||
|
||
ConsultantReviewModel? consultantReview;
|
||
int? planDuration;
|
||
int? currentPlanDay;
|
||
String? planName;
|
||
if (diaryDay.chosenPlanId != null) {
|
||
try {
|
||
final chosenPlanModel = await chatRepository.getChosenPlan(id: diaryDay.chosenPlanId!);
|
||
if (!isConsultantView &&
|
||
(diaryDay.typeOfDiary.diaryState == DiaryStateEnum.lastDayCommented ||
|
||
diaryDay.typeOfDiary.diaryState == DiaryStateEnum.commented)) {
|
||
await diaryRepository.viewCommentOfDiaryDayByConsultant(diaryId: diaryDay.id);
|
||
}
|
||
consultantReview = await diaryRepository.getDiaryComments(
|
||
planId: diaryDay.chosenPlanId!,
|
||
diaryId: diaryDay.id,
|
||
);
|
||
planDuration = chosenPlanModel.plan.duration;
|
||
planName = chosenPlanModel.plan.name;
|
||
currentPlanDay = consultantReview.currentPlanDay;
|
||
} catch (_) {
|
||
// Офлайн — данные плана недоступны
|
||
}
|
||
}
|
||
|
||
final nutrition = await getNutrition(diaryDay.id);
|
||
|
||
final isDiaryFinished =
|
||
diaryDay.typeOfDiary.diaryState == DiaryStateEnum.finished ||
|
||
diaryDay.typeOfDiary.diaryState == DiaryStateEnum.lastDayFinished;
|
||
|
||
final isDiaryCommented =
|
||
diaryDay.typeOfDiary.diaryState == DiaryStateEnum.commented ||
|
||
diaryDay.typeOfDiary.diaryState == DiaryStateEnum.lastDayCommented ||
|
||
diaryDay.typeOfDiary.diaryState == DiaryStateEnum.reviewedByUser;
|
||
|
||
// Offline-first: получаем кол-во операций в очереди
|
||
int pendingCount = 0;
|
||
try {
|
||
pendingCount = await localDataSource.getPendingCount();
|
||
} catch (_) {
|
||
// Ошибка чтения pending_operations — не критично
|
||
}
|
||
|
||
emit(
|
||
DiaryState.loaded(
|
||
diary: diaryDay,
|
||
nutrition: nutrition,
|
||
selectedDay: selectedDay,
|
||
selectedMeal: selectedMeal,
|
||
isConsultantView: isConsultantView,
|
||
consultantReview: consultantReview,
|
||
isDiaryFinished: isDiaryFinished,
|
||
isDiaryCommented: isDiaryCommented,
|
||
chosenPlanCurrentDay: currentPlanDay,
|
||
chosenPlanDuration: planDuration,
|
||
chosenPlanName: planName,
|
||
isMoodEnabled: isMoodEnabled,
|
||
isWakeUpAndRetireEnabled: isWakeUpAndRetireTimeEnabled,
|
||
pendingOpsCount: pendingCount,
|
||
isOfflineMode: _lastFetchWasOffline,
|
||
),
|
||
);
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
log(e.toString(), stackTrace: st);
|
||
emit(DiaryState.error(errorMessage: e.toString()));
|
||
}
|
||
}
|
||
|
||
Future<bool> finishDiaryDay({required int diaryId, required String wakeUp, required String retire}) async {
|
||
try {
|
||
await diaryRepository.finishDiaryDay(diaryId: diaryId, wakeUp: wakeUp, retire: retire, comment: comment.isEmpty ? null : comment);
|
||
await updateCurrentDiary();
|
||
return true;
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
log(e.toString(), stackTrace: st);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
Future<NutritionDataModel?> getNutrition(int index) async {
|
||
try {
|
||
return await diaryRepository.getNutritionData(index);
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
log('getNutrition offline fallback: $e');
|
||
return null; // Офлайн — нет данных по калориям, не критично
|
||
}
|
||
}
|
||
|
||
Future<void> addProductToMeal({
|
||
required int diaryId,
|
||
required int mealId,
|
||
required String productName,
|
||
required String portion,
|
||
required int quantity,
|
||
int? productNutritionalValueId,
|
||
}) async {
|
||
emit((state as DiaryStateLoaded).copyWith(isLoadingAddingProductInMeal: true));
|
||
try {
|
||
await diaryRepository.addPortionToMeal(
|
||
diaryId: diaryId,
|
||
mealId: mealId,
|
||
productName: productName,
|
||
portion: portion,
|
||
quantity: quantity,
|
||
productNutritionalValueId: productNutritionalValueId,
|
||
);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
final s = state;
|
||
if (s is DiaryStateLoaded) {
|
||
emit(s.copyWith(isLoadingAddingProductInMeal: false));
|
||
}
|
||
}
|
||
}
|
||
|
||
Future<void> updateProductInMeal({
|
||
required int diaryId,
|
||
required int mealId,
|
||
required int portionId,
|
||
required String productName,
|
||
required String portion,
|
||
required int quantity,
|
||
int? productNutritionalValueId,
|
||
required PortionState portionState,
|
||
}) async {
|
||
try {
|
||
if (portionState == PortionState.filledDiet || portionState == PortionState.eatenFromDiet) {
|
||
await diaryRepository.addPortionToMeal(
|
||
diaryId: diaryId,
|
||
mealId: mealId,
|
||
productName: productName,
|
||
portion: portion,
|
||
quantity: quantity,
|
||
productNutritionalValueId: productNutritionalValueId,
|
||
);
|
||
} else {
|
||
await diaryRepository.updateProductInMeal(
|
||
diaryId: diaryId,
|
||
mealId: mealId,
|
||
portionId: portionId,
|
||
productName: productName,
|
||
portion: portion,
|
||
quantity: quantity,
|
||
productNutritionalValueId: productNutritionalValueId,
|
||
portionState: portionState,
|
||
);
|
||
}
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<void> markEaten({required int diaryId, required int mealId, required int portionId}) async {
|
||
try {
|
||
await diaryRepository.markEaten(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<void> unmarkEaten({required int diaryId, required int mealId, required int portionId}) async {
|
||
try {
|
||
await diaryRepository.unmarkEaten(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<void> restore({required int diaryId, required int mealId, required int portionId}) async {
|
||
try {
|
||
await diaryRepository.restore(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<void> deleteProductFromMeal({required int diaryId, required int mealId, required int portionId}) async {
|
||
try {
|
||
await diaryRepository.deleteProductFromMeal(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<List<GlossaryModel>> getGlossaryListByQuery(String query) async {
|
||
try {
|
||
return await glossaryRepository.getGlossaryListByQuery(query);
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
return [];
|
||
}
|
||
}
|
||
|
||
Future<void> uploadPhotos({required List<File> files, required int diaryId}) async {
|
||
try {
|
||
await diaryRepository.uploadPhotos(files: await ImageCompressUtility.compressFilesList(files), diaryId: diaryId, mealId: selectedMeal);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<void> deletePhoto({required DiaryPhotoModel photo, required int diaryId}) async {
|
||
try {
|
||
await diaryRepository.deletePhoto(photo: photo, diaryId: diaryId, mealId: selectedMeal);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<GlossaryModerationModel?> sendProductToModeration({
|
||
required String name,
|
||
required double energy,
|
||
required double proteins,
|
||
required double fats,
|
||
required double carbohydrates,
|
||
}) async {
|
||
try {
|
||
return await diaryRepository.sendProductToModeration(name: name, energy: energy, proteins: proteins, fats: fats, carbohydrates: carbohydrates);
|
||
} catch (e, stackTrace) {
|
||
await reportFrom(e, stackTrace, this);
|
||
log(e.toString(), stackTrace: stackTrace);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
Future<void> fillTime({required int diaryId, required String time}) async {
|
||
try {
|
||
await diaryRepository.fillTime(diaryId: diaryId, mealId: selectedMeal, time: time);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<void> fillWakeup({required int diaryId, required String time}) async {
|
||
try {
|
||
await diaryRepository.fillWakeup(diaryId: diaryId, time: time);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<void> fillRetire({required int diaryId, required String time}) async {
|
||
try {
|
||
await diaryRepository.fillRetire(diaryId: diaryId, time: time);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<void> fillSatiety({required int diaryId, required int satiety}) async {
|
||
try {
|
||
await diaryRepository.fillSatiety(diaryId: diaryId, mealId: selectedMeal, satiety: satiety);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
Future<void> fillMood({required int diaryId, required int mood}) async {
|
||
try {
|
||
await diaryRepository.fillMood(diaryId: diaryId, mealId: selectedMeal, mood: mood);
|
||
await updateCurrentDiary();
|
||
} catch (e, st) {
|
||
await reportFrom(e, st, this);
|
||
}
|
||
}
|
||
|
||
void fillComment(String comment) {
|
||
this.comment = comment;
|
||
commentNeedsToBeFilled = comment.isNotEmpty && comment.length < 3;
|
||
}
|
||
|
||
@override
|
||
Future<void> close() {
|
||
_connectivitySubscription?.cancel();
|
||
return super.close();
|
||
}
|
||
}
|
||
|
||
enum DiaryFetchingErrors { canNotCreateFutureDays, dayAlreadyExists }
|